2 Copyright (C) 2011 Samsung Electronics
3 Copyright (C) 2013 Intel Corporation. All rights reserved.
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
22 #include "AcceleratedPlatformLayer.h"
24 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE) && ENABLE(TIZEN_ACCELERATED_PLATFORM_LAYER)
26 #if ENABLE(TIZEN_DDK_WORKAROUND)
27 #include "Extensions3D.h"
30 #include "ImageBuffer.h"
31 #include "ImageData.h"
32 #include "NotImplemented.h"
34 #define GL_GLEXT_PROTOTYPES 1
35 #include <GLES2/gl2.h>
36 #include <GLES2/gl2ext.h>
42 #include <wtf/OwnArrayPtr.h>
46 PassOwnPtr<AcceleratedPlatformLayer> AcceleratedPlatformLayer::create(GraphicsContext3D::Attributes attrs, GraphicsContext3D::RenderStyle renderStyle)
48 if (renderStyle == GraphicsContext3D::RenderDirectlyToHostWindow)
51 OwnPtr<AcceleratedPlatformLayer> internal = adoptPtr(new AcceleratedPlatformLayer(attrs, renderStyle));
52 if (!internal->initialize(0))
55 return internal.release();
59 : activeTexture(GraphicsContext3D::TEXTURE0)
62 , sourceFactor(GraphicsContext3D::ONE)
63 , destinationFactor(GraphicsContext3D::ZERO)
69 , stencilFunc(GraphicsContext3D::ALWAYS)
71 , stencilMask(UINT_MAX)
72 , stencilFail(GraphicsContext3D::KEEP)
73 , stencilZFail(GraphicsContext3D::KEEP)
74 , stencilZPass(GraphicsContext3D::KEEP)
80 m_state = BlendFuncCacheDirty | DepthMaskCacheDirty | StencilFuncCacheDirty | StencilOpCacheDirty | ViewportCacheDirty;
85 if (!pixelStoreIntMap.isEmpty())
86 pixelStoreIntMap.clear();
88 if (!capabilityStateMap.isEmpty())
89 capabilityStateMap.clear();
92 AcceleratedPlatformLayer::AcceleratedPlatformLayer(GraphicsContext3D::Attributes attrs, GraphicsContext3D::RenderStyle renderStyle)
93 : GraphicsContext3DInternal(attrs, GraphicsContext3D::RenderOffscreen)
94 , m_compositorTexture(0)
95 , m_layerComposited(false)
101 , m_renderStyle(renderStyle)
102 , m_state(adoptPtr(new State()))
106 AcceleratedPlatformLayer::~AcceleratedPlatformLayer()
108 if (m_renderStyle == GraphicsContext3D::RenderToCurrentGLContext)
111 makeContextCurrent();
112 GL_CMD(glBindFramebuffer(GL_FRAMEBUFFER, 0));
113 GL_CMD(glBindTexture(GL_TEXTURE_2D, 0));
115 if (m_compositorTexture)
116 GL_CMD(glDeleteTextures(1, &m_compositorTexture));
121 void AcceleratedPlatformLayer::releaseResources()
123 // Release the current context and drawable only after destroying any associated gl resources.
125 if (m_offScreenSurface)
126 m_offScreenSurface->destroy();
128 if (m_offScreenContext) {
129 m_offScreenContext->destroy();
130 m_offScreenContext->releaseCurrent();
134 PlatformLayer* AcceleratedPlatformLayer::platformLayer() const
136 return const_cast<TextureMapperPlatformLayer*>(static_cast<const TextureMapperPlatformLayer*>(this));
139 bool AcceleratedPlatformLayer::initialize(HostWindow*)
141 if (!initializeSurface())
144 validateAttributes();
146 // ANGLE integration starts
147 ShBuiltInResources ANGLEResources;
148 ShInitBuiltInResources(&ANGLEResources);
150 GL_CMD(getIntegerv(GraphicsContext3D::MAX_VERTEX_ATTRIBS, &ANGLEResources.MaxVertexAttribs));
151 GL_CMD(getIntegerv(GraphicsContext3D::MAX_VERTEX_UNIFORM_VECTORS, &ANGLEResources.MaxVertexUniformVectors));
152 GL_CMD(getIntegerv(GraphicsContext3D::MAX_VARYING_VECTORS, &ANGLEResources.MaxVaryingVectors));
153 GL_CMD(getIntegerv(GraphicsContext3D::MAX_VERTEX_TEXTURE_IMAGE_UNITS, &ANGLEResources.MaxVertexTextureImageUnits));
154 GL_CMD(getIntegerv(GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS, &ANGLEResources.MaxCombinedTextureImageUnits));
155 GL_CMD(getIntegerv(GraphicsContext3D::MAX_TEXTURE_IMAGE_UNITS, &ANGLEResources.MaxTextureImageUnits));
156 GL_CMD(getIntegerv(GraphicsContext3D::MAX_FRAGMENT_UNIFORM_VECTORS, &ANGLEResources.MaxFragmentUniformVectors));
158 // Always set to 1 for OpenGL ES.
159 ANGLEResources.MaxDrawBuffers = 1;
160 m_compiler.setResources(ANGLEResources);
161 // ANGLE Integration block ENDs
163 if (m_renderStyle != GraphicsContext3D::RenderToCurrentGLContext)
164 GL_CMD(glClearColor(0.0, 0.0, 0.0, 0.0));
169 bool AcceleratedPlatformLayer::initializeSurface()
171 m_offScreenContext = GLPlatformContext::createContext(m_renderStyle);
172 if (!m_offScreenContext)
175 if (m_renderStyle == GraphicsContext3D::RenderOffscreen) {
176 GLPlatformSurface::SurfaceAttributes sharedSurfaceAttributes = GLPlatformSurface::Default;
177 if (m_attributes.alpha)
178 sharedSurfaceAttributes |= GLPlatformSurface::SupportAlpha;
180 if (m_attributes.depth)
181 sharedSurfaceAttributes |= GLPlatformSurface::SupportDepth;
183 if (m_attributes.stencil)
184 sharedSurfaceAttributes |= GLPlatformSurface::SupportStencil;
186 m_offScreenSurface = GLPlatformSurface::createOffScreenSurface(sharedSurfaceAttributes, IntSize(m_width, m_height));
188 if (!m_offScreenSurface)
191 if (!m_offScreenContext->initialize(m_offScreenSurface.get()))
194 if (!makeContextCurrent())
197 if (m_offScreenSurface->attributes() & GLPlatformSurface::SupportAlpha)
198 m_surfaceFlags |= GraphicsSurface::Alpha;
200 if (m_attributes.premultipliedAlpha)
201 m_surfaceFlags |= GraphicsSurface::PremultipliedAlpha;
203 // synchronize the attributes,
204 m_attributes.stencil = m_offScreenSurface->attributes() & GLPlatformSurface::SupportStencil;
205 m_attributes.depth = m_offScreenSurface->attributes() & GLPlatformSurface::SupportDepth;
206 m_attributes.alpha = m_offScreenSurface->attributes() & GLPlatformSurface::SupportAlpha;
208 m_surfaceHandle = m_offScreenSurface->handle();
214 bool AcceleratedPlatformLayer::makeContextCurrent()
216 bool success = m_offScreenContext->makeCurrent(m_offScreenSurface.get());
218 if (!m_offScreenContext->isValid()) {
219 // FIXME: Restore context
220 if (m_contextLostCallback)
221 m_contextLostCallback->onContextLost();
229 void AcceleratedPlatformLayer::setContextLostCallback(PassOwnPtr<GraphicsContext3D::ContextLostCallback> callBack)
231 m_contextLostCallback = callBack;
234 bool AcceleratedPlatformLayer::paintToCanvas(const unsigned char* imagePixels, int imageWidth, int imageHeight, int canvasWidth, int canvasHeight, PlatformContextCairo* context)
236 if (!imagePixels || imageWidth <= 0 || imageHeight <= 0 || canvasWidth <= 0 || canvasHeight <= 0 || !context)
239 cairo_t* cr = context->cr();
242 RefPtr<cairo_surface_t> imageSurface = adoptRef(cairo_image_surface_create_for_data(
243 const_cast<unsigned char*>(imagePixels), CAIRO_FORMAT_ARGB32, imageWidth, imageHeight, imageWidth * 4));
245 cairo_rectangle(cr, 0, 0, canvasWidth, canvasHeight);
247 // OpenGL keeps the pixels stored bottom up, so we need to flip the image here.
248 cairo_matrix_t matrix;
249 cairo_matrix_init(&matrix, 1.0, 0.0, 0.0, -1.0, 0.0, imageHeight);
250 cairo_set_matrix(cr, &matrix);
251 cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
252 cairo_set_source_surface(cr, imageSurface.get(), 0, 0);
259 void AcceleratedPlatformLayer::paintRenderingResultsToCanvas(ImageBuffer* imageBuffer, int width, int height)
261 int totalBytes = 4 * width * height;
263 OwnArrayPtr<unsigned char> pixels = adoptArrayPtr(new unsigned char[totalBytes]);
267 readRenderingResults(pixels.get(), totalBytes , width , height);
269 #if ENABLE(TIZEN_CANVAS_CAIRO_GLES_RENDERING)
270 cairo_surface_t* surface = imageBuffer->getSurface();
271 if (cairo_surface_get_type(surface) == CAIRO_SURFACE_TYPE_GL) {
272 // TODO: premultipliedAlpha currently not getting applied. Need to apply the value properly.
273 if (!m_attributes.premultipliedAlpha) {
274 for (int i = 0; i < totalBytes; i = 4) {
275 // Premultiply alpha.
276 pixels[i+0] = std::min(255, pixels[i+0] * pixels[i+3] / 255);
277 pixels[i+1] = std::min(255, pixels[i+1] * pixels[i+3] / 255);
278 pixels[i+2] = std::min(255, pixels[i+2] * pixels[i+3] / 255);
283 paintToCanvas(pixels.get(), width, height,
284 imageBuffer->internalSize().width(), imageBuffer->internalSize().height(), imageBuffer->context()->platformContext());
287 PassRefPtr<ImageData> AcceleratedPlatformLayer::paintRenderingResultsToImageData(int width, int height)
289 // Reading premultiplied alpha would involve unpremultiplying, which is
291 if (m_attributes.premultipliedAlpha)
294 RefPtr<ImageData> imageData = ImageData::create(IntSize(width, height));
295 unsigned char* pixels = imageData->data()->data();
296 int totalBytes = 4 * width * height;
298 readRenderingResults(pixels, totalBytes, width, height);
301 for (int i = 0; i < totalBytes; i = 4)
302 std::swap(pixels[i], pixels[i+2]);
304 return imageData.release();
307 void AcceleratedPlatformLayer::markContextChanged()
309 m_layerComposited = false;
310 m_swapBuffers = true;
313 bool AcceleratedPlatformLayer::swapPlatformSurfaces()
318 makeContextCurrent();
319 m_swapBuffers = false;
320 m_offScreenSurface->swapBuffers();
321 m_layerComposited = true;
325 void AcceleratedPlatformLayer::prepareTexture(int width, int height)
327 if (m_layerComposited)
330 GLuint internalColorFormat = 0;
331 if (m_attributes.alpha)
332 internalColorFormat = GL_RGBA;
334 internalColorFormat = GL_RGB;
336 makeContextCurrent();
337 GL_CMD(glActiveTexture(GL_TEXTURE0));
338 GL_CMD(glBindTexture(GL_TEXTURE_2D, m_compositorTexture));
339 GL_CMD(glCopyTexImage2D(GL_TEXTURE_2D, 0, internalColorFormat, 0, 0, width, height, 0));
340 GL_CMD(glBindTexture(GL_TEXTURE_2D, m_state->boundTexture0));
341 GL_CMD(glActiveTexture(m_state->activeTexture));
344 m_layerComposited = true;
347 void AcceleratedPlatformLayer::readRenderingResults(unsigned char *pixels, int pixelsSize, int width, int height)
349 int totalBytes = width * height * 4;
350 if (pixelsSize < totalBytes)
353 makeContextCurrent();
354 if (m_attributes.antialias)
357 GLint packAlignment = 4;
358 bool mustRestorePackAlignment = false;
359 GL_CMD(glGetIntegerv(GL_PACK_ALIGNMENT, &packAlignment));
360 if (packAlignment > 4) {
361 pixelStorei(GL_PACK_ALIGNMENT, 4);
362 mustRestorePackAlignment = true;
365 GL_CMD(glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels));
367 for (int i = 0; i < totalBytes; i = 4)
368 std::swap(pixels[i], pixels[i+2]);
370 if (mustRestorePackAlignment)
371 pixelStorei(GL_PACK_ALIGNMENT, packAlignment);
374 void AcceleratedPlatformLayer::reshape(int width, int height)
376 if ((m_width == width) && (m_height == height))
381 makeContextCurrent();
383 if (m_offScreenSurface && (m_offScreenSurface->attributes() & GLPlatformSurface::DoubleBuffered)) {
384 m_offScreenSurface->swapBuffers();
385 m_offScreenSurface->setGeometry(IntRect(0, 0, m_width, m_height));
387 // FIXME: Handle resize case for single buffered surface.
389 m_surfaceHandle = m_offScreenSurface->handle();
391 if (m_attributes.antialias)
394 // Initialize renderbuffers to 0.
395 GLfloat clearColorValue[] = {0, 0, 0, 0}, clearDepthValue = 0;
396 GLint clearStencilValue = 0;
397 GLboolean colorMaskValue[] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE}, depthMaskValue = GL_TRUE;
398 GLuint stencilMask = 0xffffffff;
399 GLboolean isScissorEnabled = GL_FALSE;
400 GLboolean isDitherEnabled = GL_FALSE;
402 GLbitfield clearMask = GL_COLOR_BUFFER_BIT;
404 GL_CMD(glGetFloatv(GL_COLOR_CLEAR_VALUE, clearColorValue));
405 GL_CMD(glClearColor(0, 0, 0, 0));
406 GL_CMD(glGetBooleanv(GL_COLOR_WRITEMASK, colorMaskValue));
407 GL_CMD(glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE));
409 if (m_attributes.depth) {
410 GL_CMD(glGetFloatv(GL_DEPTH_CLEAR_VALUE, &clearDepthValue));
411 GL_CMD(glClearDepthf(1.0));
412 GL_CMD(glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMaskValue));
413 GL_CMD(glDepthMask(GL_TRUE));
414 clearMask |= GL_DEPTH_BUFFER_BIT;
417 if (m_attributes.stencil) {
418 GL_CMD(glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &clearStencilValue));
419 GL_CMD(glClearStencil(0));
420 GL_CMD(glGetIntegerv(GL_STENCIL_WRITEMASK, reinterpret_cast<GLint*>(&stencilMask)));
421 GL_CMD(glStencilMaskSeparate(GL_FRONT, 0xffffffff));
422 clearMask |= GL_STENCIL_BUFFER_BIT;
425 isScissorEnabled = GL_CMD(glIsEnabled(GL_SCISSOR_TEST));
426 GL_CMD(glDisable(GL_SCISSOR_TEST));
427 isDitherEnabled = GL_CMD(glIsEnabled(GL_DITHER));
428 GL_CMD(glDisable(GL_DITHER));
430 GL_CMD(glClear(clearMask));
432 GL_CMD(glClearColor(clearColorValue[0], clearColorValue[1], clearColorValue[2], clearColorValue[3]));
433 GL_CMD(glColorMask(colorMaskValue[0], colorMaskValue[1], colorMaskValue[2], colorMaskValue[3]));
435 if (m_attributes.depth) {
436 GL_CMD(glClearDepthf(clearDepthValue));
437 GL_CMD(glDepthMask(depthMaskValue));
439 if (m_attributes.stencil) {
440 GL_CMD(glClearStencil(clearStencilValue));
441 GL_CMD(glStencilMaskSeparate(GL_FRONT, stencilMask));
444 if (isScissorEnabled)
445 GL_CMD(glEnable(GL_SCISSOR_TEST));
447 GL_CMD(glDisable(GL_SCISSOR_TEST));
450 GL_CMD(glEnable(GL_DITHER));
452 GL_CMD(glDisable(GL_DITHER));
455 void AcceleratedPlatformLayer::activeTexture(GC3Denum texture)
457 if (m_state->activeTexture != texture) {
458 m_state->activeTexture = texture;
459 GraphicsContext3DInternal::activeTexture(texture);
463 void AcceleratedPlatformLayer::bindFramebuffer(GC3Denum target, Platform3DObject framebuffer)
465 GLuint fbo = framebuffer;
466 if (framebuffer != m_state->boundFBO) {
467 m_state->boundFBO = fbo;
468 // FIXME : Below lines are workaround codes.(driver issue)
469 // PlatformSurface surface is not updated properly after binding FBO.
470 // It seems previous frame is remained.
471 #if ENABLE(TIZEN_DDK_WORKAROUND)
472 if (flush && framebuffer && !m_layerComposited)
475 GraphicsContext3DInternal::bindFramebuffer(target, fbo);
479 #if ENABLE(TIZEN_DDK_WORKAROUND)
480 void AcceleratedPlatformLayer::framebufferTexture2D(GC3Denum target, GC3Denum attachment, GC3Denum textarget, Platform3DObject texture, GC3Dint level)
482 // We should probably remove the tid that was set to framebuffer from m_renderTargetTextures
483 // if texture is no longer rendered to, but since this is temporary code that will be removed
484 // when the DDK is fixed, and that scenario is quite unlikely to happen, I'll just leave it as is.
485 if (target != Extensions3D::READ_FRAMEBUFFER && texture)
486 m_renderTargetTextures.add(texture);
488 GraphicsContext3DInternal::framebufferTexture2D(target, attachment, textarget, texture, level);
491 void AcceleratedPlatformLayer::generateMipmap(GC3Denum target)
493 // FIXME: Render to texture related driver issue.
494 // Remove GC3DOffscreen::generateMipmap and related code when driver issue is fixed.
495 // The rendered texture contents are not properly flushed before generating mipmaps.
497 GL_CMD(glGetIntegerv(GL_TEXTURE_BINDING_2D, &boundTexture));
498 if (m_renderTargetTextures.contains(boundTexture))
501 GraphicsContext3DInternal::generateMipmap(target);
505 void AcceleratedPlatformLayer::bindTexture(GC3Denum target, Platform3DObject texture)
507 if (m_state->activeTexture == GL_TEXTURE0 && target == GL_TEXTURE_2D) {
508 if (m_state->boundTexture0 == texture)
511 m_state->boundTexture0 = texture;
514 GraphicsContext3DInternal::bindTexture(target, texture);
517 void AcceleratedPlatformLayer::bufferData(GC3Denum target, GC3Dsizeiptr size, const void* data, GC3Denum usage)
519 GraphicsContext3DInternal::bufferData(target, size, data, usage);
521 // FIXME : Driver issue!
522 // Following lines are temporary to avoid webgl conformance test failures.
523 // See draw-arrays-out-of-bounds.html.
524 // If a parameter size inputted to glBufferData is zero,
525 // GL_OUT_OF_MEMORY error is occurred while running in Mali driver.
527 GC3Denum error = getError();
528 if (error == GL_OUT_OF_MEMORY)
530 synthesizeGLError(error); // Push the error back again.
534 bool AcceleratedPlatformLayer::getActiveAttrib(Platform3DObject program, GC3Duint index, ActiveInfo& info)
537 synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
541 makeContextCurrent();
542 GLint maxAttributeSize = 0;
543 GL_CMD(glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxAttributeSize));
545 GLchar name[maxAttributeSize]; // GL_ACTIVE_ATTRIBUTE_MAX_LENGTH includes null termination
546 GLsizei nameLength = 0;
549 GL_CMD(glGetActiveAttrib(program, index, maxAttributeSize, &nameLength, &size, &type, name));
553 info.name = String(name, nameLength);
559 bool AcceleratedPlatformLayer::getActiveUniform(Platform3DObject program, GC3Duint index, ActiveInfo& info)
562 synthesizeGLError(GL_INVALID_VALUE);
566 makeContextCurrent();
567 GC3Dint maxUniformSize = 0;
568 GL_CMD(glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniformSize));
570 GLchar name[maxUniformSize]; // GL_ACTIVE_UNIFORM_MAX_LENGTH includes null termination
571 GC3Dsizei nameLength = 0;
574 GL_CMD(glGetActiveUniform(program, index, maxUniformSize, &nameLength, &size, &type, name));
578 info.name = String(name, nameLength);
582 // FIXME : "[0]" is added at end of name in WebGLRenderingContext::getActiveUniform()
583 // when isGLES2Compliant is only false. I can't understand the reason.
584 // I add "[0]" here to avoid faling webgl conformance test(get-active-test.html),
585 // but if it makes something wrong later, remove following lines
586 if (isGLES2Compliant() && info.size > 1 && !info.name.endsWith("[0]"))
587 info.name.append("[0]");
592 void AcceleratedPlatformLayer::getFloatv(GC3Denum pname, GC3Dfloat* value)
594 GraphicsContext3DInternal::getFloatv(pname, value);
596 // FIXME : Fllowing lines are for fixing SGX & Mali driver issue.
598 case GL_ALIASED_POINT_SIZE_RANGE:
599 case GL_ALIASED_LINE_WIDTH_RANGE:
600 if (value[0] == value[1]) {
610 if (value[0] < value[1]) {
611 if (value[1] < 1.0) {
629 void AcceleratedPlatformLayer::getIntegerv(GC3Denum pname, GC3Dint* value)
631 makeContextCurrent();
632 GL_CMD(glGetIntegerv(pname, value));
635 void AcceleratedPlatformLayer::viewport(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
637 if (!updateViewportCache(x, y, width, height))
640 makeContextCurrent();
641 GL_CMD(glViewport(x, y, width, height));
644 void AcceleratedPlatformLayer::stencilOp(GC3Denum fail, GC3Denum zfail, GC3Denum zpass)
646 if (!updateStencilOpCache(fail, zfail, zpass))
649 makeContextCurrent();
650 GL_CMD(glStencilOp(fail, zfail, zpass));
653 void AcceleratedPlatformLayer::stencilFunc(GC3Denum func, GC3Dint ref, GC3Duint mask)
655 if (!updateStencilFuncCache(func, ref, mask))
658 makeContextCurrent();
659 GL_CMD(glStencilFunc(func, ref, mask));
662 void AcceleratedPlatformLayer::scissor(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
664 if (!updateScissorCache(x, y, width, height))
667 makeContextCurrent();
668 GL_CMD(glScissor(x, y, width, height));
671 void AcceleratedPlatformLayer::pixelStorei(GC3Denum pname, GC3Dint param)
673 if (!updatePixelStoreiCache(pname, param))
676 makeContextCurrent();
677 GL_CMD(glPixelStorei(pname, param));
680 GC3Dboolean AcceleratedPlatformLayer::isEnabled(GC3Denum cap)
682 State::CapabilityState state = getCapabilityState(cap);
683 if (state != State::CapabilityUnknown)
684 return state == State::CapabilityEnabled ? true : false;
686 makeContextCurrent();
687 return GL_CMD(glIsEnabled(cap));
690 void AcceleratedPlatformLayer::enable(GC3Denum cap)
692 if (!updateCapabilityCache(cap, State::CapabilityEnabled))
695 makeContextCurrent();
696 GL_CMD(glEnable(cap));
699 void AcceleratedPlatformLayer::disable(GC3Denum cap)
701 if (!updateCapabilityCache(cap, State::CapabilityDisabled))
704 makeContextCurrent();
705 GL_CMD(glDisable(cap));
708 void AcceleratedPlatformLayer::depthMask(GC3Dboolean flag)
710 if (!updateDepthMaskCache(flag))
713 makeContextCurrent();
714 GL_CMD(glDepthMask(flag));
717 void AcceleratedPlatformLayer::blendFunc(GC3Denum sfactor, GC3Denum dfactor)
719 if (!updateBlendFuncCache(sfactor, dfactor))
722 makeContextCurrent();
723 GL_CMD(glBlendFunc(sfactor, dfactor));
726 // below functions are for ANGLE integration
727 void AcceleratedPlatformLayer::compileShader(Platform3DObject shader)
730 makeContextCurrent();
733 ANGLEShaderType shaderType;
735 GL_CMD(glGetShaderiv(shader, GraphicsContext3D::SHADER_TYPE, &GLshaderType));
737 if (GLshaderType == GraphicsContext3D::VERTEX_SHADER)
738 shaderType = SHADER_TYPE_VERTEX;
739 else if (GLshaderType == GraphicsContext3D::FRAGMENT_SHADER)
740 shaderType = SHADER_TYPE_FRAGMENT;
742 return; // Invalid shader type.
744 HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader);
746 if (result == m_shaderSourceMap.end())
749 ShaderSourceEntry& entry = result->second;
751 String translatedShaderSource;
752 String shaderInfoLog;
754 bool isValid = m_compiler.validateShaderSource(entry.source.utf8().data(), shaderType, translatedShaderSource, shaderInfoLog);
756 entry.log = shaderInfoLog;
757 entry.isValid = isValid;
760 return; // Shader didn't validate, don't move forward with compiling translated source.
762 int len = entry.source.length();
763 CString cstr = entry.source.utf8();
764 const char* s = cstr.data();
766 GL_CMD(glShaderSource(shader, 1, &s, &len));
767 GL_CMD(glCompileShader(shader));
771 void AcceleratedPlatformLayer::getShaderiv(Platform3DObject shader, GC3Denum pname, GC3Dint* value)
775 makeContextCurrent();
777 HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader);
780 case GraphicsContext3D::DELETE_STATUS:
781 case GraphicsContext3D::SHADER_TYPE:
782 GL_CMD(glGetShaderiv(shader, pname, value));
784 case GraphicsContext3D::COMPILE_STATUS:
785 if (result == m_shaderSourceMap.end()) {
786 *value = static_cast<int>(false);
789 *value = static_cast<int>(result->second.isValid);
791 case GraphicsContext3D::INFO_LOG_LENGTH:
792 if (result == m_shaderSourceMap.end()) {
796 *value = getShaderInfoLog(shader).length();
798 case GraphicsContext3D::SHADER_SOURCE_LENGTH:
799 *value = getShaderSource(shader).length();
802 synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
806 String AcceleratedPlatformLayer::getShaderInfoLog(Platform3DObject shader)
810 makeContextCurrent();
812 HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader);
813 if (result == m_shaderSourceMap.end())
816 ShaderSourceEntry entry = result->second;
821 GL_CMD(glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length));
826 OwnArrayPtr<GLchar> info = adoptArrayPtr(new GLchar[length]);
827 GL_CMD(glGetShaderInfoLog(shader, length, &size, info.get()));
829 return String(info.get());
832 String AcceleratedPlatformLayer::getShaderSource(Platform3DObject shader)
836 makeContextCurrent();
838 HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader);
839 if (result == m_shaderSourceMap.end())
842 return result->second.source;
845 void AcceleratedPlatformLayer::shaderSource(Platform3DObject shader, const String& string)
849 makeContextCurrent();
851 ShaderSourceEntry entry;
853 entry.source = string;
854 entry.isValid = false;
856 m_shaderSourceMap.set(shader, entry);
859 bool AcceleratedPlatformLayer::updateBlendFuncCache(GC3Denum sourceFactor, GC3Denum destinationFactor)
861 if (m_state->m_state & State::BlendFuncCacheDirty)
862 m_state->m_state &= ~State::BlendFuncCacheDirty;
863 else if (m_state->sourceFactor == sourceFactor && m_state->destinationFactor == destinationFactor)
866 m_state->sourceFactor = sourceFactor;
867 m_state->destinationFactor = destinationFactor;
871 bool AcceleratedPlatformLayer::updateDepthMaskCache(GC3Dboolean depthMask)
873 if (m_state->m_state & State::DepthMaskCacheDirty)
874 m_state->m_state &= ~State::DepthMaskCacheDirty;
875 else if (m_state->depthMask == depthMask)
878 m_state->depthMask = depthMask;
882 bool AcceleratedPlatformLayer::updateScissorCache(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
884 if (m_state->m_state & State::ScissorCacheDirty)
885 m_state->m_state &= ~State::ScissorCacheDirty;
886 else if (m_state->scissorX == x && m_state->scissorY == y && m_state->scissorWidth == width && m_state->scissorHeight == height)
889 m_state->scissorX = x;
890 m_state->scissorY = y;
891 m_state->scissorWidth = width;
892 m_state->scissorHeight = height;
896 bool AcceleratedPlatformLayer::updateStencilFuncCache(GC3Denum func, GC3Dint ref, GC3Duint mask)
898 if (m_state->m_state & State::StencilFuncCacheDirty)
899 m_state->m_state &= ~State::StencilFuncCacheDirty;
900 else if (m_state->stencilFunc == func && m_state->stencilRef == ref && m_state->stencilMask == mask)
903 m_state->stencilFunc = func;
904 m_state->stencilRef = ref;
905 m_state->stencilMask = mask;
909 bool AcceleratedPlatformLayer::updateStencilOpCache(GC3Denum fail, GC3Denum zfail, GC3Denum zpass)
913 if (m_state->m_state & State::StencilOpCacheDirty)
914 m_state->m_state &= ~State::StencilOpCacheDirty;
915 else if (m_state->stencilFail == fail && m_state->stencilZFail == zfail && m_state->stencilZPass == zpass)
918 m_state->stencilFail = fail;
919 m_state->stencilZFail = zfail;
920 m_state->stencilZPass = zpass;
924 bool AcceleratedPlatformLayer::updateViewportCache(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
926 if (m_state->m_state & State::ViewportCacheDirty)
927 m_state->m_state &= ~State::ViewportCacheDirty;
928 else if (m_state->viewportX == x && m_state->viewportY == y && m_state->viewportWidth == width && m_state->viewportHeight == height)
931 m_state->viewportX = x;
932 m_state->viewportY = y;
933 m_state->viewportWidth = width;
934 m_state->viewportHeight = height;
938 bool AcceleratedPlatformLayer::updatePixelStoreiCache(GC3Denum pname, GC3Dint param)
940 State::PixelStoreIntMap::const_iterator it = m_state->pixelStoreIntMap.find(pname);
941 if (it != m_state->pixelStoreIntMap.end() && it->second == param)
944 m_state->pixelStoreIntMap.set(pname, param);
948 State::CapabilityState AcceleratedPlatformLayer::getCapabilityState(GC3Denum cap)
950 State::CapabilityStateMap::const_iterator it = m_state->capabilityStateMap.find(cap);
951 if (it == m_state->capabilityStateMap.end())
952 return State::CapabilityUnknown;
957 bool AcceleratedPlatformLayer::updateCapabilityCache(GC3Denum cap, State::CapabilityState isEnabled)
959 State::CapabilityStateMap::const_iterator it = m_state->capabilityStateMap.find(cap);
960 if (it != m_state->capabilityStateMap.end() && it->second == isEnabled)
963 m_state->capabilityStateMap.set(cap, isEnabled);
967 } // namespace WebCore