blob: 892dce1c805251a31abc956273b199872c3268b8 [file] [log] [blame]
caryclark52edc4d2015-02-02 12:55:14 -08001/*
2 * Copyright 2015 Google Inc.
3 *
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 *
8 */
9
10#include "HelloWorld.h"
11
12#include "gl/GrGLInterface.h"
bsalomonf276ac52015-10-09 13:36:42 -070013#include "GrContext.h"
caryclark52edc4d2015-02-02 12:55:14 -080014#include "SkApplication.h"
15#include "SkCanvas.h"
16#include "SkGradientShader.h"
17#include "SkGraphics.h"
18#include "SkGr.h"
19
20void application_init() {
21 SkGraphics::Init();
22 SkEvent::Init();
23}
24
25void application_term() {
26 SkEvent::Term();
caryclark52edc4d2015-02-02 12:55:14 -080027}
28
29HelloWorldWindow::HelloWorldWindow(void* hwnd)
30 : INHERITED(hwnd) {
31 fType = kGPU_DeviceType;
32 fRenderTarget = NULL;
33 fRotationAngle = 0;
34 this->setTitle();
35 this->setUpBackend();
36}
37
38HelloWorldWindow::~HelloWorldWindow() {
39 tearDownBackend();
40}
41
42void HelloWorldWindow::tearDownBackend() {
43 SkSafeUnref(fContext);
44 fContext = NULL;
45
46 SkSafeUnref(fInterface);
47 fInterface = NULL;
48
49 SkSafeUnref(fRenderTarget);
50 fRenderTarget = NULL;
51
mtklein18300a32016-03-16 13:53:35 -070052 INHERITED::release();
caryclark52edc4d2015-02-02 12:55:14 -080053}
54
55void HelloWorldWindow::setTitle() {
56 SkString title("Hello World ");
57 title.appendf(fType == kRaster_DeviceType ? "raster" : "opengl");
58 INHERITED::setTitle(title.c_str());
59}
60
61bool HelloWorldWindow::setUpBackend() {
caryclark52edc4d2015-02-02 12:55:14 -080062 this->setVisibleP(true);
63 this->setClipToBounds(false);
64
65 bool result = attach(kNativeGL_BackEndType, 0 /*msaa*/, &fAttachmentInfo);
66 if (false == result) {
67 SkDebugf("Not possible to create backend.\n");
mtklein18300a32016-03-16 13:53:35 -070068 release();
caryclark52edc4d2015-02-02 12:55:14 -080069 return false;
70 }
71
72 fInterface = GrGLCreateNativeInterface();
73
74 SkASSERT(NULL != fInterface);
75
76 fContext = GrContext::Create(kOpenGL_GrBackend, (GrBackendContext)fInterface);
77 SkASSERT(NULL != fContext);
78
79 this->setUpRenderTarget();
80 return true;
81}
82
83void HelloWorldWindow::setUpRenderTarget() {
84 SkSafeUnref(fRenderTarget);
85 fRenderTarget = this->renderTarget(fAttachmentInfo, fInterface, fContext);
86}
87
88void HelloWorldWindow::drawContents(SkCanvas* canvas) {
89 // Clear background
90 canvas->drawColor(SK_ColorWHITE);
91
92 SkPaint paint;
93 paint.setColor(SK_ColorRED);
94
95 // Draw a rectangle with red paint
reedc6f28f72016-03-14 12:22:10 -070096 SkRect rect = SkRect::MakeXYWH(10, 10, 128, 128);
caryclark52edc4d2015-02-02 12:55:14 -080097 canvas->drawRect(rect, paint);
98
99 // Set up a linear gradient and draw a circle
100 {
101 SkPoint linearPoints[] = {
102 {0, 0},
103 {300, 300}
104 };
105 SkColor linearColors[] = {SK_ColorGREEN, SK_ColorBLACK};
106
reedc6f28f72016-03-14 12:22:10 -0700107 paint.setShader(SkGradientShader::MakeLinear(
108 linearPoints, linearColors, nullptr, 2,
109 SkShader::kMirror_TileMode));
caryclark52edc4d2015-02-02 12:55:14 -0800110 paint.setFlags(SkPaint::kAntiAlias_Flag);
111
112 canvas->drawCircle(200, 200, 64, paint);
113
114 // Detach shader
reedc6f28f72016-03-14 12:22:10 -0700115 paint.setShader(nullptr);
caryclark52edc4d2015-02-02 12:55:14 -0800116 }
117
118 // Draw a message with a nice black paint.
119 paint.setFlags(
120 SkPaint::kAntiAlias_Flag |
121 SkPaint::kSubpixelText_Flag | // ... avoid waggly text when rotating.
122 SkPaint::kUnderlineText_Flag);
123 paint.setColor(SK_ColorBLACK);
124 paint.setTextSize(20);
125
126 canvas->save();
127
128 static const char message[] = "Hello World";
129
130 // Translate and rotate
131 canvas->translate(300, 300);
132 fRotationAngle += 0.2f;
133 if (fRotationAngle > 360) {
134 fRotationAngle -= 360;
135 }
136 canvas->rotate(fRotationAngle);
137
138 // Draw the text:
139 canvas->drawText(message, strlen(message), 0, 0, paint);
140
141 canvas->restore();
142}
143
144void HelloWorldWindow::draw(SkCanvas* canvas) {
145 drawContents(canvas);
146 // in case we have queued drawing calls
147 fContext->flush();
148 // Invalidate the window to force a redraw. Poor man's animation mechanism.
149 this->inval(NULL);
150
151 if (kRaster_DeviceType == fType) {
152 // need to send the raster bits to the (gpu) window
reed9ce9d672016-03-17 10:51:11 -0700153 sk_sp<SkImage> snap = fSurface->makeImageSnapshot();
reed6ceeebd2016-03-09 14:26:26 -0800154 SkPixmap pmap;
155 if (snap->peekPixels(&pmap)) {
156 const SkImageInfo& info = pmap.info();
157 fRenderTarget->writePixels(0, 0, snap->width(), snap->height(),
158 SkImageInfo2GrPixelConfig(info.colorType(),
159 info.alphaType(),
brianosmana6359362016-03-21 06:55:37 -0700160 info.profileType(),
161 *fContext->caps()),
reed6ceeebd2016-03-09 14:26:26 -0800162 pmap.addr(),
163 pmap.rowBytes(),
164 GrContext::kFlushWrites_PixelOp);
165 }
caryclark52edc4d2015-02-02 12:55:14 -0800166 }
167 INHERITED::present();
168}
169
170void HelloWorldWindow::onSizeChange() {
171 setUpRenderTarget();
172}
173
174bool HelloWorldWindow::onHandleChar(SkUnichar unichar) {
175 if (' ' == unichar) {
176 fType = fType == kRaster_DeviceType ? kGPU_DeviceType: kRaster_DeviceType;
177 tearDownBackend();
178 setUpBackend();
179 this->setTitle();
180 this->inval(NULL);
181 }
182 return true;
183}
184
185SkOSWindow* create_sk_window(void* hwnd, int , char** ) {
186 return new HelloWorldWindow(hwnd);
187}