[WTF] Add makeUnique<T>, which ensures T is fast-allocated, makeUnique / makeUniqueWi...
[WebKit-https.git] / Source / WebCore / platform / graphics / opengl / GraphicsContext3DOpenGL.cpp
1 /*
2  * Copyright (C) 2010, 2013 Apple Inc. All rights reserved.
3  * Copyright (C) 2011 Google Inc. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
25  */
26
27 #include "config.h"
28
29 #if ENABLE(GRAPHICS_CONTEXT_3D) && (USE(OPENGL) || (PLATFORM(COCOA) && USE(OPENGL_ES)))
30
31 #include "GraphicsContext3D.h"
32
33 #if PLATFORM(IOS_FAMILY)
34 #include "GraphicsContext3DIOS.h"
35 #endif
36 #include "Extensions3DOpenGL.h"
37 #include "IntRect.h"
38 #include "IntSize.h"
39 #include "NotImplemented.h"
40 #include "TemporaryOpenGLSetting.h"
41 #include <algorithm>
42 #include <cstring>
43 #include <wtf/MainThread.h>
44 #include <wtf/text/CString.h>
45
46 #if USE(ACCELERATE)
47 #include <Accelerate/Accelerate.h>
48 #endif
49
50 #if PLATFORM(GTK) || PLATFORM(WIN)
51 #include "OpenGLShims.h"
52 #elif USE(OPENGL_ES)
53 #import <OpenGLES/ES2/glext.h>
54 // From <OpenGLES/glext.h>
55 #define GL_RGBA32F_ARB                      0x8814
56 #define GL_RGB32F_ARB                       0x8815
57 #elif USE(OPENGL)
58 #define GL_DO_NOT_WARN_IF_MULTI_GL_VERSION_HEADERS_INCLUDED
59 #include <OpenGL/gl.h>
60 #include <OpenGL/gl3.h>
61 #undef GL_DO_NOT_WARN_IF_MULTI_GL_VERSION_HEADERS_INCLUDED
62 #endif
63
64 namespace WebCore {
65
66 void GraphicsContext3D::releaseShaderCompiler()
67 {
68     makeContextCurrent();
69     notImplemented();
70 }
71
72 #if PLATFORM(MAC)
73 static void wipeAlphaChannelFromPixels(int width, int height, unsigned char* pixels)
74 {
75     // We can assume this doesn't overflow because the calling functions
76     // use checked arithmetic.
77     int totalBytes = width * height * 4;
78     for (int i = 0; i < totalBytes; i += 4)
79         pixels[i + 3] = 255;
80 }
81 #endif
82
83 void GraphicsContext3D::readPixelsAndConvertToBGRAIfNecessary(int x, int y, int width, int height, unsigned char* pixels)
84 {
85     // NVIDIA drivers have a bug where calling readPixels in BGRA can return the wrong values for the alpha channel when the alpha is off for the context.
86     if (!m_attrs.alpha && getExtensions().isNVIDIA()) {
87         ::glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
88 #if USE(ACCELERATE)
89         vImage_Buffer src;
90         src.height = height;
91         src.width = width;
92         src.rowBytes = width * 4;
93         src.data = pixels;
94
95         vImage_Buffer dest;
96         dest.height = height;
97         dest.width = width;
98         dest.rowBytes = width * 4;
99         dest.data = pixels;
100
101         // Swap pixel channels from RGBA to BGRA.
102         const uint8_t map[4] = { 2, 1, 0, 3 };
103         vImagePermuteChannels_ARGB8888(&src, &dest, map, kvImageNoFlags);
104 #else
105         int totalBytes = width * height * 4;
106         for (int i = 0; i < totalBytes; i += 4)
107             std::swap(pixels[i], pixels[i + 2]);
108 #endif
109     } else
110         ::glReadPixels(x, y, width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pixels);
111
112 #if PLATFORM(MAC)
113     if (!m_attrs.alpha)
114         wipeAlphaChannelFromPixels(width, height, pixels);
115 #endif
116 }
117
118 void GraphicsContext3D::validateAttributes()
119 {
120     validateDepthStencil("GL_EXT_packed_depth_stencil");
121 }
122
123 bool GraphicsContext3D::reshapeFBOs(const IntSize& size)
124 {
125     const int width = size.width();
126     const int height = size.height();
127     GLuint colorFormat, internalDepthStencilFormat = 0;
128     if (m_attrs.alpha) {
129         m_internalColorFormat = GL_RGBA8;
130         colorFormat = GL_RGBA;
131     } else {
132         m_internalColorFormat = GL_RGB8;
133         colorFormat = GL_RGB;
134     }
135     if (m_attrs.stencil || m_attrs.depth) {
136         // We don't allow the logic where stencil is required and depth is not.
137         // See GraphicsContext3D::validateAttributes.
138
139         Extensions3D& extensions = getExtensions();
140         // Use a 24 bit depth buffer where we know we have it.
141         if (extensions.supports("GL_EXT_packed_depth_stencil"))
142             internalDepthStencilFormat = GL_DEPTH24_STENCIL8_EXT;
143         else
144 #if PLATFORM(COCOA) && USE(OPENGL_ES)
145             internalDepthStencilFormat = GL_DEPTH_COMPONENT16;
146 #else
147             internalDepthStencilFormat = GL_DEPTH_COMPONENT;
148 #endif
149     }
150
151     // Resize multisample FBO.
152     if (m_attrs.antialias) {
153         GLint maxSampleCount;
154         ::glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSampleCount);
155         // Using more than 4 samples is slow on some hardware and is unlikely to
156         // produce a significantly better result.
157         GLint sampleCount = std::min(4, maxSampleCount);
158         ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
159         ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleColorBuffer);
160 #if PLATFORM(COCOA) && USE(OPENGL_ES)
161         ::glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, GL_RGBA8_OES, width, height);
162 #else
163         ::glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, m_internalColorFormat, width, height);
164 #endif
165         ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_multisampleColorBuffer);
166         if (m_attrs.stencil || m_attrs.depth) {
167             ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer);
168             ::glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalDepthStencilFormat, width, height);
169             if (m_attrs.stencil)
170                 ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer);
171             if (m_attrs.depth)
172                 ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer);
173         }
174         ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
175         if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) {
176             // FIXME: cleanup.
177             notImplemented();
178         }
179     }
180
181     // resize regular FBO
182     ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
183     ASSERT(m_texture);
184 #if PLATFORM(COCOA)
185 #if USE(OPENGL_ES)
186     ::glBindRenderbuffer(GL_RENDERBUFFER, m_texture);
187     ::glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_texture);
188     setRenderbufferStorageFromDrawable(m_currentWidth, m_currentHeight);
189 #else
190     allocateIOSurfaceBackingStore(IntSize(width, height));
191     updateFramebufferTextureBackingStoreFromLayer();
192     ::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, m_texture, 0);
193 #endif // !USE(OPENGL_ES))
194 #else
195     ::glBindTexture(GL_TEXTURE_2D, m_texture);
196     ::glTexImage2D(GL_TEXTURE_2D, 0, m_internalColorFormat, width, height, 0, colorFormat, GL_UNSIGNED_BYTE, 0);
197     ::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0);
198
199 #if USE(COORDINATED_GRAPHICS)
200     if (m_compositorTexture) {
201         ::glBindTexture(GL_TEXTURE_2D, m_compositorTexture);
202         ::glTexImage2D(GL_TEXTURE_2D, 0, m_internalColorFormat, width, height, 0, colorFormat, GL_UNSIGNED_BYTE, 0);
203         ::glBindTexture(GL_TEXTURE_2D, 0);
204         ::glBindTexture(GL_TEXTURE_2D, m_intermediateTexture);
205         ::glTexImage2D(GL_TEXTURE_2D, 0, m_internalColorFormat, width, height, 0, colorFormat, GL_UNSIGNED_BYTE, 0);
206         ::glBindTexture(GL_TEXTURE_2D, 0);
207     }
208 #endif
209 #endif
210
211     attachDepthAndStencilBufferIfNeeded(internalDepthStencilFormat, width, height);
212
213     bool mustRestoreFBO = true;
214     if (m_attrs.antialias) {
215         ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
216         if (m_state.boundFBO == m_multisampleFBO)
217             mustRestoreFBO = false;
218     } else {
219         if (m_state.boundFBO == m_fbo)
220             mustRestoreFBO = false;
221     }
222
223     return mustRestoreFBO;
224 }
225
226 void GraphicsContext3D::attachDepthAndStencilBufferIfNeeded(GLuint internalDepthStencilFormat, int width, int height)
227 {
228     if (!m_attrs.antialias && (m_attrs.stencil || m_attrs.depth)) {
229         ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthStencilBuffer);
230         ::glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internalDepthStencilFormat, width, height);
231         if (m_attrs.stencil)
232             ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer);
233         if (m_attrs.depth)
234             ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer);
235         ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
236     }
237
238     if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) {
239         // FIXME: cleanup
240         notImplemented();
241     }
242 }
243
244 void GraphicsContext3D::resolveMultisamplingIfNecessary(const IntRect& rect)
245 {
246     TemporaryOpenGLSetting scopedScissor(GL_SCISSOR_TEST, GL_FALSE);
247     TemporaryOpenGLSetting scopedDither(GL_DITHER, GL_FALSE);
248     TemporaryOpenGLSetting scopedDepth(GL_DEPTH_TEST, GL_FALSE);
249     TemporaryOpenGLSetting scopedStencil(GL_STENCIL_TEST, GL_FALSE);
250
251 #if PLATFORM(COCOA) && USE(OPENGL_ES)
252     GLint boundFrameBuffer;
253     ::glGetIntegerv(GL_FRAMEBUFFER_BINDING, &boundFrameBuffer);
254 #endif
255
256     ::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO);
257     ::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo);
258 #if PLATFORM(COCOA) && USE(OPENGL_ES)
259     UNUSED_PARAM(rect);
260     ::glFlush();
261     ::glResolveMultisampleFramebufferAPPLE();
262     const GLenum discards[] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT };
263     ::glDiscardFramebufferEXT(GL_READ_FRAMEBUFFER_APPLE, 2, discards);
264     ::glBindFramebuffer(GL_FRAMEBUFFER, boundFrameBuffer);
265 #else
266     IntRect resolveRect = rect;
267     if (rect.isEmpty())
268         resolveRect = IntRect(0, 0, m_currentWidth, m_currentHeight);
269
270     ::glBlitFramebufferEXT(resolveRect.x(), resolveRect.y(), resolveRect.maxX(), resolveRect.maxY(), resolveRect.x(), resolveRect.y(), resolveRect.maxX(), resolveRect.maxY(), GL_COLOR_BUFFER_BIT, GL_LINEAR);
271 #endif
272 }
273
274 void GraphicsContext3D::renderbufferStorage(GC3Denum target, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height)
275 {
276     makeContextCurrent();
277 #if USE(OPENGL)
278     switch (internalformat) {
279     case DEPTH_STENCIL:
280         internalformat = GL_DEPTH24_STENCIL8_EXT;
281         break;
282     case DEPTH_COMPONENT16:
283         internalformat = GL_DEPTH_COMPONENT;
284         break;
285     case RGBA4:
286     case RGB5_A1:
287         internalformat = GL_RGBA;
288         break;
289     case RGB565:
290         internalformat = GL_RGB;
291         break;
292     }
293 #endif
294     ::glRenderbufferStorageEXT(target, internalformat, width, height);
295 }
296
297 void GraphicsContext3D::getIntegerv(GC3Denum pname, GC3Dint* value)
298 {
299     // Need to emulate MAX_FRAGMENT/VERTEX_UNIFORM_VECTORS and MAX_VARYING_VECTORS
300     // because desktop GL's corresponding queries return the number of components
301     // whereas GLES2 return the number of vectors (each vector has 4 components).
302     // Therefore, the value returned by desktop GL needs to be divided by 4.
303     makeContextCurrent();
304     switch (pname) {
305 #if USE(OPENGL)
306     case MAX_FRAGMENT_UNIFORM_VECTORS:
307         ::glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, value);
308         *value /= 4;
309         break;
310     case MAX_VERTEX_UNIFORM_VECTORS:
311         ::glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, value);
312         *value /= 4;
313         break;
314     case MAX_VARYING_VECTORS:
315         if (isGLES2Compliant()) {
316             ASSERT(::glGetError() == GL_NO_ERROR);
317             ::glGetIntegerv(GL_MAX_VARYING_VECTORS, value);
318             if (::glGetError() == GL_INVALID_ENUM) {
319                 ::glGetIntegerv(GL_MAX_VARYING_COMPONENTS, value);
320                 *value /= 4;
321             }
322         } else {
323             ::glGetIntegerv(GL_MAX_VARYING_FLOATS, value);
324             *value /= 4;
325         }
326         break;
327 #endif
328     case MAX_TEXTURE_SIZE:
329         ::glGetIntegerv(MAX_TEXTURE_SIZE, value);
330         if (getExtensions().requiresRestrictedMaximumTextureSize())
331             *value = std::min(4096, *value);
332         break;
333     case MAX_CUBE_MAP_TEXTURE_SIZE:
334         ::glGetIntegerv(MAX_CUBE_MAP_TEXTURE_SIZE, value);
335         if (getExtensions().requiresRestrictedMaximumTextureSize())
336             *value = std::min(1024, *value);
337         break;
338 #if PLATFORM(MAC)
339     // Some older hardware advertises a larger maximum than they
340     // can actually handle. Rather than detecting such devices, simply
341     // clamp the maximum to 8192, which is big enough for a 5K display.
342     case MAX_RENDERBUFFER_SIZE:
343         ::glGetIntegerv(MAX_RENDERBUFFER_SIZE, value);
344         *value = std::min(8192, *value);
345         break;
346     case MAX_VIEWPORT_DIMS:
347         ::glGetIntegerv(MAX_VIEWPORT_DIMS, value);
348         value[0] = std::min(8192, value[0]);
349         value[1] = std::min(8192, value[1]);
350         break;
351 #endif
352     default:
353         ::glGetIntegerv(pname, value);
354     }
355 }
356
357 void GraphicsContext3D::getShaderPrecisionFormat(GC3Denum shaderType, GC3Denum precisionType, GC3Dint* range, GC3Dint* precision)
358 {
359     UNUSED_PARAM(shaderType);
360     ASSERT(range);
361     ASSERT(precision);
362
363     makeContextCurrent();
364
365     switch (precisionType) {
366     case GraphicsContext3D::LOW_INT:
367     case GraphicsContext3D::MEDIUM_INT:
368     case GraphicsContext3D::HIGH_INT:
369         // These values are for a 32-bit twos-complement integer format.
370         range[0] = 31;
371         range[1] = 30;
372         precision[0] = 0;
373         break;
374     case GraphicsContext3D::LOW_FLOAT:
375     case GraphicsContext3D::MEDIUM_FLOAT:
376     case GraphicsContext3D::HIGH_FLOAT:
377         // These values are for an IEEE single-precision floating-point format.
378         range[0] = 127;
379         range[1] = 127;
380         precision[0] = 23;
381         break;
382     default:
383         ASSERT_NOT_REACHED();
384         break;
385     }
386 }
387
388 bool GraphicsContext3D::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels)
389 {
390     if (width && height && !pixels) {
391         synthesizeGLError(INVALID_VALUE);
392         return false;
393     }
394
395     GC3Denum openGLFormat = format;
396     GC3Denum openGLInternalFormat = internalformat;
397 #if USE(OPENGL)
398     if (type == GL_FLOAT) {
399         if (format == GL_RGBA)
400             openGLInternalFormat = GL_RGBA32F_ARB;
401         else if (format == GL_RGB)
402             openGLInternalFormat = GL_RGB32F_ARB;
403     } else if (type == HALF_FLOAT_OES) {
404         if (format == GL_RGBA)
405             openGLInternalFormat = GL_RGBA16F_ARB;
406         else if (format == GL_RGB)
407             openGLInternalFormat = GL_RGB16F_ARB;
408         else if (format == GL_LUMINANCE)
409             openGLInternalFormat = GL_LUMINANCE16F_ARB;
410         else if (format == GL_ALPHA)
411             openGLInternalFormat = GL_ALPHA16F_ARB;
412         else if (format == GL_LUMINANCE_ALPHA)
413             openGLInternalFormat = GL_LUMINANCE_ALPHA16F_ARB;
414         type = GL_HALF_FLOAT_ARB;
415     }
416
417     ASSERT(format != Extensions3D::SRGB8_ALPHA8_EXT);
418     if (format == Extensions3D::SRGB_ALPHA_EXT)
419         openGLFormat = GL_RGBA;
420     else if (format == Extensions3D::SRGB_EXT)
421         openGLFormat = GL_RGB;
422 #endif
423
424     if (m_usingCoreProfile) {
425         // There are some format values used in WebGL that are deprecated when using a core profile, so we need
426         // to adapt them.
427         switch (openGLInternalFormat) {
428         case ALPHA:
429             // The format is a simple component containing an alpha value. It needs to be backed with a GL_RED plane.
430             // We change the formats to GL_RED (both need to be GL_ALPHA in WebGL) and instruct the texture to swizzle
431             // the red component values with the alpha component values.
432             openGLInternalFormat = openGLFormat = RED;
433             texParameteri(target, TEXTURE_SWIZZLE_A, RED);
434             break;
435         case LUMINANCE_ALPHA:
436             // The format has 2 components, an alpha one and a luminance one (same value for red, green and blue).
437             // It needs to be backed with a GL_RG plane, using the red component for the colors and the green component
438             // for alpha. We change the formats to GL_RG and swizzle the components.
439             openGLInternalFormat = openGLFormat = RG;
440             texParameteri(target, TEXTURE_SWIZZLE_R, RED);
441             texParameteri(target, TEXTURE_SWIZZLE_G, RED);
442             texParameteri(target, TEXTURE_SWIZZLE_B, RED);
443             texParameteri(target, TEXTURE_SWIZZLE_A, GREEN);
444             break;
445         default:
446             break;
447         }
448     }
449
450     texImage2DDirect(target, level, openGLInternalFormat, width, height, border, openGLFormat, type, pixels);
451     return true;
452 }
453
454 void GraphicsContext3D::depthRange(GC3Dclampf zNear, GC3Dclampf zFar)
455 {
456     makeContextCurrent();
457 #if PLATFORM(COCOA) && USE(OPENGL_ES)
458     ::glDepthRangef(static_cast<float>(zNear), static_cast<float>(zFar));
459 #else
460     ::glDepthRange(zNear, zFar);
461 #endif
462 }
463
464 void GraphicsContext3D::clearDepth(GC3Dclampf depth)
465 {
466     makeContextCurrent();
467 #if PLATFORM(COCOA) && USE(OPENGL_ES)
468     ::glClearDepthf(static_cast<float>(depth));
469 #else
470     ::glClearDepth(depth);
471 #endif
472 }
473
474 #if !PLATFORM(GTK)
475 Extensions3D& GraphicsContext3D::getExtensions()
476 {
477     if (!m_extensions)
478         m_extensions = makeUnique<Extensions3DOpenGL>(this, isGLES2Compliant());
479     return *m_extensions;
480 }
481 #endif
482
483 void GraphicsContext3D::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, void* data)
484 {
485     // FIXME: remove the two glFlush calls when the driver bug is fixed, i.e.,
486     // all previous rendering calls should be done before reading pixels.
487     makeContextCurrent();
488     ::glFlush();
489     if (m_attrs.antialias && m_state.boundFBO == m_multisampleFBO) {
490         resolveMultisamplingIfNecessary(IntRect(x, y, width, height));
491         ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_fbo);
492         ::glFlush();
493     }
494     ::glReadPixels(x, y, width, height, format, type, data);
495     if (m_attrs.antialias && m_state.boundFBO == m_multisampleFBO)
496         ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO);
497
498 #if PLATFORM(MAC)
499     if (!m_attrs.alpha && (format == GraphicsContext3D::RGBA || format == GraphicsContext3D::BGRA) && (m_state.boundFBO == m_fbo || (m_attrs.antialias && m_state.boundFBO == m_multisampleFBO)))
500         wipeAlphaChannelFromPixels(width, height, static_cast<unsigned char*>(data));
501 #endif
502 }
503
504 }
505
506 #endif // ENABLE(GRAPHICS_CONTEXT_3D) && (USE(OPENGL) || (PLATFORM(COCOA) && USE(OPENGL_ES)))