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 "SkApplication.h" 14#include "SkCanvas.h" 15#include "SkGradientShader.h" 16#include "SkGraphics.h" 17#include "SkGr.h" 18 19void application_init() { 20 SkGraphics::Init(); 21 SkEvent::Init(); 22} 23 24void application_term() { 25 SkEvent::Term(); 26 SkGraphics::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->setColorType(kRGBA_8888_SkColorType); 63 this->setVisibleP(true); 64 this->setClipToBounds(false); 65 66 bool result = attach(kNativeGL_BackEndType, 0 /*msaa*/, &fAttachmentInfo); 67 if (false == result) { 68 SkDebugf("Not possible to create backend.\n"); 69 detach(); 70 return false; 71 } 72 73 fInterface = GrGLCreateNativeInterface(); 74 75 SkASSERT(NULL != fInterface); 76 77 fContext = GrContext::Create(kOpenGL_GrBackend, (GrBackendContext)fInterface); 78 SkASSERT(NULL != fContext); 79 80 this->setUpRenderTarget(); 81 return true; 82} 83 84void HelloWorldWindow::setUpRenderTarget() { 85 SkSafeUnref(fRenderTarget); 86 fRenderTarget = this->renderTarget(fAttachmentInfo, fInterface, fContext); 87} 88 89void HelloWorldWindow::drawContents(SkCanvas* canvas) { 90 // Clear background 91 canvas->drawColor(SK_ColorWHITE); 92 93 SkPaint paint; 94 paint.setColor(SK_ColorRED); 95 96 // Draw a rectangle with red paint 97 SkRect rect = { 98 10, 10, 99 128, 128 100 }; 101 canvas->drawRect(rect, paint); 102 103 // Set up a linear gradient and draw a circle 104 { 105 SkPoint linearPoints[] = { 106 {0, 0}, 107 {300, 300} 108 }; 109 SkColor linearColors[] = {SK_ColorGREEN, SK_ColorBLACK}; 110 111 SkShader* shader = SkGradientShader::CreateLinear( 112 linearPoints, linearColors, NULL, 2, 113 SkShader::kMirror_TileMode); 114 SkAutoUnref shader_deleter(shader); 115 116 paint.setShader(shader); 117 paint.setFlags(SkPaint::kAntiAlias_Flag); 118 119 canvas->drawCircle(200, 200, 64, paint); 120 121 // Detach shader 122 paint.setShader(NULL); 123 } 124 125 // Draw a message with a nice black paint. 126 paint.setFlags( 127 SkPaint::kAntiAlias_Flag | 128 SkPaint::kSubpixelText_Flag | // ... avoid waggly text when rotating. 129 SkPaint::kUnderlineText_Flag); 130 paint.setColor(SK_ColorBLACK); 131 paint.setTextSize(20); 132 133 canvas->save(); 134 135 static const char message[] = "Hello World"; 136 137 // Translate and rotate 138 canvas->translate(300, 300); 139 fRotationAngle += 0.2f; 140 if (fRotationAngle > 360) { 141 fRotationAngle -= 360; 142 } 143 canvas->rotate(fRotationAngle); 144 145 // Draw the text: 146 canvas->drawText(message, strlen(message), 0, 0, paint); 147 148 canvas->restore(); 149} 150 151void HelloWorldWindow::draw(SkCanvas* canvas) { 152 drawContents(canvas); 153 // in case we have queued drawing calls 154 fContext->flush(); 155 // Invalidate the window to force a redraw. Poor man's animation mechanism. 156 this->inval(NULL); 157 158 if (kRaster_DeviceType == fType) { 159 // need to send the raster bits to the (gpu) window 160 SkImage* snap = fSurface->newImageSnapshot(); 161 size_t rowBytes; 162 SkImageInfo info; 163 const void* pixels = snap->peekPixels(&info, &rowBytes); 164 fRenderTarget->writePixels(0, 0, snap->width(), snap->height(), 165 SkImageInfo2GrPixelConfig(info.colorType(), 166 info.alphaType(), 167 info.profileType()), 168 pixels, 169 rowBytes, 170 GrContext::kFlushWrites_PixelOp); 171 SkSafeUnref(snap); 172 } 173 INHERITED::present(); 174} 175 176void HelloWorldWindow::onSizeChange() { 177 setUpRenderTarget(); 178} 179 180bool HelloWorldWindow::onHandleChar(SkUnichar unichar) { 181 if (' ' == unichar) { 182 fType = fType == kRaster_DeviceType ? kGPU_DeviceType: kRaster_DeviceType; 183 tearDownBackend(); 184 setUpBackend(); 185 this->setTitle(); 186 this->inval(NULL); 187 } 188 return true; 189} 190 191SkOSWindow* create_sk_window(void* hwnd, int , char** ) { 192 return new HelloWorldWindow(hwnd); 193} 194