OLD | NEW |
| (Empty) |
1 #include <cstdio> | |
2 #include <string> | |
3 | |
4 #include "ppapi/cpp/completion_callback.h" | |
5 #include "ppapi/cpp/graphics_2d.h" | |
6 #include "ppapi/cpp/image_data.h" | |
7 #include "ppapi/cpp/instance.h" | |
8 #include "ppapi/cpp/module.h" | |
9 #include "ppapi/cpp/var.h" | |
10 | |
11 #include "SampleApp.h" | |
12 #include "SkApplication.h" | |
13 #include "SkCanvas.h" | |
14 #include "SkBitmap.h" | |
15 #include "SkEvent.h" | |
16 #include "SkWindow.h" | |
17 | |
18 class SkiaInstance; | |
19 | |
20 namespace { | |
21 void FlushCallback(void* data, int32_t result); | |
22 } | |
23 | |
24 SkiaInstance* gPluginInstance; | |
25 extern int main(int, char**); | |
26 | |
27 class SkiaInstance : public pp::Instance { | |
28 public: | |
29 explicit SkiaInstance(PP_Instance instance) : pp::Instance(instance), | |
30 fFlushPending(false), | |
31 fGraphics2dContext(NULL), | |
32 fPixelBuffer(NULL) | |
33 { | |
34 gPluginInstance = this; | |
35 application_init(); | |
36 char* commandName = "SampleApp"; | |
37 fWindow = new SampleWindow(NULL, 0, &commandName, NULL); | |
38 } | |
39 | |
40 virtual ~SkiaInstance() { | |
41 gPluginInstance = NULL; | |
42 delete fWindow; | |
43 application_term(); | |
44 } | |
45 | |
46 virtual void HandleMessage(const pp::Var& var_message) { | |
47 // Receive a message from javascript. Right now this just signals us to | |
48 // get started. | |
49 uint32_t width = 500; | |
50 uint32_t height = 500; | |
51 char buffer[2048]; | |
52 sprintf(buffer, "SetSize:%d,%d", width, height); | |
53 PostMessage(buffer); | |
54 } | |
55 | |
56 virtual void DidChangeView(const pp::Rect& position, | |
57 const pp::Rect& clip) { | |
58 if (position.size().width() == width() && | |
59 position.size().height() == height()) { | |
60 return; // Size didn't change, no need to update anything. | |
61 } | |
62 // Create a new device context with the new size. | |
63 DestroyContext(); | |
64 CreateContext(position.size()); | |
65 // Delete the old pixel buffer and create a new one. | |
66 delete fPixelBuffer; | |
67 fPixelBuffer = NULL; | |
68 if (fGraphics2dContext != NULL) { | |
69 fPixelBuffer = new pp::ImageData(this, | |
70 PP_IMAGEDATAFORMAT_BGRA_PREMUL, | |
71 fGraphics2dContext->size(), | |
72 false); | |
73 fWindow->resize(position.size().width(), position.size().height()); | |
74 fWindow->update(NULL); | |
75 paint(); | |
76 } | |
77 } | |
78 | |
79 // Indicate whether a flush is pending. This can only be called from the | |
80 // main thread; it is not thread safe. | |
81 bool flush_pending() const { | |
82 return fFlushPending; | |
83 } | |
84 void set_flush_pending(bool flag) { | |
85 fFlushPending = flag; | |
86 } | |
87 | |
88 void paint() { | |
89 if (fPixelBuffer) { | |
90 // Draw some stuff. TODO(borenet): Actually have SampleApp draw into | |
91 // the plugin area. | |
92 uint32_t w = fPixelBuffer->size().width(); | |
93 uint32_t h = fPixelBuffer->size().height(); | |
94 uint32_t* data = (uint32_t*) fPixelBuffer->data(); | |
95 // Create a bitmap using the fPixelBuffer pixels | |
96 SkBitmap bitmap; | |
97 bitmap.setConfig(SkBitmap::kARGB_8888_Config, w, h); | |
98 bitmap.setPixels(data); | |
99 // Create a canvas with the bitmap as the backend | |
100 SkCanvas canvas(bitmap); | |
101 | |
102 canvas.drawColor(SK_ColorBLUE); | |
103 SkRect rect = SkRect::MakeXYWH(10, 10, 80, 80); | |
104 SkPaint rect_paint; | |
105 rect_paint.setStyle(SkPaint::kFill_Style); | |
106 rect_paint.setColor(SK_ColorRED); | |
107 canvas.drawRect(rect, rect_paint); | |
108 | |
109 FlushPixelBuffer(); | |
110 } | |
111 } | |
112 | |
113 private: | |
114 int width() const { | |
115 return fPixelBuffer ? fPixelBuffer->size().width() : 0; | |
116 } | |
117 | |
118 int height() const { | |
119 return fPixelBuffer ? fPixelBuffer->size().height() : 0; | |
120 } | |
121 | |
122 bool IsContextValid() const { | |
123 return fGraphics2dContext != NULL; | |
124 } | |
125 | |
126 void CreateContext(const pp::Size& size) { | |
127 if (IsContextValid()) | |
128 return; | |
129 fGraphics2dContext = new pp::Graphics2D(this, size, false); | |
130 if (!BindGraphics(*fGraphics2dContext)) { | |
131 SkDebugf("Couldn't bind the device context"); | |
132 } | |
133 } | |
134 | |
135 void DestroyContext() { | |
136 if (!IsContextValid()) | |
137 return; | |
138 delete fGraphics2dContext; | |
139 fGraphics2dContext = NULL; | |
140 } | |
141 | |
142 void FlushPixelBuffer() { | |
143 if (!IsContextValid()) | |
144 return; | |
145 // Note that the pixel lock is held while the buffer is copied into the | |
146 // device context and then flushed. | |
147 fGraphics2dContext->PaintImageData(*fPixelBuffer, pp::Point()); | |
148 if (flush_pending()) | |
149 return; | |
150 set_flush_pending(true); | |
151 fGraphics2dContext->Flush(pp::CompletionCallback(&FlushCallback, this)); | |
152 } | |
153 | |
154 bool fFlushPending; | |
155 pp::Graphics2D* fGraphics2dContext; | |
156 pp::ImageData* fPixelBuffer; | |
157 SampleWindow* fWindow; | |
158 }; | |
159 | |
160 class SkiaModule : public pp::Module { | |
161 public: | |
162 SkiaModule() : pp::Module() {} | |
163 virtual ~SkiaModule() {} | |
164 | |
165 virtual pp::Instance* CreateInstance(PP_Instance instance) { | |
166 gPluginInstance = new SkiaInstance(instance); | |
167 return gPluginInstance; | |
168 } | |
169 }; | |
170 | |
171 namespace { | |
172 void FlushCallback(void* data, int32_t result) { | |
173 static_cast<SkiaInstance*>(data)->set_flush_pending(false); | |
174 } | |
175 } | |
176 | |
177 namespace pp { | |
178 Module* CreateModule() { | |
179 return new SkiaModule(); | |
180 } | |
181 } // namespace pp | |
182 | |
183 | |
184 /////////////////////////////////////////// | |
185 ///////////// SkOSWindow impl ///////////// | |
186 /////////////////////////////////////////// | |
187 | |
188 void SkOSWindow::onSetTitle(const char title[]) | |
189 { | |
190 char buffer[2048]; | |
191 sprintf(buffer, "SetTitle:%s", title); | |
192 gPluginInstance->PostMessage(buffer); | |
193 } | |
194 | |
195 void SkOSWindow::onHandleInval(const SkIRect& rect) | |
196 { | |
197 gPluginInstance->paint(); | |
198 } | |
199 | |
200 void SkOSWindow::onPDFSaved(const char title[], const char desc[], | |
201 const char path[]) { | |
202 } | |
203 | |
204 /////////////////////////////////////////// | |
205 /////////////// SkEvent impl ////////////// | |
206 /////////////////////////////////////////// | |
207 | |
208 void SkEvent::SignalQueueTimer(SkMSec ms) { | |
209 } | |
210 | |
211 void SkEvent::SignalNonEmptyQueue() { | |
212 } | |
OLD | NEW |