| /* | |
| * Copyright 2015 Google Inc. | |
| * | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| * | |
| */ | |
| #include "HelloWorld.h" | |
| #include "gl/GrGLInterface.h" | |
| #include "GrContext.h" | |
| #include "SkApplication.h" | |
| #include "SkCanvas.h" | |
| #include "SkGradientShader.h" | |
| #include "SkGraphics.h" | |
| #include "SkGr.h" | |
| void application_init() { | |
| SkGraphics::Init(); | |
| SkEvent::Init(); | |
| } | |
| void application_term() { | |
| SkEvent::Term(); | |
| } | |
| HelloWorldWindow::HelloWorldWindow(void* hwnd) | |
| : INHERITED(hwnd) { | |
| fType = kGPU_DeviceType; | |
| fRenderTarget = NULL; | |
| fRotationAngle = 0; | |
| this->setTitle(); | |
| this->setUpBackend(); | |
| } | |
| HelloWorldWindow::~HelloWorldWindow() { | |
| tearDownBackend(); | |
| } | |
| void HelloWorldWindow::tearDownBackend() { | |
| SkSafeUnref(fContext); | |
| fContext = NULL; | |
| SkSafeUnref(fInterface); | |
| fInterface = NULL; | |
| SkSafeUnref(fRenderTarget); | |
| fRenderTarget = NULL; | |
| INHERITED::release(); | |
| } | |
| void HelloWorldWindow::setTitle() { | |
| SkString title("Hello World "); | |
| title.appendf(fType == kRaster_DeviceType ? "raster" : "opengl"); | |
| INHERITED::setTitle(title.c_str()); | |
| } | |
| bool HelloWorldWindow::setUpBackend() { | |
| this->setVisibleP(true); | |
| this->setClipToBounds(false); | |
| bool result = attach(kNativeGL_BackEndType, 0 /*msaa*/, &fAttachmentInfo); | |
| if (false == result) { | |
| SkDebugf("Not possible to create backend.\n"); | |
| release(); | |
| return false; | |
| } | |
| fInterface = GrGLCreateNativeInterface(); | |
| SkASSERT(NULL != fInterface); | |
| fContext = GrContext::Create(kOpenGL_GrBackend, (GrBackendContext)fInterface); | |
| SkASSERT(NULL != fContext); | |
| this->setUpRenderTarget(); | |
| return true; | |
| } | |
| void HelloWorldWindow::setUpRenderTarget() { | |
| SkSafeUnref(fRenderTarget); | |
| fRenderTarget = this->renderTarget(fAttachmentInfo, fInterface, fContext); | |
| } | |
| void HelloWorldWindow::drawContents(SkCanvas* canvas) { | |
| // Clear background | |
| canvas->drawColor(SK_ColorWHITE); | |
| SkPaint paint; | |
| paint.setColor(SK_ColorRED); | |
| // Draw a rectangle with red paint | |
| SkRect rect = SkRect::MakeXYWH(10, 10, 128, 128); | |
| canvas->drawRect(rect, paint); | |
| // Set up a linear gradient and draw a circle | |
| { | |
| SkPoint linearPoints[] = { | |
| {0, 0}, | |
| {300, 300} | |
| }; | |
| SkColor linearColors[] = {SK_ColorGREEN, SK_ColorBLACK}; | |
| paint.setShader(SkGradientShader::MakeLinear( | |
| linearPoints, linearColors, nullptr, 2, | |
| SkShader::kMirror_TileMode)); | |
| paint.setFlags(SkPaint::kAntiAlias_Flag); | |
| canvas->drawCircle(200, 200, 64, paint); | |
| // Detach shader | |
| paint.setShader(nullptr); | |
| } | |
| // Draw a message with a nice black paint. | |
| paint.setFlags( | |
| SkPaint::kAntiAlias_Flag | | |
| SkPaint::kSubpixelText_Flag | // ... avoid waggly text when rotating. | |
| SkPaint::kUnderlineText_Flag); | |
| paint.setColor(SK_ColorBLACK); | |
| paint.setTextSize(20); | |
| canvas->save(); | |
| static const char message[] = "Hello World"; | |
| // Translate and rotate | |
| canvas->translate(300, 300); | |
| fRotationAngle += 0.2f; | |
| if (fRotationAngle > 360) { | |
| fRotationAngle -= 360; | |
| } | |
| canvas->rotate(fRotationAngle); | |
| // Draw the text: | |
| canvas->drawText(message, strlen(message), 0, 0, paint); | |
| canvas->restore(); | |
| } | |
| void HelloWorldWindow::draw(SkCanvas* canvas) { | |
| drawContents(canvas); | |
| // in case we have queued drawing calls | |
| fContext->flush(); | |
| // Invalidate the window to force a redraw. Poor man's animation mechanism. | |
| this->inval(NULL); | |
| if (kRaster_DeviceType == fType) { | |
| // need to send the raster bits to the (gpu) window | |
| sk_sp<SkImage> snap = fSurface->makeImageSnapshot(); | |
| SkPixmap pmap; | |
| if (snap->peekPixels(&pmap)) { | |
| const SkImageInfo& info = pmap.info(); | |
| fRenderTarget->writePixels(0, 0, snap->width(), snap->height(), | |
| SkImageInfo2GrPixelConfig(info.colorType(), | |
| info.alphaType(), | |
| info.profileType(), | |
| *fContext->caps()), | |
| pmap.addr(), | |
| pmap.rowBytes(), | |
| GrContext::kFlushWrites_PixelOp); | |
| } | |
| } | |
| INHERITED::present(); | |
| } | |
| void HelloWorldWindow::onSizeChange() { | |
| setUpRenderTarget(); | |
| } | |
| bool HelloWorldWindow::onHandleChar(SkUnichar unichar) { | |
| if (' ' == unichar) { | |
| fType = fType == kRaster_DeviceType ? kGPU_DeviceType: kRaster_DeviceType; | |
| tearDownBackend(); | |
| setUpBackend(); | |
| this->setTitle(); | |
| this->inval(NULL); | |
| } | |
| return true; | |
| } | |
| SkOSWindow* create_sk_window(void* hwnd, int , char** ) { | |
| return new HelloWorldWindow(hwnd); | |
| } |