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 20void application_init() { 21 SkGraphics::Init(); 22 SkEvent::Init(); 23} 24 25void application_term() { 26 SkEvent::Term(); 27} 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 52 INHERITED::detach(); 53} 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() { 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 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 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 150void 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 175void HelloWorldWindow::onSizeChange() { 176 setUpRenderTarget(); 177} 178 179bool 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 190SkOSWindow* create_sk_window(void* hwnd, int , char** ) { 191 return new HelloWorldWindow(hwnd); 192} 193