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