2 * Copyright (C) 2010 Apple Inc. All rights reserved.
3 * Copyright (C) 2011 Google Inc. All rights reserved.
4 * Copyright (C) 2012 ChangSeok Oh <shivamidow@gmail.com>
5 * Copyright (C) 2012 Research In Motion Limited. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
24 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 #include "GraphicsContext3D.h"
36 #include "Extensions3DOpenGLES.h"
38 #include "Extensions3DOpenGL.h"
40 #include "GraphicsContext.h"
41 #include "ImageBuffer.h"
42 #include "ImageData.h"
46 #include "NotImplemented.h"
48 #include <runtime/ArrayBuffer.h>
49 #include <runtime/ArrayBufferView.h>
50 #include <runtime/Float32Array.h>
51 #include <runtime/Int32Array.h>
52 #include <runtime/Uint8Array.h>
53 #include <wtf/MainThread.h>
54 #include <wtf/text/CString.h>
57 #include "OpenGLESShims.h"
59 #include <OpenGL/gl.h>
60 #elif PLATFORM(GTK) || PLATFORM(EFL) || PLATFORM(WIN) || PLATFORM(NIX)
61 #include "OpenGLShims.h"
64 #if PLATFORM(BLACKBERRY)
65 #include <BlackBerryPlatformLog.h>
70 static ShaderNameHash* currentNameHashMapForShader;
72 // Hash function used by the ANGLE translator/compiler to do
73 // symbol name mangling. Since this is a static method, before
74 // calling compileShader we set currentNameHashMapForShader
75 // to point to the map kept by the current instance of GraphicsContext3D.
77 static uint64_t nameHashForShader(const char* name, size_t length)
82 CString nameAsCString = CString(name);
84 // Look up name in our local map.
85 if (currentNameHashMapForShader) {
86 ShaderNameHash::iterator result = currentNameHashMapForShader->find(nameAsCString);
87 if (result != currentNameHashMapForShader->end())
91 unsigned hashValue = nameAsCString.hash();
93 // Convert the 32-bit hash from CString::hash into a 64-bit result
94 // by shifting then adding the size of our table. Overflow would
95 // only be a problem if we're already hashing to the same value (and
96 // we're hoping that over the lifetime of the context we
97 // don't have that many symbols).
99 uint64_t result = hashValue;
100 result = (result << 32) + (currentNameHashMapForShader->size() + 1);
102 currentNameHashMapForShader->set(nameAsCString, result);
106 PassRefPtr<GraphicsContext3D> GraphicsContext3D::createForCurrentGLContext()
108 RefPtr<GraphicsContext3D> context = adoptRef(new GraphicsContext3D(Attributes(), 0, GraphicsContext3D::RenderToCurrentGLContext));
109 return context->m_private ? context.release() : 0;
112 void GraphicsContext3D::validateDepthStencil(const char* packedDepthStencilExtension)
114 Extensions3D* extensions = getExtensions();
115 if (m_attrs.stencil) {
116 if (extensions->supports(packedDepthStencilExtension)) {
117 extensions->ensureEnabled(packedDepthStencilExtension);
118 // Force depth if stencil is true.
119 m_attrs.depth = true;
121 m_attrs.stencil = false;
123 if (m_attrs.antialias) {
124 if (!extensions->maySupportMultisampling() || !extensions->supports("GL_ANGLE_framebuffer_multisample") || isGLES2Compliant())
125 m_attrs.antialias = false;
127 extensions->ensureEnabled("GL_ANGLE_framebuffer_multisample");
131 bool GraphicsContext3D::isResourceSafe()
136 void GraphicsContext3D::paintRenderingResultsToCanvas(ImageBuffer* imageBuffer, DrawingBuffer*)
138 int rowBytes = m_currentWidth * 4;
139 int totalBytes = rowBytes * m_currentHeight;
141 auto pixels = std::make_unique<unsigned char[]>(totalBytes);
145 readRenderingResults(pixels.get(), totalBytes);
147 if (!m_attrs.premultipliedAlpha) {
148 for (int i = 0; i < totalBytes; i += 4) {
149 // Premultiply alpha.
150 pixels[i + 0] = std::min(255, pixels[i + 0] * pixels[i + 3] / 255);
151 pixels[i + 1] = std::min(255, pixels[i + 1] * pixels[i + 3] / 255);
152 pixels[i + 2] = std::min(255, pixels[i + 2] * pixels[i + 3] / 255);
156 #if PLATFORM(BLACKBERRY) || USE(CG)
157 paintToCanvas(pixels.get(), m_currentWidth, m_currentHeight,
158 imageBuffer->internalSize().width(), imageBuffer->internalSize().height(), imageBuffer->context());
160 paintToCanvas(pixels.get(), m_currentWidth, m_currentHeight,
161 imageBuffer->internalSize().width(), imageBuffer->internalSize().height(), imageBuffer->context()->platformContext());
165 bool GraphicsContext3D::paintCompositedResultsToCanvas(ImageBuffer*)
167 // Not needed at the moment, so return that nothing was done.
171 PassRefPtr<ImageData> GraphicsContext3D::paintRenderingResultsToImageData(DrawingBuffer*)
173 // Reading premultiplied alpha would involve unpremultiplying, which is
175 if (m_attrs.premultipliedAlpha)
178 RefPtr<ImageData> imageData = ImageData::create(IntSize(m_currentWidth, m_currentHeight));
179 unsigned char* pixels = imageData->data()->data();
180 int totalBytes = 4 * m_currentWidth * m_currentHeight;
182 readRenderingResults(pixels, totalBytes);
185 for (int i = 0; i < totalBytes; i += 4)
186 std::swap(pixels[i], pixels[i + 2]);
188 return imageData.release();
191 #if !PLATFORM(BLACKBERRY)
192 void GraphicsContext3D::prepareTexture()
194 if (m_layerComposited)
197 makeContextCurrent();
198 if (m_attrs.antialias)
199 resolveMultisamplingIfNecessary();
201 ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_fbo);
202 ::glActiveTexture(GL_TEXTURE0);
203 ::glBindTexture(GL_TEXTURE_2D, m_compositorTexture);
204 ::glCopyTexImage2D(GL_TEXTURE_2D, 0, m_internalColorFormat, 0, 0, m_currentWidth, m_currentHeight, 0);
205 ::glBindTexture(GL_TEXTURE_2D, m_state.boundTexture0);
206 ::glActiveTexture(m_state.activeTexture);
207 if (m_state.boundFBO != m_fbo)
208 ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_state.boundFBO);
210 m_layerComposited = true;
214 void GraphicsContext3D::readRenderingResults(unsigned char *pixels, int pixelsSize)
216 if (pixelsSize < m_currentWidth * m_currentHeight * 4)
219 makeContextCurrent();
221 bool mustRestoreFBO = false;
222 if (m_attrs.antialias) {
223 resolveMultisamplingIfNecessary();
224 ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_fbo);
225 mustRestoreFBO = true;
227 if (m_state.boundFBO != m_fbo) {
228 mustRestoreFBO = true;
229 ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_fbo);
233 GLint packAlignment = 4;
234 bool mustRestorePackAlignment = false;
235 ::glGetIntegerv(GL_PACK_ALIGNMENT, &packAlignment);
236 if (packAlignment > 4) {
237 ::glPixelStorei(GL_PACK_ALIGNMENT, 4);
238 mustRestorePackAlignment = true;
241 readPixelsAndConvertToBGRAIfNecessary(0, 0, m_currentWidth, m_currentHeight, pixels);
243 if (mustRestorePackAlignment)
244 ::glPixelStorei(GL_PACK_ALIGNMENT, packAlignment);
247 ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_state.boundFBO);
250 void GraphicsContext3D::reshape(int width, int height)
252 if (!platformGraphicsContext3D())
255 if (width == m_currentWidth && height == m_currentHeight)
258 #if (PLATFORM(EFL) || PLATFORM(NIX)) && USE(GRAPHICS_SURFACE)
259 ::glFlush(); // Make sure all GL calls have been committed before resizing.
260 createGraphicsSurfaces(IntSize(width, height));
263 m_currentWidth = width;
264 m_currentHeight = height;
266 makeContextCurrent();
267 validateAttributes();
269 bool mustRestoreFBO = reshapeFBOs(IntSize(width, height));
271 // Initialize renderbuffers to 0.
272 GLfloat clearColor[] = {0, 0, 0, 0}, clearDepth = 0;
273 GLint clearStencil = 0;
274 GLboolean colorMask[] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE}, depthMask = GL_TRUE;
275 GLuint stencilMask = 0xffffffff;
276 GLboolean isScissorEnabled = GL_FALSE;
277 GLboolean isDitherEnabled = GL_FALSE;
278 GLbitfield clearMask = GL_COLOR_BUFFER_BIT;
279 ::glGetFloatv(GL_COLOR_CLEAR_VALUE, clearColor);
280 ::glClearColor(0, 0, 0, 0);
281 ::glGetBooleanv(GL_COLOR_WRITEMASK, colorMask);
282 ::glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
284 ::glGetFloatv(GL_DEPTH_CLEAR_VALUE, &clearDepth);
285 GraphicsContext3D::clearDepth(1);
286 ::glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMask);
287 ::glDepthMask(GL_TRUE);
288 clearMask |= GL_DEPTH_BUFFER_BIT;
290 if (m_attrs.stencil) {
291 ::glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &clearStencil);
293 ::glGetIntegerv(GL_STENCIL_WRITEMASK, reinterpret_cast<GLint*>(&stencilMask));
294 ::glStencilMaskSeparate(GL_FRONT, 0xffffffff);
295 clearMask |= GL_STENCIL_BUFFER_BIT;
297 isScissorEnabled = ::glIsEnabled(GL_SCISSOR_TEST);
298 ::glDisable(GL_SCISSOR_TEST);
299 isDitherEnabled = ::glIsEnabled(GL_DITHER);
300 ::glDisable(GL_DITHER);
302 ::glClear(clearMask);
304 ::glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
305 ::glColorMask(colorMask[0], colorMask[1], colorMask[2], colorMask[3]);
307 GraphicsContext3D::clearDepth(clearDepth);
308 ::glDepthMask(depthMask);
310 if (m_attrs.stencil) {
311 ::glClearStencil(clearStencil);
312 ::glStencilMaskSeparate(GL_FRONT, stencilMask);
314 if (isScissorEnabled)
315 ::glEnable(GL_SCISSOR_TEST);
317 ::glDisable(GL_SCISSOR_TEST);
319 ::glEnable(GL_DITHER);
321 ::glDisable(GL_DITHER);
324 ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_state.boundFBO);
329 bool GraphicsContext3D::areProgramSymbolsValid(Platform3DObject vertexShader, Platform3DObject fragmentShader) const
331 UNUSED_PARAM(vertexShader);
332 UNUSED_PARAM(fragmentShader);
337 IntSize GraphicsContext3D::getInternalFramebufferSize() const
339 return IntSize(m_currentWidth, m_currentHeight);
342 void GraphicsContext3D::activeTexture(GC3Denum texture)
344 makeContextCurrent();
345 m_state.activeTexture = texture;
346 ::glActiveTexture(texture);
349 void GraphicsContext3D::attachShader(Platform3DObject program, Platform3DObject shader)
353 makeContextCurrent();
354 ::glAttachShader(program, shader);
357 void GraphicsContext3D::bindAttribLocation(Platform3DObject program, GC3Duint index, const String& name)
360 makeContextCurrent();
362 String mappedName = mappedSymbolName(program, SHADER_SYMBOL_TYPE_ATTRIBUTE, name);
363 LOG(WebGL, "::bindAttribLocation is mapping %s to %s", name.utf8().data(), mappedName.utf8().data());
364 ::glBindAttribLocation(program, index, mappedName.utf8().data());
367 void GraphicsContext3D::bindBuffer(GC3Denum target, Platform3DObject buffer)
369 makeContextCurrent();
370 ::glBindBuffer(target, buffer);
373 void GraphicsContext3D::bindFramebuffer(GC3Denum target, Platform3DObject buffer)
375 makeContextCurrent();
380 #if PLATFORM(BLACKBERRY)
383 fbo = (m_attrs.antialias ? m_multisampleFBO : m_fbo);
385 if (fbo != m_state.boundFBO) {
386 ::glBindFramebufferEXT(target, fbo);
387 m_state.boundFBO = fbo;
391 void GraphicsContext3D::bindRenderbuffer(GC3Denum target, Platform3DObject renderbuffer)
393 makeContextCurrent();
394 ::glBindRenderbufferEXT(target, renderbuffer);
398 void GraphicsContext3D::bindTexture(GC3Denum target, Platform3DObject texture)
400 makeContextCurrent();
401 if (m_state.activeTexture == GL_TEXTURE0 && target == GL_TEXTURE_2D)
402 m_state.boundTexture0 = texture;
403 ::glBindTexture(target, texture);
406 void GraphicsContext3D::blendColor(GC3Dclampf red, GC3Dclampf green, GC3Dclampf blue, GC3Dclampf alpha)
408 makeContextCurrent();
409 ::glBlendColor(red, green, blue, alpha);
412 void GraphicsContext3D::blendEquation(GC3Denum mode)
414 makeContextCurrent();
415 ::glBlendEquation(mode);
418 void GraphicsContext3D::blendEquationSeparate(GC3Denum modeRGB, GC3Denum modeAlpha)
420 makeContextCurrent();
421 ::glBlendEquationSeparate(modeRGB, modeAlpha);
425 void GraphicsContext3D::blendFunc(GC3Denum sfactor, GC3Denum dfactor)
427 makeContextCurrent();
428 ::glBlendFunc(sfactor, dfactor);
431 void GraphicsContext3D::blendFuncSeparate(GC3Denum srcRGB, GC3Denum dstRGB, GC3Denum srcAlpha, GC3Denum dstAlpha)
433 makeContextCurrent();
434 ::glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
437 void GraphicsContext3D::bufferData(GC3Denum target, GC3Dsizeiptr size, GC3Denum usage)
439 makeContextCurrent();
440 ::glBufferData(target, size, 0, usage);
443 void GraphicsContext3D::bufferData(GC3Denum target, GC3Dsizeiptr size, const void* data, GC3Denum usage)
445 makeContextCurrent();
446 ::glBufferData(target, size, data, usage);
449 void GraphicsContext3D::bufferSubData(GC3Denum target, GC3Dintptr offset, GC3Dsizeiptr size, const void* data)
451 makeContextCurrent();
452 ::glBufferSubData(target, offset, size, data);
455 GC3Denum GraphicsContext3D::checkFramebufferStatus(GC3Denum target)
457 makeContextCurrent();
458 return ::glCheckFramebufferStatusEXT(target);
461 void GraphicsContext3D::clearColor(GC3Dclampf r, GC3Dclampf g, GC3Dclampf b, GC3Dclampf a)
463 makeContextCurrent();
464 ::glClearColor(r, g, b, a);
467 void GraphicsContext3D::clear(GC3Dbitfield mask)
469 makeContextCurrent();
473 void GraphicsContext3D::clearStencil(GC3Dint s)
475 makeContextCurrent();
479 void GraphicsContext3D::colorMask(GC3Dboolean red, GC3Dboolean green, GC3Dboolean blue, GC3Dboolean alpha)
481 makeContextCurrent();
482 ::glColorMask(red, green, blue, alpha);
485 void GraphicsContext3D::compileShader(Platform3DObject shader)
488 makeContextCurrent();
490 // Turn on name mapping. Due to the way ANGLE name hashing works, we
491 // point a global hashmap to the map owned by this context.
492 ShBuiltInResources ANGLEResources = m_compiler.getResources();
493 ShHashFunction64 previousHashFunction = ANGLEResources.HashFunction;
494 ANGLEResources.HashFunction = nameHashForShader;
496 if (!nameHashMapForShaders)
497 nameHashMapForShaders = adoptPtr(new ShaderNameHash);
498 currentNameHashMapForShader = nameHashMapForShaders.get();
499 m_compiler.setResources(ANGLEResources);
501 String translatedShaderSource = m_extensions->getTranslatedShaderSourceANGLE(shader);
503 ANGLEResources.HashFunction = previousHashFunction;
504 m_compiler.setResources(ANGLEResources);
505 currentNameHashMapForShader = nullptr;
507 if (!translatedShaderSource.length())
510 const CString& translatedShaderCString = translatedShaderSource.utf8();
511 const char* translatedShaderPtr = translatedShaderCString.data();
512 int translatedShaderLength = translatedShaderCString.length();
514 LOG(WebGL, "--- begin original shader source ---\n%s\n--- end original shader source ---\n", getShaderSource(shader).utf8().data());
515 LOG(WebGL, "--- begin translated shader source ---\n%s\n--- end translated shader source ---", translatedShaderPtr);
517 ::glShaderSource(shader, 1, &translatedShaderPtr, &translatedShaderLength);
519 ::glCompileShader(shader);
521 int GLCompileSuccess;
523 ::glGetShaderiv(shader, COMPILE_STATUS, &GLCompileSuccess);
525 ShaderSourceMap::iterator result = m_shaderSourceMap.find(shader);
526 GraphicsContext3D::ShaderSourceEntry& entry = result->value;
528 // Populate the shader log
530 ::glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
534 auto info = std::make_unique<GLchar[]>(length);
535 ::glGetShaderInfoLog(shader, length, &size, info.get());
537 entry.log = info.get();
540 if (GLCompileSuccess != GL_TRUE) {
541 entry.isValid = false;
542 LOG(WebGL, "Error: shader translator produced a shader that OpenGL would not compile.");
543 #if PLATFORM(BLACKBERRY) && !defined(NDEBUG)
544 BBLOG(BlackBerry::Platform::LogLevelWarn, "The shader validated, but didn't compile.\n");
549 void GraphicsContext3D::copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border)
551 makeContextCurrent();
552 #if !PLATFORM(BLACKBERRY)
553 if (m_attrs.antialias && m_state.boundFBO == m_multisampleFBO) {
554 resolveMultisamplingIfNecessary(IntRect(x, y, width, height));
555 ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_fbo);
558 ::glCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
559 #if !PLATFORM(BLACKBERRY)
560 if (m_attrs.antialias && m_state.boundFBO == m_multisampleFBO)
561 ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO);
565 void GraphicsContext3D::copyTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
567 makeContextCurrent();
568 #if !PLATFORM(BLACKBERRY)
569 if (m_attrs.antialias && m_state.boundFBO == m_multisampleFBO) {
570 resolveMultisamplingIfNecessary(IntRect(x, y, width, height));
571 ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_fbo);
574 ::glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
575 #if !PLATFORM(BLACKBERRY)
576 if (m_attrs.antialias && m_state.boundFBO == m_multisampleFBO)
577 ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO);
581 void GraphicsContext3D::cullFace(GC3Denum mode)
583 makeContextCurrent();
587 void GraphicsContext3D::depthFunc(GC3Denum func)
589 makeContextCurrent();
593 void GraphicsContext3D::depthMask(GC3Dboolean flag)
595 makeContextCurrent();
599 void GraphicsContext3D::detachShader(Platform3DObject program, Platform3DObject shader)
603 makeContextCurrent();
604 ::glDetachShader(program, shader);
607 void GraphicsContext3D::disable(GC3Denum cap)
609 makeContextCurrent();
613 void GraphicsContext3D::disableVertexAttribArray(GC3Duint index)
615 makeContextCurrent();
616 ::glDisableVertexAttribArray(index);
619 void GraphicsContext3D::drawArrays(GC3Denum mode, GC3Dint first, GC3Dsizei count)
621 makeContextCurrent();
622 ::glDrawArrays(mode, first, count);
625 void GraphicsContext3D::drawElements(GC3Denum mode, GC3Dsizei count, GC3Denum type, GC3Dintptr offset)
627 makeContextCurrent();
628 ::glDrawElements(mode, count, type, reinterpret_cast<GLvoid*>(static_cast<intptr_t>(offset)));
631 void GraphicsContext3D::enable(GC3Denum cap)
633 makeContextCurrent();
637 void GraphicsContext3D::enableVertexAttribArray(GC3Duint index)
639 makeContextCurrent();
640 ::glEnableVertexAttribArray(index);
643 void GraphicsContext3D::finish()
645 makeContextCurrent();
649 void GraphicsContext3D::flush()
651 makeContextCurrent();
655 void GraphicsContext3D::framebufferRenderbuffer(GC3Denum target, GC3Denum attachment, GC3Denum renderbuffertarget, Platform3DObject buffer)
657 makeContextCurrent();
658 ::glFramebufferRenderbufferEXT(target, attachment, renderbuffertarget, buffer);
661 void GraphicsContext3D::framebufferTexture2D(GC3Denum target, GC3Denum attachment, GC3Denum textarget, Platform3DObject texture, GC3Dint level)
663 makeContextCurrent();
664 ::glFramebufferTexture2DEXT(target, attachment, textarget, texture, level);
667 void GraphicsContext3D::frontFace(GC3Denum mode)
669 makeContextCurrent();
673 void GraphicsContext3D::generateMipmap(GC3Denum target)
675 makeContextCurrent();
676 ::glGenerateMipmap(target);
679 bool GraphicsContext3D::getActiveAttrib(Platform3DObject program, GC3Duint index, ActiveInfo& info)
682 synthesizeGLError(INVALID_VALUE);
685 makeContextCurrent();
686 GLint maxAttributeSize = 0;
687 ::glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxAttributeSize);
688 auto name = std::make_unique<GLchar[]>(maxAttributeSize); // GL_ACTIVE_ATTRIBUTE_MAX_LENGTH includes null termination.
689 GLsizei nameLength = 0;
692 ::glGetActiveAttrib(program, index, maxAttributeSize, &nameLength, &size, &type, name.get());
696 String originalName = originalSymbolName(program, SHADER_SYMBOL_TYPE_ATTRIBUTE, String(name.get(), nameLength));
698 info.name = originalName;
704 bool GraphicsContext3D::getActiveUniform(Platform3DObject program, GC3Duint index, ActiveInfo& info)
707 synthesizeGLError(INVALID_VALUE);
711 makeContextCurrent();
712 GLint maxUniformSize = 0;
713 ::glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniformSize);
715 auto name = std::make_unique<GLchar[]>(maxUniformSize); // GL_ACTIVE_UNIFORM_MAX_LENGTH includes null termination.
716 GLsizei nameLength = 0;
719 ::glGetActiveUniform(program, index, maxUniformSize, &nameLength, &size, &type, name.get());
723 String originalName = originalSymbolName(program, SHADER_SYMBOL_TYPE_UNIFORM, String(name.get(), nameLength));
725 info.name = originalName;
731 void GraphicsContext3D::getAttachedShaders(Platform3DObject program, GC3Dsizei maxCount, GC3Dsizei* count, Platform3DObject* shaders)
734 synthesizeGLError(INVALID_VALUE);
737 makeContextCurrent();
738 ::glGetAttachedShaders(program, maxCount, count, shaders);
741 String GraphicsContext3D::mappedSymbolName(Platform3DObject program, ANGLEShaderSymbolType symbolType, const String& name)
744 Platform3DObject shaders[2];
745 getAttachedShaders(program, 2, &count, shaders);
747 for (GC3Dsizei i = 0; i < count; ++i) {
748 ShaderSourceMap::iterator result = m_shaderSourceMap.find(shaders[i]);
749 if (result == m_shaderSourceMap.end())
752 const ShaderSymbolMap& symbolMap = result->value.symbolMap(symbolType);
753 ShaderSymbolMap::const_iterator symbolEntry = symbolMap.find(name);
754 if (symbolEntry != symbolMap.end())
755 return symbolEntry->value.mappedName;
760 String GraphicsContext3D::originalSymbolName(Platform3DObject program, ANGLEShaderSymbolType symbolType, const String& name)
763 Platform3DObject shaders[2];
764 getAttachedShaders(program, 2, &count, shaders);
766 for (GC3Dsizei i = 0; i < count; ++i) {
767 ShaderSourceMap::iterator result = m_shaderSourceMap.find(shaders[i]);
768 if (result == m_shaderSourceMap.end())
771 const ShaderSymbolMap& symbolMap = result->value.symbolMap(symbolType);
772 ShaderSymbolMap::const_iterator symbolEntry;
773 for (symbolEntry = symbolMap.begin(); symbolEntry != symbolMap.end(); ++symbolEntry) {
774 if (symbolEntry->value.mappedName == name)
775 return symbolEntry->key;
781 int GraphicsContext3D::getAttribLocation(Platform3DObject program, const String& name)
786 makeContextCurrent();
788 String mappedName = mappedSymbolName(program, SHADER_SYMBOL_TYPE_ATTRIBUTE, name);
789 LOG(WebGL, "::getAttribLocation is mapping %s to %s", name.utf8().data(), mappedName.utf8().data());
790 return ::glGetAttribLocation(program, mappedName.utf8().data());
793 GraphicsContext3D::Attributes GraphicsContext3D::getContextAttributes()
798 GC3Denum GraphicsContext3D::getError()
800 if (m_syntheticErrors.size() > 0) {
801 ListHashSet<GC3Denum>::iterator iter = m_syntheticErrors.begin();
802 GC3Denum err = *iter;
803 m_syntheticErrors.remove(iter);
807 makeContextCurrent();
808 return ::glGetError();
811 String GraphicsContext3D::getString(GC3Denum name)
813 makeContextCurrent();
814 return String(reinterpret_cast<const char*>(::glGetString(name)));
817 void GraphicsContext3D::hint(GC3Denum target, GC3Denum mode)
819 makeContextCurrent();
820 ::glHint(target, mode);
823 GC3Dboolean GraphicsContext3D::isBuffer(Platform3DObject buffer)
828 makeContextCurrent();
829 return ::glIsBuffer(buffer);
832 GC3Dboolean GraphicsContext3D::isEnabled(GC3Denum cap)
834 makeContextCurrent();
835 return ::glIsEnabled(cap);
838 GC3Dboolean GraphicsContext3D::isFramebuffer(Platform3DObject framebuffer)
843 makeContextCurrent();
844 return ::glIsFramebufferEXT(framebuffer);
847 GC3Dboolean GraphicsContext3D::isProgram(Platform3DObject program)
852 makeContextCurrent();
853 return ::glIsProgram(program);
856 GC3Dboolean GraphicsContext3D::isRenderbuffer(Platform3DObject renderbuffer)
861 makeContextCurrent();
862 return ::glIsRenderbufferEXT(renderbuffer);
865 GC3Dboolean GraphicsContext3D::isShader(Platform3DObject shader)
870 makeContextCurrent();
871 return ::glIsShader(shader);
874 GC3Dboolean GraphicsContext3D::isTexture(Platform3DObject texture)
879 makeContextCurrent();
880 return ::glIsTexture(texture);
883 void GraphicsContext3D::lineWidth(GC3Dfloat width)
885 makeContextCurrent();
886 ::glLineWidth(width);
889 void GraphicsContext3D::linkProgram(Platform3DObject program)
892 makeContextCurrent();
893 ::glLinkProgram(program);
896 void GraphicsContext3D::pixelStorei(GC3Denum pname, GC3Dint param)
898 makeContextCurrent();
899 ::glPixelStorei(pname, param);
902 void GraphicsContext3D::polygonOffset(GC3Dfloat factor, GC3Dfloat units)
904 makeContextCurrent();
905 ::glPolygonOffset(factor, units);
908 void GraphicsContext3D::sampleCoverage(GC3Dclampf value, GC3Dboolean invert)
910 makeContextCurrent();
911 ::glSampleCoverage(value, invert);
914 void GraphicsContext3D::scissor(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
916 makeContextCurrent();
917 ::glScissor(x, y, width, height);
920 void GraphicsContext3D::shaderSource(Platform3DObject shader, const String& string)
924 makeContextCurrent();
926 ShaderSourceEntry entry;
928 entry.source = string;
930 m_shaderSourceMap.set(shader, entry);
933 void GraphicsContext3D::stencilFunc(GC3Denum func, GC3Dint ref, GC3Duint mask)
935 makeContextCurrent();
936 ::glStencilFunc(func, ref, mask);
939 void GraphicsContext3D::stencilFuncSeparate(GC3Denum face, GC3Denum func, GC3Dint ref, GC3Duint mask)
941 makeContextCurrent();
942 ::glStencilFuncSeparate(face, func, ref, mask);
945 void GraphicsContext3D::stencilMask(GC3Duint mask)
947 makeContextCurrent();
948 ::glStencilMask(mask);
951 void GraphicsContext3D::stencilMaskSeparate(GC3Denum face, GC3Duint mask)
953 makeContextCurrent();
954 ::glStencilMaskSeparate(face, mask);
957 void GraphicsContext3D::stencilOp(GC3Denum fail, GC3Denum zfail, GC3Denum zpass)
959 makeContextCurrent();
960 ::glStencilOp(fail, zfail, zpass);
963 void GraphicsContext3D::stencilOpSeparate(GC3Denum face, GC3Denum fail, GC3Denum zfail, GC3Denum zpass)
965 makeContextCurrent();
966 ::glStencilOpSeparate(face, fail, zfail, zpass);
969 void GraphicsContext3D::texParameterf(GC3Denum target, GC3Denum pname, GC3Dfloat value)
971 makeContextCurrent();
972 ::glTexParameterf(target, pname, value);
975 void GraphicsContext3D::texParameteri(GC3Denum target, GC3Denum pname, GC3Dint value)
977 makeContextCurrent();
978 ::glTexParameteri(target, pname, value);
981 void GraphicsContext3D::uniform1f(GC3Dint location, GC3Dfloat v0)
983 makeContextCurrent();
984 ::glUniform1f(location, v0);
987 void GraphicsContext3D::uniform1fv(GC3Dint location, GC3Dsizei size, GC3Dfloat* array)
989 makeContextCurrent();
990 ::glUniform1fv(location, size, array);
993 void GraphicsContext3D::uniform2f(GC3Dint location, GC3Dfloat v0, GC3Dfloat v1)
995 makeContextCurrent();
996 ::glUniform2f(location, v0, v1);
999 void GraphicsContext3D::uniform2fv(GC3Dint location, GC3Dsizei size, GC3Dfloat* array)
1001 // FIXME: length needs to be a multiple of 2.
1002 makeContextCurrent();
1003 ::glUniform2fv(location, size, array);
1006 void GraphicsContext3D::uniform3f(GC3Dint location, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2)
1008 makeContextCurrent();
1009 ::glUniform3f(location, v0, v1, v2);
1012 void GraphicsContext3D::uniform3fv(GC3Dint location, GC3Dsizei size, GC3Dfloat* array)
1014 // FIXME: length needs to be a multiple of 3.
1015 makeContextCurrent();
1016 ::glUniform3fv(location, size, array);
1019 void GraphicsContext3D::uniform4f(GC3Dint location, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2, GC3Dfloat v3)
1021 makeContextCurrent();
1022 ::glUniform4f(location, v0, v1, v2, v3);
1025 void GraphicsContext3D::uniform4fv(GC3Dint location, GC3Dsizei size, GC3Dfloat* array)
1027 // FIXME: length needs to be a multiple of 4.
1028 makeContextCurrent();
1029 ::glUniform4fv(location, size, array);
1032 void GraphicsContext3D::uniform1i(GC3Dint location, GC3Dint v0)
1034 makeContextCurrent();
1035 ::glUniform1i(location, v0);
1038 void GraphicsContext3D::uniform1iv(GC3Dint location, GC3Dsizei size, GC3Dint* array)
1040 makeContextCurrent();
1041 ::glUniform1iv(location, size, array);
1044 void GraphicsContext3D::uniform2i(GC3Dint location, GC3Dint v0, GC3Dint v1)
1046 makeContextCurrent();
1047 ::glUniform2i(location, v0, v1);
1050 void GraphicsContext3D::uniform2iv(GC3Dint location, GC3Dsizei size, GC3Dint* array)
1052 // FIXME: length needs to be a multiple of 2.
1053 makeContextCurrent();
1054 ::glUniform2iv(location, size, array);
1057 void GraphicsContext3D::uniform3i(GC3Dint location, GC3Dint v0, GC3Dint v1, GC3Dint v2)
1059 makeContextCurrent();
1060 ::glUniform3i(location, v0, v1, v2);
1063 void GraphicsContext3D::uniform3iv(GC3Dint location, GC3Dsizei size, GC3Dint* array)
1065 // FIXME: length needs to be a multiple of 3.
1066 makeContextCurrent();
1067 ::glUniform3iv(location, size, array);
1070 void GraphicsContext3D::uniform4i(GC3Dint location, GC3Dint v0, GC3Dint v1, GC3Dint v2, GC3Dint v3)
1072 makeContextCurrent();
1073 ::glUniform4i(location, v0, v1, v2, v3);
1076 void GraphicsContext3D::uniform4iv(GC3Dint location, GC3Dsizei size, GC3Dint* array)
1078 // FIXME: length needs to be a multiple of 4.
1079 makeContextCurrent();
1080 ::glUniform4iv(location, size, array);
1083 void GraphicsContext3D::uniformMatrix2fv(GC3Dint location, GC3Dsizei size, GC3Dboolean transpose, GC3Dfloat* array)
1085 // FIXME: length needs to be a multiple of 4.
1086 makeContextCurrent();
1087 ::glUniformMatrix2fv(location, size, transpose, array);
1090 void GraphicsContext3D::uniformMatrix3fv(GC3Dint location, GC3Dsizei size, GC3Dboolean transpose, GC3Dfloat* array)
1092 // FIXME: length needs to be a multiple of 9.
1093 makeContextCurrent();
1094 ::glUniformMatrix3fv(location, size, transpose, array);
1097 void GraphicsContext3D::uniformMatrix4fv(GC3Dint location, GC3Dsizei size, GC3Dboolean transpose, GC3Dfloat* array)
1099 // FIXME: length needs to be a multiple of 16.
1100 makeContextCurrent();
1101 ::glUniformMatrix4fv(location, size, transpose, array);
1104 void GraphicsContext3D::useProgram(Platform3DObject program)
1106 makeContextCurrent();
1107 ::glUseProgram(program);
1110 void GraphicsContext3D::validateProgram(Platform3DObject program)
1114 makeContextCurrent();
1115 ::glValidateProgram(program);
1118 void GraphicsContext3D::vertexAttrib1f(GC3Duint index, GC3Dfloat v0)
1120 makeContextCurrent();
1121 ::glVertexAttrib1f(index, v0);
1124 void GraphicsContext3D::vertexAttrib1fv(GC3Duint index, GC3Dfloat* array)
1126 makeContextCurrent();
1127 ::glVertexAttrib1fv(index, array);
1130 void GraphicsContext3D::vertexAttrib2f(GC3Duint index, GC3Dfloat v0, GC3Dfloat v1)
1132 makeContextCurrent();
1133 ::glVertexAttrib2f(index, v0, v1);
1136 void GraphicsContext3D::vertexAttrib2fv(GC3Duint index, GC3Dfloat* array)
1138 makeContextCurrent();
1139 ::glVertexAttrib2fv(index, array);
1142 void GraphicsContext3D::vertexAttrib3f(GC3Duint index, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2)
1144 makeContextCurrent();
1145 ::glVertexAttrib3f(index, v0, v1, v2);
1148 void GraphicsContext3D::vertexAttrib3fv(GC3Duint index, GC3Dfloat* array)
1150 makeContextCurrent();
1151 ::glVertexAttrib3fv(index, array);
1154 void GraphicsContext3D::vertexAttrib4f(GC3Duint index, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2, GC3Dfloat v3)
1156 makeContextCurrent();
1157 ::glVertexAttrib4f(index, v0, v1, v2, v3);
1160 void GraphicsContext3D::vertexAttrib4fv(GC3Duint index, GC3Dfloat* array)
1162 makeContextCurrent();
1163 ::glVertexAttrib4fv(index, array);
1166 void GraphicsContext3D::vertexAttribPointer(GC3Duint index, GC3Dint size, GC3Denum type, GC3Dboolean normalized, GC3Dsizei stride, GC3Dintptr offset)
1168 makeContextCurrent();
1169 ::glVertexAttribPointer(index, size, type, normalized, stride, reinterpret_cast<GLvoid*>(static_cast<intptr_t>(offset)));
1172 void GraphicsContext3D::viewport(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
1174 makeContextCurrent();
1175 ::glViewport(x, y, width, height);
1178 void GraphicsContext3D::getBooleanv(GC3Denum pname, GC3Dboolean* value)
1180 makeContextCurrent();
1181 ::glGetBooleanv(pname, value);
1184 void GraphicsContext3D::getBufferParameteriv(GC3Denum target, GC3Denum pname, GC3Dint* value)
1186 makeContextCurrent();
1187 ::glGetBufferParameteriv(target, pname, value);
1190 void GraphicsContext3D::getFloatv(GC3Denum pname, GC3Dfloat* value)
1192 makeContextCurrent();
1193 ::glGetFloatv(pname, value);
1196 void GraphicsContext3D::getFramebufferAttachmentParameteriv(GC3Denum target, GC3Denum attachment, GC3Denum pname, GC3Dint* value)
1198 makeContextCurrent();
1199 if (attachment == DEPTH_STENCIL_ATTACHMENT)
1200 attachment = DEPTH_ATTACHMENT; // Or STENCIL_ATTACHMENT, either works.
1201 ::glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, value);
1204 void GraphicsContext3D::getProgramiv(Platform3DObject program, GC3Denum pname, GC3Dint* value)
1206 makeContextCurrent();
1207 ::glGetProgramiv(program, pname, value);
1210 String GraphicsContext3D::getProgramInfoLog(Platform3DObject program)
1214 makeContextCurrent();
1216 ::glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
1221 auto info = std::make_unique<GLchar[]>(length);
1222 ::glGetProgramInfoLog(program, length, &size, info.get());
1224 return String(info.get());
1227 void GraphicsContext3D::getRenderbufferParameteriv(GC3Denum target, GC3Denum pname, GC3Dint* value)
1229 makeContextCurrent();
1230 ::glGetRenderbufferParameterivEXT(target, pname, value);
1233 void GraphicsContext3D::getShaderiv(Platform3DObject shader, GC3Denum pname, GC3Dint* value)
1237 makeContextCurrent();
1239 ShaderSourceMap::iterator result = m_shaderSourceMap.find(shader);
1244 ::glGetShaderiv(shader, pname, value);
1246 case COMPILE_STATUS:
1247 if (result == m_shaderSourceMap.end()) {
1248 *value = static_cast<int>(false);
1251 *value = static_cast<int>(result->value.isValid);
1253 case INFO_LOG_LENGTH:
1254 if (result == m_shaderSourceMap.end()) {
1258 *value = getShaderInfoLog(shader).length();
1260 case SHADER_SOURCE_LENGTH:
1261 *value = getShaderSource(shader).length();
1264 synthesizeGLError(INVALID_ENUM);
1268 String GraphicsContext3D::getShaderInfoLog(Platform3DObject shader)
1272 makeContextCurrent();
1274 ShaderSourceMap::iterator result = m_shaderSourceMap.find(shader);
1275 if (result == m_shaderSourceMap.end())
1278 ShaderSourceEntry entry = result->value;
1283 ::glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
1288 auto info = std::make_unique<GLchar[]>(length);
1289 ::glGetShaderInfoLog(shader, length, &size, info.get());
1291 return String(info.get());
1294 String GraphicsContext3D::getShaderSource(Platform3DObject shader)
1298 makeContextCurrent();
1300 ShaderSourceMap::iterator result = m_shaderSourceMap.find(shader);
1301 if (result == m_shaderSourceMap.end())
1304 return result->value.source;
1308 void GraphicsContext3D::getTexParameterfv(GC3Denum target, GC3Denum pname, GC3Dfloat* value)
1310 makeContextCurrent();
1311 ::glGetTexParameterfv(target, pname, value);
1314 void GraphicsContext3D::getTexParameteriv(GC3Denum target, GC3Denum pname, GC3Dint* value)
1316 makeContextCurrent();
1317 ::glGetTexParameteriv(target, pname, value);
1320 void GraphicsContext3D::getUniformfv(Platform3DObject program, GC3Dint location, GC3Dfloat* value)
1322 makeContextCurrent();
1323 ::glGetUniformfv(program, location, value);
1326 void GraphicsContext3D::getUniformiv(Platform3DObject program, GC3Dint location, GC3Dint* value)
1328 makeContextCurrent();
1329 ::glGetUniformiv(program, location, value);
1332 GC3Dint GraphicsContext3D::getUniformLocation(Platform3DObject program, const String& name)
1336 makeContextCurrent();
1338 String mappedName = mappedSymbolName(program, SHADER_SYMBOL_TYPE_UNIFORM, name);
1339 LOG(WebGL, "::getUniformLocation is mapping %s to %s", name.utf8().data(), mappedName.utf8().data());
1340 return ::glGetUniformLocation(program, mappedName.utf8().data());
1343 void GraphicsContext3D::getVertexAttribfv(GC3Duint index, GC3Denum pname, GC3Dfloat* value)
1345 makeContextCurrent();
1346 ::glGetVertexAttribfv(index, pname, value);
1349 void GraphicsContext3D::getVertexAttribiv(GC3Duint index, GC3Denum pname, GC3Dint* value)
1351 makeContextCurrent();
1352 ::glGetVertexAttribiv(index, pname, value);
1355 GC3Dsizeiptr GraphicsContext3D::getVertexAttribOffset(GC3Duint index, GC3Denum pname)
1357 makeContextCurrent();
1359 GLvoid* pointer = 0;
1360 ::glGetVertexAttribPointerv(index, pname, &pointer);
1361 return static_cast<GC3Dsizeiptr>(reinterpret_cast<intptr_t>(pointer));
1364 void GraphicsContext3D::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoff, GC3Dint yoff, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, const void* pixels)
1366 makeContextCurrent();
1368 if (type == HALF_FLOAT_OES)
1369 type = GL_HALF_FLOAT_ARB;
1371 // FIXME: we will need to deal with PixelStore params when dealing with image buffers that differ from the subimage size.
1372 ::glTexSubImage2D(target, level, xoff, yoff, width, height, format, type, pixels);
1375 void GraphicsContext3D::compressedTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Dsizei imageSize, const void* data)
1377 makeContextCurrent();
1378 ::glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);
1381 void GraphicsContext3D::compressedTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Dsizei imageSize, const void* data)
1383 makeContextCurrent();
1384 ::glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);
1387 Platform3DObject GraphicsContext3D::createBuffer()
1389 makeContextCurrent();
1391 glGenBuffers(1, &o);
1395 Platform3DObject GraphicsContext3D::createFramebuffer()
1397 makeContextCurrent();
1399 glGenFramebuffersEXT(1, &o);
1403 Platform3DObject GraphicsContext3D::createProgram()
1405 makeContextCurrent();
1406 return glCreateProgram();
1409 Platform3DObject GraphicsContext3D::createRenderbuffer()
1411 makeContextCurrent();
1413 glGenRenderbuffersEXT(1, &o);
1417 Platform3DObject GraphicsContext3D::createShader(GC3Denum type)
1419 makeContextCurrent();
1420 return glCreateShader((type == FRAGMENT_SHADER) ? GL_FRAGMENT_SHADER : GL_VERTEX_SHADER);
1423 Platform3DObject GraphicsContext3D::createTexture()
1425 makeContextCurrent();
1427 glGenTextures(1, &o);
1431 void GraphicsContext3D::deleteBuffer(Platform3DObject buffer)
1433 makeContextCurrent();
1434 glDeleteBuffers(1, &buffer);
1437 void GraphicsContext3D::deleteFramebuffer(Platform3DObject framebuffer)
1439 makeContextCurrent();
1440 if (framebuffer == m_state.boundFBO) {
1441 // Make sure the framebuffer is not going to be used for drawing
1442 // operations after it gets deleted.
1443 bindFramebuffer(FRAMEBUFFER, 0);
1445 glDeleteFramebuffersEXT(1, &framebuffer);
1448 void GraphicsContext3D::deleteProgram(Platform3DObject program)
1450 makeContextCurrent();
1451 glDeleteProgram(program);
1454 void GraphicsContext3D::deleteRenderbuffer(Platform3DObject renderbuffer)
1456 makeContextCurrent();
1457 glDeleteRenderbuffersEXT(1, &renderbuffer);
1460 void GraphicsContext3D::deleteShader(Platform3DObject shader)
1462 makeContextCurrent();
1463 glDeleteShader(shader);
1466 void GraphicsContext3D::deleteTexture(Platform3DObject texture)
1468 makeContextCurrent();
1469 if (m_state.boundTexture0 == texture)
1470 m_state.boundTexture0 = 0;
1471 glDeleteTextures(1, &texture);
1474 void GraphicsContext3D::synthesizeGLError(GC3Denum error)
1476 m_syntheticErrors.add(error);
1479 void GraphicsContext3D::markContextChanged()
1481 m_layerComposited = false;
1484 void GraphicsContext3D::markLayerComposited()
1486 m_layerComposited = true;
1489 bool GraphicsContext3D::layerComposited() const
1491 return m_layerComposited;
1494 void GraphicsContext3D::texImage2DDirect(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels)
1496 makeContextCurrent();
1497 ::glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
1502 #endif // USE(3D_GRAPHICS)