blob: 5239311c85c81b2513b2443af7ac1ccf2e74ee47 [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;
caryclark52edc4d2015-02-02 12:55:14 -080032 fRotationAngle = 0;
33 this->setTitle();
34 this->setUpBackend();
35}
36
37HelloWorldWindow::~HelloWorldWindow() {
38 tearDownBackend();
39}
40
41void HelloWorldWindow::tearDownBackend() {
42 SkSafeUnref(fContext);
43 fContext = NULL;
44
45 SkSafeUnref(fInterface);
46 fInterface = NULL;
47
robertphillipsecf3dbe2016-07-28 15:17:34 -070048 fGpuSurface = nullptr;
caryclark52edc4d2015-02-02 12:55:14 -080049
mtklein18300a32016-03-16 13:53:35 -070050 INHERITED::release();
caryclark52edc4d2015-02-02 12:55:14 -080051}
52
53void HelloWorldWindow::setTitle() {
54 SkString title("Hello World ");
55 title.appendf(fType == kRaster_DeviceType ? "raster" : "opengl");
56 INHERITED::setTitle(title.c_str());
57}
58
59bool HelloWorldWindow::setUpBackend() {
caryclark52edc4d2015-02-02 12:55:14 -080060 this->setVisibleP(true);
61 this->setClipToBounds(false);
62
brianosman2d1ee792016-05-05 12:24:31 -070063 bool result = attach(kNativeGL_BackEndType, 0 /*msaa*/, false, &fAttachmentInfo);
caryclark52edc4d2015-02-02 12:55:14 -080064 if (false == result) {
65 SkDebugf("Not possible to create backend.\n");
mtklein18300a32016-03-16 13:53:35 -070066 release();
caryclark52edc4d2015-02-02 12:55:14 -080067 return false;
68 }
69
70 fInterface = GrGLCreateNativeInterface();
caryclark52edc4d2015-02-02 12:55:14 -080071 SkASSERT(NULL != fInterface);
72
73 fContext = GrContext::Create(kOpenGL_GrBackend, (GrBackendContext)fInterface);
74 SkASSERT(NULL != fContext);
75
robertphillipsecf3dbe2016-07-28 15:17:34 -070076 this->setUpGpuBackedSurface();
caryclark52edc4d2015-02-02 12:55:14 -080077 return true;
78}
79
robertphillipsecf3dbe2016-07-28 15:17:34 -070080void HelloWorldWindow::setUpGpuBackedSurface() {
81 fGpuSurface = this->makeGpuBackedSurface(fAttachmentInfo, fInterface, fContext);
caryclark52edc4d2015-02-02 12:55:14 -080082}
83
84void HelloWorldWindow::drawContents(SkCanvas* canvas) {
85 // Clear background
86 canvas->drawColor(SK_ColorWHITE);
87
88 SkPaint paint;
89 paint.setColor(SK_ColorRED);
90
91 // Draw a rectangle with red paint
reedc6f28f72016-03-14 12:22:10 -070092 SkRect rect = SkRect::MakeXYWH(10, 10, 128, 128);
caryclark52edc4d2015-02-02 12:55:14 -080093 canvas->drawRect(rect, paint);
94
95 // Set up a linear gradient and draw a circle
96 {
97 SkPoint linearPoints[] = {
98 {0, 0},
99 {300, 300}
100 };
101 SkColor linearColors[] = {SK_ColorGREEN, SK_ColorBLACK};
102
reedc6f28f72016-03-14 12:22:10 -0700103 paint.setShader(SkGradientShader::MakeLinear(
104 linearPoints, linearColors, nullptr, 2,
105 SkShader::kMirror_TileMode));
caryclark52edc4d2015-02-02 12:55:14 -0800106 paint.setFlags(SkPaint::kAntiAlias_Flag);
107
108 canvas->drawCircle(200, 200, 64, paint);
109
110 // Detach shader
reedc6f28f72016-03-14 12:22:10 -0700111 paint.setShader(nullptr);
caryclark52edc4d2015-02-02 12:55:14 -0800112 }
113
114 // Draw a message with a nice black paint.
115 paint.setFlags(
116 SkPaint::kAntiAlias_Flag |
117 SkPaint::kSubpixelText_Flag | // ... avoid waggly text when rotating.
118 SkPaint::kUnderlineText_Flag);
119 paint.setColor(SK_ColorBLACK);
120 paint.setTextSize(20);
121
122 canvas->save();
123
124 static const char message[] = "Hello World";
125
126 // Translate and rotate
127 canvas->translate(300, 300);
128 fRotationAngle += 0.2f;
129 if (fRotationAngle > 360) {
130 fRotationAngle -= 360;
131 }
132 canvas->rotate(fRotationAngle);
133
134 // Draw the text:
135 canvas->drawText(message, strlen(message), 0, 0, paint);
136
137 canvas->restore();
138}
139
140void HelloWorldWindow::draw(SkCanvas* canvas) {
robertphillipsecf3dbe2016-07-28 15:17:34 -0700141 this->drawContents(canvas);
caryclark52edc4d2015-02-02 12:55:14 -0800142 // in case we have queued drawing calls
143 fContext->flush();
144 // Invalidate the window to force a redraw. Poor man's animation mechanism.
145 this->inval(NULL);
146
147 if (kRaster_DeviceType == fType) {
148 // need to send the raster bits to the (gpu) window
robertphillipsecf3dbe2016-07-28 15:17:34 -0700149 sk_sp<SkImage> snap = fRasterSurface->makeImageSnapshot();
reed6ceeebd2016-03-09 14:26:26 -0800150 SkPixmap pmap;
151 if (snap->peekPixels(&pmap)) {
152 const SkImageInfo& info = pmap.info();
robertphillipsecf3dbe2016-07-28 15:17:34 -0700153
154 SkCanvas* canvas = fGpuSurface->getCanvas();
155
156 canvas->writePixels(info, pmap.addr(), pmap.rowBytes(), 0, 0);
157 canvas->flush();
reed6ceeebd2016-03-09 14:26:26 -0800158 }
caryclark52edc4d2015-02-02 12:55:14 -0800159 }
160 INHERITED::present();
161}
162
163void HelloWorldWindow::onSizeChange() {
robertphillipsecf3dbe2016-07-28 15:17:34 -0700164 this->setUpGpuBackedSurface();
caryclark52edc4d2015-02-02 12:55:14 -0800165}
166
167bool HelloWorldWindow::onHandleChar(SkUnichar unichar) {
168 if (' ' == unichar) {
169 fType = fType == kRaster_DeviceType ? kGPU_DeviceType: kRaster_DeviceType;
170 tearDownBackend();
171 setUpBackend();
172 this->setTitle();
173 this->inval(NULL);
174 }
175 return true;
176}
177
178SkOSWindow* create_sk_window(void* hwnd, int , char** ) {
179 return new HelloWorldWindow(hwnd);
180}