OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (C) 2010 Apple Inc. All rights reserved. | |
3 * Copyright (C) 2010 Google Inc. All rights reserved. | |
4 * Copyright (C) 2010 Mozilla Corporation. All rights reserved. | |
5 * | |
6 * Redistribution and use in source and binary forms, with or without | |
7 * modification, are permitted provided that the following conditions | |
8 * are met: | |
9 * 1. Redistributions of source code must retain the above copyright | |
10 * notice, this list of conditions and the following disclaimer. | |
11 * 2. Redistributions in binary form must reproduce the above copyright | |
12 * notice, this list of conditions and the following disclaimer in the | |
13 * documentation and/or other materials provided with the distribution. | |
14 * | |
15 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY | |
16 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR | |
19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | |
23 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
26 */ | |
27 | |
28 #include "config.h" | |
29 | |
30 #include "core/platform/graphics/GraphicsContext3D.h" | |
31 | |
32 #include "core/platform/graphics/GraphicsContext.h" | |
33 #include "core/platform/graphics/ImageBuffer.h" | |
34 #include "core/platform/graphics/gpu/DrawingBuffer.h" | |
35 #include "core/platform/image-decoders/ImageDecoder.h" | |
36 #include "platform/CheckedInt.h" | |
37 #include "platform/graphics/ImageObserver.h" | |
38 #include "third_party/skia/include/gpu/GrContext.h" | |
39 #include "third_party/skia/include/gpu/gl/GrGLInterface.h" | |
40 #include "wtf/CPU.h" | |
41 #include "wtf/text/CString.h" | |
42 #include "wtf/text/StringHash.h" | |
43 | |
44 #include "public/platform/Platform.h" | |
45 #include "public/platform/WebGraphicsContext3D.h" | |
46 #include "public/platform/WebGraphicsContext3DProvider.h" | |
47 | |
48 namespace WebCore { | |
49 | |
50 namespace { | |
51 | |
52 void getDrawingParameters(DrawingBuffer* drawingBuffer, blink::WebGraphicsContex
t3D* graphicsContext3D, | |
53 Platform3DObject* frameBufferId, int* width, int* heig
ht) | |
54 { | |
55 ASSERT(drawingBuffer); | |
56 *frameBufferId = drawingBuffer->framebuffer(); | |
57 *width = drawingBuffer->size().width(); | |
58 *height = drawingBuffer->size().height(); | |
59 } | |
60 | |
61 } // anonymous namespace | |
62 | |
63 GraphicsContext3D::GraphicsContext3D(PassOwnPtr<blink::WebGraphicsContext3D> web
Context, bool preserveDrawingBuffer) | |
64 : m_impl(webContext.get()) | |
65 , m_ownedWebContext(webContext) | |
66 , m_initializedAvailableExtensions(false) | |
67 , m_layerComposited(false) | |
68 , m_preserveDrawingBuffer(preserveDrawingBuffer) | |
69 , m_packAlignment(4) | |
70 , m_resourceSafety(ResourceSafetyUnknown) | |
71 , m_grContext(0) | |
72 { | |
73 } | |
74 | |
75 GraphicsContext3D::GraphicsContext3D(PassOwnPtr<blink::WebGraphicsContext3DProvi
der> provider, bool preserveDrawingBuffer) | |
76 : m_provider(provider) | |
77 , m_impl(m_provider->context3d()) | |
78 , m_initializedAvailableExtensions(false) | |
79 , m_layerComposited(false) | |
80 , m_preserveDrawingBuffer(preserveDrawingBuffer) | |
81 , m_packAlignment(4) | |
82 , m_resourceSafety(ResourceSafetyUnknown) | |
83 , m_grContext(m_provider->grContext()) | |
84 { | |
85 } | |
86 | |
87 GraphicsContext3D::~GraphicsContext3D() | |
88 { | |
89 setContextLostCallback(nullptr); | |
90 setErrorMessageCallback(nullptr); | |
91 } | |
92 | |
93 // Macros to assist in delegating from GraphicsContext3D to | |
94 // WebGraphicsContext3D. | |
95 | |
96 #define DELEGATE_TO_WEBCONTEXT(name) \ | |
97 void GraphicsContext3D::name() \ | |
98 { \ | |
99 m_impl->name(); \ | |
100 } | |
101 | |
102 #define DELEGATE_TO_WEBCONTEXT_R(name, rt) \ | |
103 rt GraphicsContext3D::name() \ | |
104 { \ | |
105 return m_impl->name(); \ | |
106 } | |
107 | |
108 #define DELEGATE_TO_WEBCONTEXT_1(name, t1) \ | |
109 void GraphicsContext3D::name(t1 a1) \ | |
110 { \ | |
111 m_impl->name(a1); \ | |
112 } | |
113 | |
114 #define DELEGATE_TO_WEBCONTEXT_1R(name, t1, rt) \ | |
115 rt GraphicsContext3D::name(t1 a1) \ | |
116 { \ | |
117 return m_impl->name(a1); \ | |
118 } | |
119 | |
120 #define DELEGATE_TO_WEBCONTEXT_2(name, t1, t2) \ | |
121 void GraphicsContext3D::name(t1 a1, t2 a2) \ | |
122 { \ | |
123 m_impl->name(a1, a2); \ | |
124 } | |
125 | |
126 #define DELEGATE_TO_WEBCONTEXT_2R(name, t1, t2, rt) \ | |
127 rt GraphicsContext3D::name(t1 a1, t2 a2) \ | |
128 { \ | |
129 return m_impl->name(a1, a2); \ | |
130 } | |
131 | |
132 #define DELEGATE_TO_WEBCONTEXT_3(name, t1, t2, t3) \ | |
133 void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3) \ | |
134 { \ | |
135 m_impl->name(a1, a2, a3); \ | |
136 } | |
137 | |
138 #define DELEGATE_TO_WEBCONTEXT_3R(name, t1, t2, t3, rt) \ | |
139 rt GraphicsContext3D::name(t1 a1, t2 a2, t3 a3) \ | |
140 { \ | |
141 return m_impl->name(a1, a2, a3); \ | |
142 } | |
143 | |
144 #define DELEGATE_TO_WEBCONTEXT_4(name, t1, t2, t3, t4) \ | |
145 void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4) \ | |
146 { \ | |
147 m_impl->name(a1, a2, a3, a4); \ | |
148 } | |
149 | |
150 #define DELEGATE_TO_WEBCONTEXT_4R(name, t1, t2, t3, t4, rt) \ | |
151 rt GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4) \ | |
152 { \ | |
153 return m_impl->name(a1, a2, a3, a4); \ | |
154 } | |
155 | |
156 #define DELEGATE_TO_WEBCONTEXT_5(name, t1, t2, t3, t4, t5) \ | |
157 void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) \ | |
158 { \ | |
159 m_impl->name(a1, a2, a3, a4, a5); \ | |
160 } | |
161 | |
162 #define DELEGATE_TO_WEBCONTEXT_6(name, t1, t2, t3, t4, t5, t6) \ | |
163 void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) \ | |
164 { \ | |
165 m_impl->name(a1, a2, a3, a4, a5, a6); \ | |
166 } | |
167 | |
168 #define DELEGATE_TO_WEBCONTEXT_6R(name, t1, t2, t3, t4, t5, t6, rt) \ | |
169 rt GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) \ | |
170 { \ | |
171 return m_impl->name(a1, a2, a3, a4, a5, a6); \ | |
172 } | |
173 | |
174 #define DELEGATE_TO_WEBCONTEXT_7(name, t1, t2, t3, t4, t5, t6, t7) \ | |
175 void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7) \ | |
176 { \ | |
177 m_impl->name(a1, a2, a3, a4, a5, a6, a7); \ | |
178 } | |
179 | |
180 #define DELEGATE_TO_WEBCONTEXT_7R(name, t1, t2, t3, t4, t5, t6, t7, rt) \ | |
181 rt GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7) \ | |
182 { \ | |
183 return m_impl->name(a1, a2, a3, a4, a5, a6, a7); \ | |
184 } | |
185 | |
186 #define DELEGATE_TO_WEBCONTEXT_8(name, t1, t2, t3, t4, t5, t6, t7, t8) \ | |
187 void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8
a8) \ | |
188 { \ | |
189 m_impl->name(a1, a2, a3, a4, a5, a6, a7, a8); \ | |
190 } | |
191 | |
192 #define DELEGATE_TO_WEBCONTEXT_9(name, t1, t2, t3, t4, t5, t6, t7, t8, t9) \ | |
193 void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8
a8, t9 a9) \ | |
194 { \ | |
195 m_impl->name(a1, a2, a3, a4, a5, a6, a7, a8, a9); \ | |
196 } | |
197 | |
198 #define DELEGATE_TO_WEBCONTEXT_9R(name, t1, t2, t3, t4, t5, t6, t7, t8, t9, rt)
\ | |
199 rt GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a
8, t9 a9) \ | |
200 { \ | |
201 return m_impl->name(a1, a2, a3, a4, a5, a6, a7, a8, a9); \ | |
202 } | |
203 | |
204 class GraphicsContext3DContextLostCallbackAdapter : public blink::WebGraphicsCon
text3D::WebGraphicsContextLostCallback { | |
205 public: | |
206 GraphicsContext3DContextLostCallbackAdapter(PassOwnPtr<GraphicsContext3D::Co
ntextLostCallback> callback) | |
207 : m_contextLostCallback(callback) { } | |
208 virtual ~GraphicsContext3DContextLostCallbackAdapter() { } | |
209 | |
210 virtual void onContextLost() | |
211 { | |
212 if (m_contextLostCallback) | |
213 m_contextLostCallback->onContextLost(); | |
214 } | |
215 private: | |
216 OwnPtr<GraphicsContext3D::ContextLostCallback> m_contextLostCallback; | |
217 }; | |
218 | |
219 class GraphicsContext3DErrorMessageCallbackAdapter : public blink::WebGraphicsCo
ntext3D::WebGraphicsErrorMessageCallback { | |
220 public: | |
221 GraphicsContext3DErrorMessageCallbackAdapter(PassOwnPtr<GraphicsContext3D::E
rrorMessageCallback> callback) | |
222 : m_errorMessageCallback(callback) { } | |
223 virtual ~GraphicsContext3DErrorMessageCallbackAdapter() { } | |
224 | |
225 virtual void onErrorMessage(const blink::WebString& message, blink::WGC3Dint
id) | |
226 { | |
227 if (m_errorMessageCallback) | |
228 m_errorMessageCallback->onErrorMessage(message, id); | |
229 } | |
230 private: | |
231 OwnPtr<GraphicsContext3D::ErrorMessageCallback> m_errorMessageCallback; | |
232 }; | |
233 | |
234 void GraphicsContext3D::setContextLostCallback(PassOwnPtr<GraphicsContext3D::Con
textLostCallback> callback) | |
235 { | |
236 if (m_ownedWebContext) { | |
237 m_contextLostCallbackAdapter = adoptPtr(new GraphicsContext3DContextLost
CallbackAdapter(callback)); | |
238 m_ownedWebContext->setContextLostCallback(m_contextLostCallbackAdapter.g
et()); | |
239 } | |
240 } | |
241 | |
242 void GraphicsContext3D::setErrorMessageCallback(PassOwnPtr<GraphicsContext3D::Er
rorMessageCallback> callback) | |
243 { | |
244 if (m_ownedWebContext) { | |
245 m_errorMessageCallbackAdapter = adoptPtr(new GraphicsContext3DErrorMessa
geCallbackAdapter(callback)); | |
246 m_ownedWebContext->setErrorMessageCallback(m_errorMessageCallbackAdapter
.get()); | |
247 } | |
248 } | |
249 | |
250 PassRefPtr<GraphicsContext3D> GraphicsContext3D::create(GraphicsContext3D::Attri
butes attrs) | |
251 { | |
252 blink::WebGraphicsContext3D::Attributes webAttributes; | |
253 webAttributes.alpha = attrs.alpha; | |
254 webAttributes.depth = attrs.depth; | |
255 webAttributes.stencil = attrs.stencil; | |
256 webAttributes.antialias = attrs.antialias; | |
257 webAttributes.premultipliedAlpha = attrs.premultipliedAlpha; | |
258 webAttributes.noExtensions = attrs.noExtensions; | |
259 webAttributes.shareResources = attrs.shareResources; | |
260 webAttributes.preferDiscreteGPU = attrs.preferDiscreteGPU; | |
261 webAttributes.failIfMajorPerformanceCaveat = attrs.failIfMajorPerformanceCav
eat; | |
262 webAttributes.topDocumentURL = attrs.topDocumentURL.string(); | |
263 | |
264 OwnPtr<blink::WebGraphicsContext3D> webContext = adoptPtr(blink::Platform::c
urrent()->createOffscreenGraphicsContext3D(webAttributes)); | |
265 if (!webContext) | |
266 return 0; | |
267 | |
268 return GraphicsContext3D::createGraphicsContextFromWebContext(webContext.rel
ease(), attrs.preserveDrawingBuffer); | |
269 } | |
270 | |
271 PassRefPtr<GraphicsContext3D> GraphicsContext3D::createGraphicsContextFromProvid
er(PassOwnPtr<blink::WebGraphicsContext3DProvider> provider, bool preserveDrawin
gBuffer) | |
272 { | |
273 RefPtr<GraphicsContext3D> context = adoptRef(new GraphicsContext3D(provider,
preserveDrawingBuffer)); | |
274 return context.release(); | |
275 } | |
276 | |
277 PassRefPtr<GraphicsContext3D> GraphicsContext3D::createGraphicsContextFromWebCon
text(PassOwnPtr<blink::WebGraphicsContext3D> webContext, bool preserveDrawingBuf
fer) | |
278 { | |
279 RefPtr<GraphicsContext3D> context = adoptRef(new GraphicsContext3D(webContex
t, preserveDrawingBuffer)); | |
280 return context.release(); | |
281 } | |
282 | |
283 GrContext* GraphicsContext3D::grContext() | |
284 { | |
285 return m_grContext; | |
286 } | |
287 | |
288 DELEGATE_TO_WEBCONTEXT_R(makeContextCurrent, bool) | |
289 DELEGATE_TO_WEBCONTEXT_R(lastFlushID, uint32_t) | |
290 | |
291 DELEGATE_TO_WEBCONTEXT_1(activeTexture, GC3Denum) | |
292 DELEGATE_TO_WEBCONTEXT_2(attachShader, Platform3DObject, Platform3DObject) | |
293 | |
294 void GraphicsContext3D::bindAttribLocation(Platform3DObject program, GC3Duint in
dex, const String& name) | |
295 { | |
296 m_impl->bindAttribLocation(program, index, name.utf8().data()); | |
297 } | |
298 | |
299 DELEGATE_TO_WEBCONTEXT_2(bindBuffer, GC3Denum, Platform3DObject) | |
300 DELEGATE_TO_WEBCONTEXT_2(bindFramebuffer, GC3Denum, Platform3DObject) | |
301 DELEGATE_TO_WEBCONTEXT_2(bindRenderbuffer, GC3Denum, Platform3DObject) | |
302 DELEGATE_TO_WEBCONTEXT_2(bindTexture, GC3Denum, Platform3DObject) | |
303 DELEGATE_TO_WEBCONTEXT_4(blendColor, GC3Dclampf, GC3Dclampf, GC3Dclampf, GC3Dcla
mpf) | |
304 DELEGATE_TO_WEBCONTEXT_1(blendEquation, GC3Denum) | |
305 DELEGATE_TO_WEBCONTEXT_2(blendEquationSeparate, GC3Denum, GC3Denum) | |
306 DELEGATE_TO_WEBCONTEXT_2(blendFunc, GC3Denum, GC3Denum) | |
307 DELEGATE_TO_WEBCONTEXT_4(blendFuncSeparate, GC3Denum, GC3Denum, GC3Denum, GC3Den
um) | |
308 | |
309 void GraphicsContext3D::bufferData(GC3Denum target, GC3Dsizeiptr size, GC3Denum
usage) | |
310 { | |
311 bufferData(target, size, 0, usage); | |
312 } | |
313 | |
314 DELEGATE_TO_WEBCONTEXT_4(bufferData, GC3Denum, GC3Dsizeiptr, const void*, GC3Den
um) | |
315 DELEGATE_TO_WEBCONTEXT_4(bufferSubData, GC3Denum, GC3Dintptr, GC3Dsizeiptr, cons
t void*) | |
316 | |
317 DELEGATE_TO_WEBCONTEXT_1R(checkFramebufferStatus, GC3Denum, GC3Denum) | |
318 DELEGATE_TO_WEBCONTEXT_1(clear, GC3Dbitfield) | |
319 DELEGATE_TO_WEBCONTEXT_4(clearColor, GC3Dclampf, GC3Dclampf, GC3Dclampf, GC3Dcla
mpf) | |
320 DELEGATE_TO_WEBCONTEXT_1(clearDepth, GC3Dclampf) | |
321 DELEGATE_TO_WEBCONTEXT_1(clearStencil, GC3Dint) | |
322 DELEGATE_TO_WEBCONTEXT_4(colorMask, GC3Dboolean, GC3Dboolean, GC3Dboolean, GC3Db
oolean) | |
323 DELEGATE_TO_WEBCONTEXT_1(compileShader, Platform3DObject) | |
324 | |
325 DELEGATE_TO_WEBCONTEXT_8(compressedTexImage2D, GC3Denum, GC3Dint, GC3Denum, GC3D
int, GC3Dint, GC3Dsizei, GC3Dsizei, const void*) | |
326 DELEGATE_TO_WEBCONTEXT_9(compressedTexSubImage2D, GC3Denum, GC3Dint, GC3Dint, GC
3Dint, GC3Dint, GC3Dint, GC3Denum, GC3Dsizei, const void*) | |
327 DELEGATE_TO_WEBCONTEXT_8(copyTexImage2D, GC3Denum, GC3Dint, GC3Denum, GC3Dint, G
C3Dint, GC3Dsizei, GC3Dsizei, GC3Dint) | |
328 DELEGATE_TO_WEBCONTEXT_8(copyTexSubImage2D, GC3Denum, GC3Dint, GC3Dint, GC3Dint,
GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei) | |
329 DELEGATE_TO_WEBCONTEXT_1(cullFace, GC3Denum) | |
330 DELEGATE_TO_WEBCONTEXT_1(depthFunc, GC3Denum) | |
331 DELEGATE_TO_WEBCONTEXT_1(depthMask, GC3Dboolean) | |
332 DELEGATE_TO_WEBCONTEXT_2(depthRange, GC3Dclampf, GC3Dclampf) | |
333 DELEGATE_TO_WEBCONTEXT_2(detachShader, Platform3DObject, Platform3DObject) | |
334 DELEGATE_TO_WEBCONTEXT_1(disable, GC3Denum) | |
335 DELEGATE_TO_WEBCONTEXT_1(disableVertexAttribArray, GC3Duint) | |
336 DELEGATE_TO_WEBCONTEXT_3(drawArrays, GC3Denum, GC3Dint, GC3Dsizei) | |
337 DELEGATE_TO_WEBCONTEXT_4(drawElements, GC3Denum, GC3Dsizei, GC3Denum, GC3Dintptr
) | |
338 | |
339 DELEGATE_TO_WEBCONTEXT_1(enable, GC3Denum) | |
340 DELEGATE_TO_WEBCONTEXT_1(enableVertexAttribArray, GC3Duint) | |
341 DELEGATE_TO_WEBCONTEXT(finish) | |
342 DELEGATE_TO_WEBCONTEXT(flush) | |
343 DELEGATE_TO_WEBCONTEXT_4(framebufferRenderbuffer, GC3Denum, GC3Denum, GC3Denum,
Platform3DObject) | |
344 DELEGATE_TO_WEBCONTEXT_5(framebufferTexture2D, GC3Denum, GC3Denum, GC3Denum, Pla
tform3DObject, GC3Dint) | |
345 DELEGATE_TO_WEBCONTEXT_1(frontFace, GC3Denum) | |
346 DELEGATE_TO_WEBCONTEXT_1(generateMipmap, GC3Denum) | |
347 | |
348 bool GraphicsContext3D::getActiveAttrib(Platform3DObject program, GC3Duint index
, ActiveInfo& info) | |
349 { | |
350 blink::WebGraphicsContext3D::ActiveInfo webInfo; | |
351 if (!m_impl->getActiveAttrib(program, index, webInfo)) | |
352 return false; | |
353 info.name = webInfo.name; | |
354 info.type = webInfo.type; | |
355 info.size = webInfo.size; | |
356 return true; | |
357 } | |
358 | |
359 bool GraphicsContext3D::getActiveUniform(Platform3DObject program, GC3Duint inde
x, ActiveInfo& info) | |
360 { | |
361 blink::WebGraphicsContext3D::ActiveInfo webInfo; | |
362 if (!m_impl->getActiveUniform(program, index, webInfo)) | |
363 return false; | |
364 info.name = webInfo.name; | |
365 info.type = webInfo.type; | |
366 info.size = webInfo.size; | |
367 return true; | |
368 } | |
369 | |
370 DELEGATE_TO_WEBCONTEXT_4(getAttachedShaders, Platform3DObject, GC3Dsizei, GC3Dsi
zei*, Platform3DObject*) | |
371 | |
372 GC3Dint GraphicsContext3D::getAttribLocation(Platform3DObject program, const Str
ing& name) | |
373 { | |
374 return m_impl->getAttribLocation(program, name.utf8().data()); | |
375 } | |
376 | |
377 DELEGATE_TO_WEBCONTEXT_2(getBooleanv, GC3Denum, GC3Dboolean*) | |
378 DELEGATE_TO_WEBCONTEXT_3(getBufferParameteriv, GC3Denum, GC3Denum, GC3Dint*) | |
379 | |
380 GraphicsContext3D::Attributes GraphicsContext3D::getContextAttributes() | |
381 { | |
382 blink::WebGraphicsContext3D::Attributes webAttributes = m_impl->getContextAt
tributes(); | |
383 GraphicsContext3D::Attributes attributes; | |
384 attributes.alpha = webAttributes.alpha; | |
385 attributes.depth = webAttributes.depth; | |
386 attributes.stencil = webAttributes.stencil; | |
387 attributes.antialias = webAttributes.antialias; | |
388 attributes.premultipliedAlpha = webAttributes.premultipliedAlpha; | |
389 attributes.preserveDrawingBuffer = m_preserveDrawingBuffer; | |
390 attributes.preferDiscreteGPU = webAttributes.preferDiscreteGPU; | |
391 return attributes; | |
392 } | |
393 | |
394 DELEGATE_TO_WEBCONTEXT_R(getError, GC3Denum) | |
395 DELEGATE_TO_WEBCONTEXT_2(getFloatv, GC3Denum, GC3Dfloat*) | |
396 DELEGATE_TO_WEBCONTEXT_4(getFramebufferAttachmentParameteriv, GC3Denum, GC3Denum
, GC3Denum, GC3Dint*) | |
397 DELEGATE_TO_WEBCONTEXT_2(getIntegerv, GC3Denum, GC3Dint*) | |
398 DELEGATE_TO_WEBCONTEXT_3(getProgramiv, Platform3DObject, GC3Denum, GC3Dint*) | |
399 DELEGATE_TO_WEBCONTEXT_1R(getProgramInfoLog, Platform3DObject, String) | |
400 DELEGATE_TO_WEBCONTEXT_3(getRenderbufferParameteriv, GC3Denum, GC3Denum, GC3Dint
*) | |
401 DELEGATE_TO_WEBCONTEXT_3(getShaderiv, Platform3DObject, GC3Denum, GC3Dint*) | |
402 DELEGATE_TO_WEBCONTEXT_1R(getShaderInfoLog, Platform3DObject, String) | |
403 DELEGATE_TO_WEBCONTEXT_4(getShaderPrecisionFormat, GC3Denum, GC3Denum, GC3Dint*,
GC3Dint*) | |
404 DELEGATE_TO_WEBCONTEXT_1R(getShaderSource, Platform3DObject, String) | |
405 DELEGATE_TO_WEBCONTEXT_1R(getString, GC3Denum, String) | |
406 DELEGATE_TO_WEBCONTEXT_3(getTexParameterfv, GC3Denum, GC3Denum, GC3Dfloat*) | |
407 DELEGATE_TO_WEBCONTEXT_3(getTexParameteriv, GC3Denum, GC3Denum, GC3Dint*) | |
408 DELEGATE_TO_WEBCONTEXT_3(getUniformfv, Platform3DObject, GC3Dint, GC3Dfloat*) | |
409 DELEGATE_TO_WEBCONTEXT_3(getUniformiv, Platform3DObject, GC3Dint, GC3Dint*) | |
410 | |
411 GC3Dint GraphicsContext3D::getUniformLocation(Platform3DObject program, const St
ring& name) | |
412 { | |
413 return m_impl->getUniformLocation(program, name.utf8().data()); | |
414 } | |
415 | |
416 DELEGATE_TO_WEBCONTEXT_3(getVertexAttribfv, GC3Duint, GC3Denum, GC3Dfloat*) | |
417 DELEGATE_TO_WEBCONTEXT_3(getVertexAttribiv, GC3Duint, GC3Denum, GC3Dint*) | |
418 DELEGATE_TO_WEBCONTEXT_2R(getVertexAttribOffset, GC3Duint, GC3Denum, GC3Dsizeipt
r) | |
419 | |
420 DELEGATE_TO_WEBCONTEXT_2(hint, GC3Denum, GC3Denum) | |
421 DELEGATE_TO_WEBCONTEXT_1R(isBuffer, Platform3DObject, GC3Dboolean) | |
422 DELEGATE_TO_WEBCONTEXT_1R(isEnabled, GC3Denum, GC3Dboolean) | |
423 DELEGATE_TO_WEBCONTEXT_1R(isFramebuffer, Platform3DObject, GC3Dboolean) | |
424 DELEGATE_TO_WEBCONTEXT_1R(isProgram, Platform3DObject, GC3Dboolean) | |
425 DELEGATE_TO_WEBCONTEXT_1R(isRenderbuffer, Platform3DObject, GC3Dboolean) | |
426 DELEGATE_TO_WEBCONTEXT_1R(isShader, Platform3DObject, GC3Dboolean) | |
427 DELEGATE_TO_WEBCONTEXT_1R(isTexture, Platform3DObject, GC3Dboolean) | |
428 DELEGATE_TO_WEBCONTEXT_1(lineWidth, GC3Dfloat) | |
429 DELEGATE_TO_WEBCONTEXT_1(linkProgram, Platform3DObject) | |
430 | |
431 void GraphicsContext3D::pixelStorei(GC3Denum pname, GC3Dint param) | |
432 { | |
433 if (pname == PACK_ALIGNMENT) | |
434 m_packAlignment = param; | |
435 m_impl->pixelStorei(pname, param); | |
436 } | |
437 | |
438 DELEGATE_TO_WEBCONTEXT_2(polygonOffset, GC3Dfloat, GC3Dfloat) | |
439 | |
440 DELEGATE_TO_WEBCONTEXT_7(readPixels, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3
Denum, GC3Denum, void*) | |
441 | |
442 DELEGATE_TO_WEBCONTEXT(releaseShaderCompiler) | |
443 DELEGATE_TO_WEBCONTEXT_4(renderbufferStorage, GC3Denum, GC3Denum, GC3Dsizei, GC3
Dsizei) | |
444 DELEGATE_TO_WEBCONTEXT_2(sampleCoverage, GC3Dclampf, GC3Dboolean) | |
445 DELEGATE_TO_WEBCONTEXT_4(scissor, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei) | |
446 | |
447 void GraphicsContext3D::shaderSource(Platform3DObject shader, const String& stri
ng) | |
448 { | |
449 m_impl->shaderSource(shader, string.utf8().data()); | |
450 } | |
451 | |
452 DELEGATE_TO_WEBCONTEXT_3(stencilFunc, GC3Denum, GC3Dint, GC3Duint) | |
453 DELEGATE_TO_WEBCONTEXT_4(stencilFuncSeparate, GC3Denum, GC3Denum, GC3Dint, GC3Du
int) | |
454 DELEGATE_TO_WEBCONTEXT_1(stencilMask, GC3Duint) | |
455 DELEGATE_TO_WEBCONTEXT_2(stencilMaskSeparate, GC3Denum, GC3Duint) | |
456 DELEGATE_TO_WEBCONTEXT_3(stencilOp, GC3Denum, GC3Denum, GC3Denum) | |
457 DELEGATE_TO_WEBCONTEXT_4(stencilOpSeparate, GC3Denum, GC3Denum, GC3Denum, GC3Den
um) | |
458 | |
459 DELEGATE_TO_WEBCONTEXT_9(texImage2D, GC3Denum, GC3Dint, GC3Denum, GC3Dsizei, GC3
Dsizei, GC3Dint, GC3Denum, GC3Denum, const void*) | |
460 DELEGATE_TO_WEBCONTEXT_3(texParameterf, GC3Denum, GC3Denum, GC3Dfloat) | |
461 DELEGATE_TO_WEBCONTEXT_3(texParameteri, GC3Denum, GC3Denum, GC3Dint) | |
462 DELEGATE_TO_WEBCONTEXT_9(texSubImage2D, GC3Denum, GC3Dint, GC3Dint, GC3Dint, GC3
Dsizei, GC3Dsizei, GC3Denum, GC3Denum, const void*) | |
463 | |
464 DELEGATE_TO_WEBCONTEXT_2(uniform1f, GC3Dint, GC3Dfloat) | |
465 DELEGATE_TO_WEBCONTEXT_3(uniform1fv, GC3Dint, GC3Dsizei, GC3Dfloat*) | |
466 DELEGATE_TO_WEBCONTEXT_2(uniform1i, GC3Dint, GC3Dint) | |
467 DELEGATE_TO_WEBCONTEXT_3(uniform1iv, GC3Dint, GC3Dsizei, GC3Dint*) | |
468 DELEGATE_TO_WEBCONTEXT_3(uniform2f, GC3Dint, GC3Dfloat, GC3Dfloat) | |
469 DELEGATE_TO_WEBCONTEXT_3(uniform2fv, GC3Dint, GC3Dsizei, GC3Dfloat*) | |
470 DELEGATE_TO_WEBCONTEXT_3(uniform2i, GC3Dint, GC3Dint, GC3Dint) | |
471 DELEGATE_TO_WEBCONTEXT_3(uniform2iv, GC3Dint, GC3Dsizei, GC3Dint*) | |
472 DELEGATE_TO_WEBCONTEXT_4(uniform3f, GC3Dint, GC3Dfloat, GC3Dfloat, GC3Dfloat) | |
473 DELEGATE_TO_WEBCONTEXT_3(uniform3fv, GC3Dint, GC3Dsizei, GC3Dfloat*) | |
474 DELEGATE_TO_WEBCONTEXT_4(uniform3i, GC3Dint, GC3Dint, GC3Dint, GC3Dint) | |
475 DELEGATE_TO_WEBCONTEXT_3(uniform3iv, GC3Dint, GC3Dsizei, GC3Dint*) | |
476 DELEGATE_TO_WEBCONTEXT_5(uniform4f, GC3Dint, GC3Dfloat, GC3Dfloat, GC3Dfloat, GC
3Dfloat) | |
477 DELEGATE_TO_WEBCONTEXT_3(uniform4fv, GC3Dint, GC3Dsizei, GC3Dfloat*) | |
478 DELEGATE_TO_WEBCONTEXT_5(uniform4i, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dint) | |
479 DELEGATE_TO_WEBCONTEXT_3(uniform4iv, GC3Dint, GC3Dsizei, GC3Dint*) | |
480 DELEGATE_TO_WEBCONTEXT_4(uniformMatrix2fv, GC3Dint, GC3Dsizei, GC3Dboolean, GC3D
float*) | |
481 DELEGATE_TO_WEBCONTEXT_4(uniformMatrix3fv, GC3Dint, GC3Dsizei, GC3Dboolean, GC3D
float*) | |
482 DELEGATE_TO_WEBCONTEXT_4(uniformMatrix4fv, GC3Dint, GC3Dsizei, GC3Dboolean, GC3D
float*) | |
483 | |
484 DELEGATE_TO_WEBCONTEXT_1(useProgram, Platform3DObject) | |
485 DELEGATE_TO_WEBCONTEXT_1(validateProgram, Platform3DObject) | |
486 | |
487 DELEGATE_TO_WEBCONTEXT_2(vertexAttrib1f, GC3Duint, GC3Dfloat) | |
488 DELEGATE_TO_WEBCONTEXT_2(vertexAttrib1fv, GC3Duint, GC3Dfloat*) | |
489 DELEGATE_TO_WEBCONTEXT_3(vertexAttrib2f, GC3Duint, GC3Dfloat, GC3Dfloat) | |
490 DELEGATE_TO_WEBCONTEXT_2(vertexAttrib2fv, GC3Duint, GC3Dfloat*) | |
491 DELEGATE_TO_WEBCONTEXT_4(vertexAttrib3f, GC3Duint, GC3Dfloat, GC3Dfloat, GC3Dflo
at) | |
492 DELEGATE_TO_WEBCONTEXT_2(vertexAttrib3fv, GC3Duint, GC3Dfloat*) | |
493 DELEGATE_TO_WEBCONTEXT_5(vertexAttrib4f, GC3Duint, GC3Dfloat, GC3Dfloat, GC3Dflo
at, GC3Dfloat) | |
494 DELEGATE_TO_WEBCONTEXT_2(vertexAttrib4fv, GC3Duint, GC3Dfloat*) | |
495 DELEGATE_TO_WEBCONTEXT_6(vertexAttribPointer, GC3Duint, GC3Dint, GC3Denum, GC3Db
oolean, GC3Dsizei, GC3Dintptr) | |
496 | |
497 DELEGATE_TO_WEBCONTEXT_4(viewport, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei) | |
498 | |
499 void GraphicsContext3D::markContextChanged() | |
500 { | |
501 m_layerComposited = false; | |
502 } | |
503 | |
504 bool GraphicsContext3D::layerComposited() const | |
505 { | |
506 return m_layerComposited; | |
507 } | |
508 | |
509 void GraphicsContext3D::markLayerComposited() | |
510 { | |
511 m_layerComposited = true; | |
512 } | |
513 | |
514 void GraphicsContext3D::paintRenderingResultsToCanvas(ImageBuffer* imageBuffer,
DrawingBuffer* drawingBuffer) | |
515 { | |
516 Platform3DObject framebufferId; | |
517 int width, height; | |
518 getDrawingParameters(drawingBuffer, m_impl, &framebufferId, &width, &height)
; | |
519 paintFramebufferToCanvas(framebufferId, width, height, !getContextAttributes
().premultipliedAlpha, imageBuffer); | |
520 } | |
521 | |
522 PassRefPtr<Uint8ClampedArray> GraphicsContext3D::paintRenderingResultsToImageDat
a(DrawingBuffer* drawingBuffer, int& width, int& height) | |
523 { | |
524 if (getContextAttributes().premultipliedAlpha) | |
525 return 0; | |
526 | |
527 Platform3DObject framebufferId; | |
528 getDrawingParameters(drawingBuffer, m_impl, &framebufferId, &width, &height)
; | |
529 | |
530 Checked<int, RecordOverflow> dataSize = 4; | |
531 dataSize *= width; | |
532 dataSize *= height; | |
533 if (dataSize.hasOverflowed()) | |
534 return 0; | |
535 | |
536 RefPtr<Uint8ClampedArray> pixels = Uint8ClampedArray::createUninitialized(wi
dth * height * 4); | |
537 | |
538 m_impl->bindFramebuffer(FRAMEBUFFER, framebufferId); | |
539 readBackFramebuffer(pixels->data(), width, height, ReadbackRGBA, AlphaDoNoth
ing); | |
540 flipVertically(pixels->data(), width, height); | |
541 | |
542 return pixels.release(); | |
543 } | |
544 | |
545 void GraphicsContext3D::readBackFramebuffer(unsigned char* pixels, int width, in
t height, ReadbackOrder readbackOrder, AlphaOp op) | |
546 { | |
547 if (m_packAlignment > 4) | |
548 m_impl->pixelStorei(PACK_ALIGNMENT, 1); | |
549 m_impl->readPixels(0, 0, width, height, RGBA, UNSIGNED_BYTE, pixels); | |
550 if (m_packAlignment > 4) | |
551 m_impl->pixelStorei(PACK_ALIGNMENT, m_packAlignment); | |
552 | |
553 size_t bufferSize = 4 * width * height; | |
554 | |
555 if (readbackOrder == ReadbackSkia) { | |
556 #if (SK_R32_SHIFT == 16) && !SK_B32_SHIFT | |
557 // Swizzle red and blue channels to match SkBitmap's byte ordering. | |
558 // TODO(kbr): expose GL_BGRA as extension. | |
559 for (size_t i = 0; i < bufferSize; i += 4) { | |
560 std::swap(pixels[i], pixels[i + 2]); | |
561 } | |
562 #endif | |
563 } | |
564 | |
565 if (op == AlphaDoPremultiply) { | |
566 for (size_t i = 0; i < bufferSize; i += 4) { | |
567 pixels[i + 0] = std::min(255, pixels[i + 0] * pixels[i + 3] / 255); | |
568 pixels[i + 1] = std::min(255, pixels[i + 1] * pixels[i + 3] / 255); | |
569 pixels[i + 2] = std::min(255, pixels[i + 2] * pixels[i + 3] / 255); | |
570 } | |
571 } else if (op != AlphaDoNothing) { | |
572 ASSERT_NOT_REACHED(); | |
573 } | |
574 } | |
575 | |
576 DELEGATE_TO_WEBCONTEXT_R(createBuffer, Platform3DObject) | |
577 DELEGATE_TO_WEBCONTEXT_R(createFramebuffer, Platform3DObject) | |
578 DELEGATE_TO_WEBCONTEXT_R(createProgram, Platform3DObject) | |
579 DELEGATE_TO_WEBCONTEXT_R(createRenderbuffer, Platform3DObject) | |
580 DELEGATE_TO_WEBCONTEXT_1R(createShader, GC3Denum, Platform3DObject) | |
581 DELEGATE_TO_WEBCONTEXT_R(createTexture, Platform3DObject) | |
582 | |
583 DELEGATE_TO_WEBCONTEXT_1(deleteBuffer, Platform3DObject) | |
584 DELEGATE_TO_WEBCONTEXT_1(deleteFramebuffer, Platform3DObject) | |
585 DELEGATE_TO_WEBCONTEXT_1(deleteProgram, Platform3DObject) | |
586 DELEGATE_TO_WEBCONTEXT_1(deleteRenderbuffer, Platform3DObject) | |
587 DELEGATE_TO_WEBCONTEXT_1(deleteShader, Platform3DObject) | |
588 DELEGATE_TO_WEBCONTEXT_1(deleteTexture, Platform3DObject) | |
589 | |
590 DELEGATE_TO_WEBCONTEXT_1(synthesizeGLError, GC3Denum) | |
591 | |
592 Extensions3D* GraphicsContext3D::extensions() | |
593 { | |
594 if (!m_extensions) | |
595 m_extensions = adoptPtr(new Extensions3D(this)); | |
596 return m_extensions.get(); | |
597 } | |
598 | |
599 bool GraphicsContext3D::texImage2DResourceSafe(GC3Denum target, GC3Dint level, G
C3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3De
num format, GC3Denum type, GC3Dint unpackAlignment) | |
600 { | |
601 ASSERT(unpackAlignment == 1 || unpackAlignment == 2 || unpackAlignment == 4
|| unpackAlignment == 8); | |
602 texImage2D(target, level, internalformat, width, height, border, format, typ
e, 0); | |
603 return true; | |
604 } | |
605 | |
606 bool GraphicsContext3D::computeFormatAndTypeParameters(GC3Denum format, | |
607 GC3Denum type, | |
608 unsigned int* componentsP
erPixel, | |
609 unsigned int* bytesPerCom
ponent) | |
610 { | |
611 switch (format) { | |
612 case GraphicsContext3D::ALPHA: | |
613 case GraphicsContext3D::LUMINANCE: | |
614 case GraphicsContext3D::DEPTH_COMPONENT: | |
615 case GraphicsContext3D::DEPTH_STENCIL: | |
616 *componentsPerPixel = 1; | |
617 break; | |
618 case GraphicsContext3D::LUMINANCE_ALPHA: | |
619 *componentsPerPixel = 2; | |
620 break; | |
621 case GraphicsContext3D::RGB: | |
622 *componentsPerPixel = 3; | |
623 break; | |
624 case GraphicsContext3D::RGBA: | |
625 case Extensions3D::BGRA_EXT: // GL_EXT_texture_format_BGRA8888 | |
626 *componentsPerPixel = 4; | |
627 break; | |
628 default: | |
629 return false; | |
630 } | |
631 switch (type) { | |
632 case GraphicsContext3D::UNSIGNED_BYTE: | |
633 *bytesPerComponent = sizeof(GC3Dubyte); | |
634 break; | |
635 case GraphicsContext3D::UNSIGNED_SHORT: | |
636 *bytesPerComponent = sizeof(GC3Dushort); | |
637 break; | |
638 case GraphicsContext3D::UNSIGNED_SHORT_5_6_5: | |
639 case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4: | |
640 case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1: | |
641 *componentsPerPixel = 1; | |
642 *bytesPerComponent = sizeof(GC3Dushort); | |
643 break; | |
644 case GraphicsContext3D::UNSIGNED_INT_24_8: | |
645 case GraphicsContext3D::UNSIGNED_INT: | |
646 *bytesPerComponent = sizeof(GC3Duint); | |
647 break; | |
648 case GraphicsContext3D::FLOAT: // OES_texture_float | |
649 *bytesPerComponent = sizeof(GC3Dfloat); | |
650 break; | |
651 case GraphicsContext3D::HALF_FLOAT_OES: // OES_texture_half_float | |
652 *bytesPerComponent = sizeof(GC3Dhalffloat); | |
653 break; | |
654 default: | |
655 return false; | |
656 } | |
657 return true; | |
658 } | |
659 | |
660 GC3Denum GraphicsContext3D::computeImageSizeInBytes(GC3Denum format, GC3Denum ty
pe, GC3Dsizei width, GC3Dsizei height, GC3Dint alignment, | |
661 unsigned int* imageSizeInByt
es, unsigned int* paddingInBytes) | |
662 { | |
663 ASSERT(imageSizeInBytes); | |
664 ASSERT(alignment == 1 || alignment == 2 || alignment == 4 || alignment == 8)
; | |
665 if (width < 0 || height < 0) | |
666 return GraphicsContext3D::INVALID_VALUE; | |
667 unsigned int bytesPerComponent, componentsPerPixel; | |
668 if (!computeFormatAndTypeParameters(format, type, &bytesPerComponent, &compo
nentsPerPixel)) | |
669 return GraphicsContext3D::INVALID_ENUM; | |
670 if (!width || !height) { | |
671 *imageSizeInBytes = 0; | |
672 if (paddingInBytes) | |
673 *paddingInBytes = 0; | |
674 return GraphicsContext3D::NO_ERROR; | |
675 } | |
676 CheckedInt<uint32_t> checkedValue(bytesPerComponent * componentsPerPixel); | |
677 checkedValue *= width; | |
678 if (!checkedValue.isValid()) | |
679 return GraphicsContext3D::INVALID_VALUE; | |
680 unsigned int validRowSize = checkedValue.value(); | |
681 unsigned int padding = 0; | |
682 unsigned int residual = validRowSize % alignment; | |
683 if (residual) { | |
684 padding = alignment - residual; | |
685 checkedValue += padding; | |
686 } | |
687 // Last row needs no padding. | |
688 checkedValue *= (height - 1); | |
689 checkedValue += validRowSize; | |
690 if (!checkedValue.isValid()) | |
691 return GraphicsContext3D::INVALID_VALUE; | |
692 *imageSizeInBytes = checkedValue.value(); | |
693 if (paddingInBytes) | |
694 *paddingInBytes = padding; | |
695 return GraphicsContext3D::NO_ERROR; | |
696 } | |
697 | |
698 GraphicsContext3D::ImageExtractor::ImageExtractor(Image* image, ImageHtmlDomSour
ce imageHtmlDomSource, bool premultiplyAlpha, bool ignoreGammaAndColorProfile) | |
699 { | |
700 m_image = image; | |
701 m_imageHtmlDomSource = imageHtmlDomSource; | |
702 m_extractSucceeded = extractImage(premultiplyAlpha, ignoreGammaAndColorProfi
le); | |
703 } | |
704 | |
705 GraphicsContext3D::ImageExtractor::~ImageExtractor() | |
706 { | |
707 if (m_skiaImage) | |
708 m_skiaImage->bitmap().unlockPixels(); | |
709 } | |
710 | |
711 bool GraphicsContext3D::ImageExtractor::extractImage(bool premultiplyAlpha, bool
ignoreGammaAndColorProfile) | |
712 { | |
713 if (!m_image) | |
714 return false; | |
715 m_skiaImage = m_image->nativeImageForCurrentFrame(); | |
716 m_alphaOp = AlphaDoNothing; | |
717 bool hasAlpha = m_skiaImage ? !m_skiaImage->bitmap().isOpaque() : true; | |
718 if ((!m_skiaImage || ignoreGammaAndColorProfile || (hasAlpha && !premultiply
Alpha)) && m_image->data()) { | |
719 // Attempt to get raw unpremultiplied image data. | |
720 OwnPtr<ImageDecoder> decoder(ImageDecoder::create( | |
721 *(m_image->data()), ImageSource::AlphaNotPremultiplied, | |
722 ignoreGammaAndColorProfile ? ImageSource::GammaAndColorProfileIgnore
d : ImageSource::GammaAndColorProfileApplied)); | |
723 if (!decoder) | |
724 return false; | |
725 decoder->setData(m_image->data(), true); | |
726 if (!decoder->frameCount()) | |
727 return false; | |
728 ImageFrame* frame = decoder->frameBufferAtIndex(0); | |
729 if (!frame || frame->status() != ImageFrame::FrameComplete) | |
730 return false; | |
731 hasAlpha = frame->hasAlpha(); | |
732 m_nativeImage = frame->asNewNativeImage(); | |
733 if (!m_nativeImage.get() || !m_nativeImage->isDataComplete() || !m_nativ
eImage->bitmap().width() || !m_nativeImage->bitmap().height()) | |
734 return false; | |
735 SkBitmap::Config skiaConfig = m_nativeImage->bitmap().config(); | |
736 if (skiaConfig != SkBitmap::kARGB_8888_Config) | |
737 return false; | |
738 m_skiaImage = m_nativeImage.get(); | |
739 if (hasAlpha && premultiplyAlpha) | |
740 m_alphaOp = AlphaDoPremultiply; | |
741 } else if (!premultiplyAlpha && hasAlpha) { | |
742 // 1. For texImage2D with HTMLVideoElment input, assume no PremultiplyAl
pha had been applied and the alpha value for each pixel is 0xFF | |
743 // which is true at present and may be changed in the future and needs a
djustment accordingly. | |
744 // 2. For texImage2D with HTMLCanvasElement input in which Alpha is alre
ady Premultiplied in this port, | |
745 // do AlphaDoUnmultiply if UNPACK_PREMULTIPLY_ALPHA_WEBGL is set to fals
e. | |
746 if (m_imageHtmlDomSource != HtmlDomVideo) | |
747 m_alphaOp = AlphaDoUnmultiply; | |
748 } | |
749 if (!m_skiaImage) | |
750 return false; | |
751 | |
752 m_imageSourceFormat = SK_B32_SHIFT ? DataFormatRGBA8 : DataFormatBGRA8; | |
753 m_imageWidth = m_skiaImage->bitmap().width(); | |
754 m_imageHeight = m_skiaImage->bitmap().height(); | |
755 if (!m_imageWidth || !m_imageHeight) | |
756 return false; | |
757 m_imageSourceUnpackAlignment = 0; | |
758 m_skiaImage->bitmap().lockPixels(); | |
759 m_imagePixelData = m_skiaImage->bitmap().getPixels(); | |
760 return true; | |
761 } | |
762 | |
763 unsigned GraphicsContext3D::getClearBitsByFormat(GC3Denum format) | |
764 { | |
765 switch (format) { | |
766 case GraphicsContext3D::ALPHA: | |
767 case GraphicsContext3D::LUMINANCE: | |
768 case GraphicsContext3D::LUMINANCE_ALPHA: | |
769 case GraphicsContext3D::RGB: | |
770 case GraphicsContext3D::RGB565: | |
771 case GraphicsContext3D::RGBA: | |
772 case GraphicsContext3D::RGBA4: | |
773 case GraphicsContext3D::RGB5_A1: | |
774 return GraphicsContext3D::COLOR_BUFFER_BIT; | |
775 case GraphicsContext3D::DEPTH_COMPONENT16: | |
776 case GraphicsContext3D::DEPTH_COMPONENT: | |
777 return GraphicsContext3D::DEPTH_BUFFER_BIT; | |
778 case GraphicsContext3D::STENCIL_INDEX8: | |
779 return GraphicsContext3D::STENCIL_BUFFER_BIT; | |
780 case GraphicsContext3D::DEPTH_STENCIL: | |
781 return GraphicsContext3D::DEPTH_BUFFER_BIT | GraphicsContext3D::STENCIL_
BUFFER_BIT; | |
782 default: | |
783 return 0; | |
784 } | |
785 } | |
786 | |
787 unsigned GraphicsContext3D::getChannelBitsByFormat(GC3Denum format) | |
788 { | |
789 switch (format) { | |
790 case GraphicsContext3D::ALPHA: | |
791 return ChannelAlpha; | |
792 case GraphicsContext3D::LUMINANCE: | |
793 return ChannelRGB; | |
794 case GraphicsContext3D::LUMINANCE_ALPHA: | |
795 return ChannelRGBA; | |
796 case GraphicsContext3D::RGB: | |
797 case GraphicsContext3D::RGB565: | |
798 return ChannelRGB; | |
799 case GraphicsContext3D::RGBA: | |
800 case GraphicsContext3D::RGBA4: | |
801 case GraphicsContext3D::RGB5_A1: | |
802 return ChannelRGBA; | |
803 case GraphicsContext3D::DEPTH_COMPONENT16: | |
804 case GraphicsContext3D::DEPTH_COMPONENT: | |
805 return ChannelDepth; | |
806 case GraphicsContext3D::STENCIL_INDEX8: | |
807 return ChannelStencil; | |
808 case GraphicsContext3D::DEPTH_STENCIL: | |
809 return ChannelDepth | ChannelStencil; | |
810 default: | |
811 return 0; | |
812 } | |
813 } | |
814 | |
815 void GraphicsContext3D::paintFramebufferToCanvas(int framebuffer, int width, int
height, bool premultiplyAlpha, ImageBuffer* imageBuffer) | |
816 { | |
817 unsigned char* pixels = 0; | |
818 | |
819 const SkBitmap* canvasBitmap = imageBuffer->context()->bitmap(); | |
820 const SkBitmap* readbackBitmap = 0; | |
821 ASSERT(canvasBitmap->config() == SkBitmap::kARGB_8888_Config); | |
822 if (canvasBitmap->width() == width && canvasBitmap->height() == height) { | |
823 // This is the fastest and most common case. We read back | |
824 // directly into the canvas's backing store. | |
825 readbackBitmap = canvasBitmap; | |
826 m_resizingBitmap.reset(); | |
827 } else { | |
828 // We need to allocate a temporary bitmap for reading back the | |
829 // pixel data. We will then use Skia to rescale this bitmap to | |
830 // the size of the canvas's backing store. | |
831 if (m_resizingBitmap.width() != width || m_resizingBitmap.height() != he
ight) { | |
832 m_resizingBitmap.setConfig(SkBitmap::kARGB_8888_Config, width, heigh
t); | |
833 if (!m_resizingBitmap.allocPixels()) | |
834 return; | |
835 } | |
836 readbackBitmap = &m_resizingBitmap; | |
837 } | |
838 | |
839 // Read back the frame buffer. | |
840 SkAutoLockPixels bitmapLock(*readbackBitmap); | |
841 pixels = static_cast<unsigned char*>(readbackBitmap->getPixels()); | |
842 | |
843 m_impl->bindFramebuffer(FRAMEBUFFER, framebuffer); | |
844 readBackFramebuffer(pixels, width, height, ReadbackSkia, premultiplyAlpha ?
AlphaDoPremultiply : AlphaDoNothing); | |
845 flipVertically(pixels, width, height); | |
846 | |
847 readbackBitmap->notifyPixelsChanged(); | |
848 if (m_resizingBitmap.readyToDraw()) { | |
849 // We need to draw the resizing bitmap into the canvas's backing store. | |
850 SkCanvas canvas(*canvasBitmap); | |
851 SkRect dst; | |
852 dst.set(SkIntToScalar(0), SkIntToScalar(0), SkIntToScalar(canvasBitmap->
width()), SkIntToScalar(canvasBitmap->height())); | |
853 canvas.drawBitmapRect(m_resizingBitmap, 0, dst); | |
854 } | |
855 } | |
856 | |
857 namespace { | |
858 | |
859 void splitStringHelper(const String& str, HashSet<String>& set) | |
860 { | |
861 Vector<String> substrings; | |
862 str.split(" ", substrings); | |
863 for (size_t i = 0; i < substrings.size(); ++i) | |
864 set.add(substrings[i]); | |
865 } | |
866 | |
867 String mapExtensionName(const String& name) | |
868 { | |
869 if (name == "GL_ANGLE_framebuffer_blit" | |
870 || name == "GL_ANGLE_framebuffer_multisample") | |
871 return "GL_CHROMIUM_framebuffer_multisample"; | |
872 return name; | |
873 } | |
874 | |
875 } // anonymous namespace | |
876 | |
877 void GraphicsContext3D::initializeExtensions() | |
878 { | |
879 if (m_initializedAvailableExtensions) | |
880 return; | |
881 | |
882 m_initializedAvailableExtensions = true; | |
883 bool success = m_impl->makeContextCurrent(); | |
884 ASSERT(success); | |
885 if (!success) | |
886 return; | |
887 | |
888 String extensionsString = m_impl->getString(GraphicsContext3D::EXTENSIONS); | |
889 splitStringHelper(extensionsString, m_enabledExtensions); | |
890 | |
891 String requestableExtensionsString = m_impl->getRequestableExtensionsCHROMIU
M(); | |
892 splitStringHelper(requestableExtensionsString, m_requestableExtensions); | |
893 } | |
894 | |
895 | |
896 bool GraphicsContext3D::supportsExtension(const String& name) | |
897 { | |
898 initializeExtensions(); | |
899 String mappedName = mapExtensionName(name); | |
900 return m_enabledExtensions.contains(mappedName) || m_requestableExtensions.c
ontains(mappedName); | |
901 } | |
902 | |
903 bool GraphicsContext3D::ensureExtensionEnabled(const String& name) | |
904 { | |
905 initializeExtensions(); | |
906 | |
907 String mappedName = mapExtensionName(name); | |
908 if (m_enabledExtensions.contains(mappedName)) | |
909 return true; | |
910 | |
911 if (m_requestableExtensions.contains(mappedName)) { | |
912 m_impl->requestExtensionCHROMIUM(mappedName.ascii().data()); | |
913 m_enabledExtensions.clear(); | |
914 m_requestableExtensions.clear(); | |
915 m_initializedAvailableExtensions = false; | |
916 } | |
917 | |
918 initializeExtensions(); | |
919 fprintf(stderr, "m_enabledExtensions.contains(%s) == %d\n", mappedName.ascii
().data(), m_enabledExtensions.contains(mappedName)); | |
920 return m_enabledExtensions.contains(mappedName); | |
921 } | |
922 | |
923 bool GraphicsContext3D::isExtensionEnabled(const String& name) | |
924 { | |
925 initializeExtensions(); | |
926 String mappedName = mapExtensionName(name); | |
927 return m_enabledExtensions.contains(mappedName); | |
928 } | |
929 | |
930 void GraphicsContext3D::flipVertically(uint8_t* framebuffer, int width, int heig
ht) | |
931 { | |
932 m_scanline.resize(width * 4); | |
933 uint8* scanline = &m_scanline[0]; | |
934 unsigned rowBytes = width * 4; | |
935 unsigned count = height / 2; | |
936 for (unsigned i = 0; i < count; i++) { | |
937 uint8* rowA = framebuffer + i * rowBytes; | |
938 uint8* rowB = framebuffer + (height - i - 1) * rowBytes; | |
939 memcpy(scanline, rowB, rowBytes); | |
940 memcpy(rowB, rowA, rowBytes); | |
941 memcpy(rowA, scanline, rowBytes); | |
942 } | |
943 } | |
944 | |
945 } // namespace WebCore | |
OLD | NEW |