1bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com 2bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com/* 3bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com * Copyright 2013 Google Inc. 4bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com * 5bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com * Use of this source code is governed by a BSD-style license that can be 6bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com * found in the LICENSE file. 7bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com */ 8bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com 9bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com#include "ppapi/cpp/completion_callback.h" 10bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com#include "ppapi/cpp/graphics_2d.h" 11bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com#include "ppapi/cpp/image_data.h" 12bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com#include "ppapi/cpp/instance.h" 13bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com#include "ppapi/cpp/module.h" 14bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com#include "ppapi/cpp/point.h" 15bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com#include "ppapi/cpp/rect.h" 16bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com#include "ppapi/cpp/var.h" 17bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com 18bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com#include "SkBitmap.h" 19bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com#include "SkCanvas.h" 20bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com#include "SkColor.h" 21bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com#include "SkGraphics.h" 22bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com#include "SkStream.h" 23bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com#include "SkString.h" 24bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com 25bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.comclass SkiaInstance; 26bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com 27bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com// Used by SkDebugf 28bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.comSkiaInstance* gPluginInstance; 29bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com 30bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.comvoid FlushCallback(void* data, int32_t result); 31bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com 32bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.comstatic void doDraw(SkCanvas* canvas, const SkPaint& paint, const char text[]) { 33bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com canvas->drawColor(SK_ColorWHITE); 34bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com SkPaint red; 35bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com red.setColor(SK_ColorRED); 36bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com canvas->drawCircle(150.0, 150.0, 100.0, red); 37bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com SkRect bounds; 38bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com canvas->getClipBounds(&bounds); 39bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com canvas->drawText(text, strlen(text), 40bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com bounds.centerX(), bounds.centerY(), 41bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com paint); 42bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com} 43bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com 44bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com// Skia's subclass of pp::Instance, our interface with the browser. 45bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.comclass SkiaInstance : public pp::Instance { 46bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.compublic: 47bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com explicit SkiaInstance(PP_Instance instance) 48bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com : pp::Instance(instance) 49bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com , fCanvas(NULL) 50bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com , fFlushLoopRunning(false) 51bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com , fFlushPending(false) 52bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com { 53bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com gPluginInstance = this; 54bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com SkGraphics::Init(); 55bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com } 56bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com 57bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com virtual ~SkiaInstance() { 58bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com SkGraphics::Term(); 59bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com gPluginInstance = NULL; 60bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com } 61bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com 62bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com virtual void HandleMessage(const pp::Var& var_message) { 63bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com // Receive a message from javascript. 64bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com } 65bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com 66bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com void Paint() { 67bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com if (!fImage.is_null()) { 68bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com SkPaint paint; 69bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com paint.setAntiAlias(true); 70bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com paint.setTextSize(SkIntToScalar(30)); 71bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com paint.setTextAlign(SkPaint::kCenter_Align); 72bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com doDraw(fCanvas, paint, "Hello"); 73bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com 74bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com fDeviceContext.PaintImageData(fImage, pp::Point(0, 0)); 75bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com if (!fFlushPending) { 76bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com fFlushPending = true; 77bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com fDeviceContext.Flush(pp::CompletionCallback(&FlushCallback, this)); 78bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com } else { 79bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com SkDebugf("A flush is pending... Skipping flush.\n"); 80bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com } 81bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com } else { 82bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com SkDebugf("No pixels to write to!\n"); 83bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com } 84bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com } 85bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com 86bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com virtual void DidChangeView(const pp::Rect& position, const pp::Rect& clip) { 87bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com if (position.size().width() == fWidth && 88bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com position.size().height() == fHeight) { 89bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com return; // We don't care about the position, only the size. 90bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com } 91bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com fWidth = position.size().width(); 92bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com fHeight = position.size().height(); 93bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com fDeviceContext = pp::Graphics2D(this, pp::Size(fWidth, fHeight), false); 94bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com if (!BindGraphics(fDeviceContext)) { 95bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com SkDebugf("Couldn't bind the device context\n"); 96bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com return; 97bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com } 98bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com fImage = pp::ImageData(this, 99bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com PP_IMAGEDATAFORMAT_BGRA_PREMUL, 100bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com pp::Size(fWidth, fHeight), false); 101bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com fBitmap.setConfig(SkBitmap::kARGB_8888_Config, fWidth, fHeight); 102bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com fBitmap.setPixels(fImage.data()); 103bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com if (fCanvas) { 104bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com delete fCanvas; 105bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com } 106bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com fCanvas = new SkCanvas(fBitmap); 107bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com fCanvas->clear(SK_ColorWHITE); 108bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com if (!fFlushLoopRunning) { 109bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com Paint(); 110bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com } 111bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com } 112bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com 113bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com void OnFlush() { 114bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com fFlushLoopRunning = true; 115bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com fFlushPending = false; 116bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com Paint(); 117bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com } 118bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com 119bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.comprivate: 120bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com pp::Graphics2D fDeviceContext; 121bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com pp::ImageData fImage; 122bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com int fWidth; 123bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com int fHeight; 124bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com 125bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com SkBitmap fBitmap; 126bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com SkCanvas* fCanvas; 127bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com 128bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com bool fFlushLoopRunning; 129bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com bool fFlushPending; 130bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com}; 131bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com 132bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.comvoid FlushCallback(void* data, int32_t result) { 133bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com static_cast<SkiaInstance*>(data)->OnFlush(); 134bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com} 135bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com 136bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.comclass SkiaModule : public pp::Module { 137bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.compublic: 138bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com SkiaModule() : pp::Module() {} 139bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com virtual ~SkiaModule() {} 140bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com 141bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com virtual pp::Instance* CreateInstance(PP_Instance instance) { 142bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com return new SkiaInstance(instance); 143bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com } 144bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com}; 145bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com 146bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.comnamespace pp { 147bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.comModule* CreateModule() { 148bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com return new SkiaModule(); 149bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com} 150bb5228888253b21ce81f0a89b605cdd7f88c0efcborenet@google.com} // namespace pp 151