• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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"
13 #include "GrContext.h"
14 #include "SkApplication.h"
15 #include "SkCanvas.h"
16 #include "SkGradientShader.h"
17 #include "SkGraphics.h"
18 #include "SkGr.h"
19 
application_init()20 void application_init() {
21     SkGraphics::Init();
22     SkEvent::Init();
23 }
24 
application_term()25 void application_term() {
26     SkEvent::Term();
27 }
28 
HelloWorldWindow(void * hwnd)29 HelloWorldWindow::HelloWorldWindow(void* hwnd)
30     : INHERITED(hwnd) {
31     fType = kGPU_DeviceType;
32     fRenderTarget = NULL;
33     fRotationAngle = 0;
34     this->setTitle();
35     this->setUpBackend();
36 }
37 
~HelloWorldWindow()38 HelloWorldWindow::~HelloWorldWindow() {
39     tearDownBackend();
40 }
41 
tearDownBackend()42 void HelloWorldWindow::tearDownBackend() {
43     SkSafeUnref(fContext);
44     fContext = NULL;
45 
46     SkSafeUnref(fInterface);
47     fInterface = NULL;
48 
49     SkSafeUnref(fRenderTarget);
50     fRenderTarget = NULL;
51 
52     INHERITED::detach();
53 }
54 
setTitle()55 void HelloWorldWindow::setTitle() {
56     SkString title("Hello World ");
57     title.appendf(fType == kRaster_DeviceType ? "raster" : "opengl");
58     INHERITED::setTitle(title.c_str());
59 }
60 
setUpBackend()61 bool HelloWorldWindow::setUpBackend() {
62     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");
68         detach();
69         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 
setUpRenderTarget()83 void HelloWorldWindow::setUpRenderTarget() {
84     SkSafeUnref(fRenderTarget);
85     fRenderTarget = this->renderTarget(fAttachmentInfo, fInterface, fContext);
86 }
87 
drawContents(SkCanvas * canvas)88 void 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
96     SkRect rect = {
97             10, 10,
98             128, 128
99     };
100     canvas->drawRect(rect, paint);
101 
102     // Set up a linear gradient and draw a circle
103     {
104         SkPoint linearPoints[] = {
105                 {0, 0},
106                 {300, 300}
107         };
108         SkColor linearColors[] = {SK_ColorGREEN, SK_ColorBLACK};
109 
110         SkShader* shader = SkGradientShader::CreateLinear(
111                 linearPoints, linearColors, NULL, 2,
112                 SkShader::kMirror_TileMode);
113         SkAutoUnref shader_deleter(shader);
114 
115         paint.setShader(shader);
116         paint.setFlags(SkPaint::kAntiAlias_Flag);
117 
118         canvas->drawCircle(200, 200, 64, paint);
119 
120         // Detach shader
121         paint.setShader(NULL);
122     }
123 
124     // Draw a message with a nice black paint.
125     paint.setFlags(
126             SkPaint::kAntiAlias_Flag |
127             SkPaint::kSubpixelText_Flag |  // ... avoid waggly text when rotating.
128             SkPaint::kUnderlineText_Flag);
129     paint.setColor(SK_ColorBLACK);
130     paint.setTextSize(20);
131 
132     canvas->save();
133 
134     static const char message[] = "Hello World";
135 
136     // Translate and rotate
137     canvas->translate(300, 300);
138     fRotationAngle += 0.2f;
139     if (fRotationAngle > 360) {
140         fRotationAngle -= 360;
141     }
142     canvas->rotate(fRotationAngle);
143 
144     // Draw the text:
145     canvas->drawText(message, strlen(message), 0, 0, paint);
146 
147     canvas->restore();
148 }
149 
draw(SkCanvas * canvas)150 void HelloWorldWindow::draw(SkCanvas* canvas) {
151     drawContents(canvas);
152     // in case we have queued drawing calls
153     fContext->flush();
154     // Invalidate the window to force a redraw. Poor man's animation mechanism.
155     this->inval(NULL);
156 
157     if (kRaster_DeviceType == fType) {
158         // need to send the raster bits to the (gpu) window
159         SkImage* snap = fSurface->newImageSnapshot();
160         size_t rowBytes = 0;
161         SkImageInfo info;
162         const void* pixels = snap->peekPixels(&info, &rowBytes);
163         fRenderTarget->writePixels(0, 0, snap->width(), snap->height(),
164                                         SkImageInfo2GrPixelConfig(info.colorType(),
165                                                                 info.alphaType(),
166                                                                 info.profileType()),
167                                         pixels,
168                                         rowBytes,
169                                         GrContext::kFlushWrites_PixelOp);
170         SkSafeUnref(snap);
171     }
172     INHERITED::present();
173 }
174 
onSizeChange()175 void HelloWorldWindow::onSizeChange() {
176     setUpRenderTarget();
177 }
178 
onHandleChar(SkUnichar unichar)179 bool HelloWorldWindow::onHandleChar(SkUnichar unichar) {
180     if (' ' == unichar) {
181         fType = fType == kRaster_DeviceType ? kGPU_DeviceType: kRaster_DeviceType;
182         tearDownBackend();
183         setUpBackend();
184         this->setTitle();
185         this->inval(NULL);
186     }
187     return true;
188 }
189 
create_sk_window(void * hwnd,int,char **)190 SkOSWindow* create_sk_window(void* hwnd, int , char** ) {
191     return new HelloWorldWindow(hwnd);
192 }
193