diff options
Diffstat (limited to 'WebCore/platform/graphics/chromium/LayerRendererChromium.cpp')
-rw-r--r-- | WebCore/platform/graphics/chromium/LayerRendererChromium.cpp | 117 |
1 files changed, 98 insertions, 19 deletions
diff --git a/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp b/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp index b071385..15acfa5 100644 --- a/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp +++ b/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp @@ -34,21 +34,25 @@ #if USE(ACCELERATED_COMPOSITING) #include "LayerRendererChromium.h" +#include "CanvasLayerChromium.h" #include "GLES2Context.h" #include "LayerChromium.h" #include "NotImplemented.h" #include "TransformLayerChromium.h" -#include "WebGLLayerChromium.h" #if PLATFORM(SKIA) #include "NativeImageSkia.h" #include "PlatformContextSkia.h" +#elif PLATFORM(CG) +#include <CoreGraphics/CGBitmapContext.h> #endif #include <GLES2/gl2.h> namespace WebCore { +#ifndef NDEBUG static WTFLogChannel LogLayerRenderer = { 0x00000000, "LayerRenderer", WTFLogChannelOn }; +#endif static void checkGLError() { @@ -195,12 +199,12 @@ PassOwnPtr<LayerRendererChromium> LayerRendererChromium::create(PassOwnPtr<GLES2 } LayerRendererChromium::LayerRendererChromium(PassOwnPtr<GLES2Context> gles2Context) - : m_rootLayer(0) - , m_needsDisplay(false) + : m_rootLayerTextureWidth(0) + , m_rootLayerTextureHeight(0) , m_positionLocation(0) , m_texCoordLocation(1) - , m_rootLayerTextureWidth(0) - , m_rootLayerTextureHeight(0) + , m_rootLayer(0) + , m_needsDisplay(false) , m_scrollPosition(IntPoint(-1, -1)) , m_currentShaderProgramType(NumShaderProgramTypes) , m_gles2Context(gles2Context) @@ -245,6 +249,19 @@ void LayerRendererChromium::setRootLayerCanvasSize(const IntSize& size) m_rootLayerSkiaContext->setDrawingToImageBuffer(true); #endif m_rootLayerGraphicsContext = new GraphicsContext(reinterpret_cast<PlatformGraphicsContext*>(m_rootLayerSkiaContext.get())); +#elif PLATFORM(CG) + // Release the previous CGBitmapContext before reallocating the backing store as a precaution. + m_rootLayerCGContext.adoptCF(0); + int rowBytes = 4 * size.width(); + m_rootLayerBackingStore.resize(rowBytes * size.height()); + memset(m_rootLayerBackingStore.data(), 0, m_rootLayerBackingStore.size()); + // FIXME: unsure whether this is the best color space choice. + RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateWithName(kCGColorSpaceGenericRGBLinear)); + m_rootLayerCGContext.adoptCF(CGBitmapContextCreate(m_rootLayerBackingStore.data(), + size.width(), size.height(), 8, rowBytes, + colorSpace.get(), + kCGImageAlphaPremultipliedLast)); + m_rootLayerGraphicsContext = new GraphicsContext(m_rootLayerCGContext.get()); #else #error "Need to implement for your platform." #endif @@ -304,34 +321,51 @@ void LayerRendererChromium::drawLayers(const IntRect& updateRect, const IntRect& // and viewport. makeContextCurrent(); + checkGLError(); + glBindTexture(GL_TEXTURE_2D, m_rootLayerTextureId); - unsigned visibleRectWidth = visibleRect.width(); - unsigned visibleRectHeight = visibleRect.height(); + checkGLError(); + + int visibleRectWidth = visibleRect.width(); + int visibleRectHeight = visibleRect.height(); if (visibleRectWidth != m_rootLayerTextureWidth || visibleRectHeight != m_rootLayerTextureHeight) { m_rootLayerTextureWidth = visibleRect.width(); m_rootLayerTextureHeight = visibleRect.height(); - m_projectionMatrix = orthoMatrix(0, visibleRectWidth + 0.5, visibleRectHeight + 0.5, 0, -1000, 1000); + m_projectionMatrix = orthoMatrix(0, visibleRectWidth, visibleRectHeight, 0, -1000, 1000); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_rootLayerTextureWidth, m_rootLayerTextureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + + checkGLError(); } // The GL viewport covers the entire visible area, including the scrollbars. glViewport(0, 0, visibleRectWidth, visibleRectHeight); + checkGLError(); + // The layer, scroll and debug border shaders all use the same vertex attributes // so we can bind them only once. glBindBuffer(GL_ARRAY_BUFFER, m_quadVboIds[Vertices]); + checkGLError(); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_quadVboIds[LayerElements]); + checkGLError(); GLuint offset = 0; glVertexAttribPointer(m_positionLocation, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(offset)); + checkGLError(); offset += 3 * sizeof(GLfloat); glVertexAttribPointer(m_texCoordLocation, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(offset)); + checkGLError(); glEnableVertexAttribArray(m_positionLocation); + checkGLError(); glEnableVertexAttribArray(m_texCoordLocation); + checkGLError(); glActiveTexture(GL_TEXTURE0); + checkGLError(); glDisable(GL_DEPTH_TEST); + checkGLError(); glDisable(GL_CULL_FACE); + checkGLError(); if (m_scrollPosition == IntPoint(-1, -1)) m_scrollPosition = scrollPosition; @@ -346,15 +380,28 @@ void LayerRendererChromium::drawLayers(const IntRect& updateRect, const IntRect& // root layer texture. The newly exposed area is subesquently filled as usual with // the contents of the updateRect. TransformationMatrix scrolledLayerMatrix; - scrolledLayerMatrix.translate3d((int)floorf(0.5 * visibleRect.width() + 0.5) - scrollDelta.x(), - (int)floorf(0.5 * visibleRect.height() + 0.5) + scrollDelta.y(), 0); +#if PLATFORM(SKIA) + float scaleFactor = 1.0f; +#elif PLATFORM(CG) + // Because the contents of the OpenGL texture are inverted + // vertically compared to the Skia backend, we need to move + // the backing store in the opposite direction. + float scaleFactor = -1.0f; +#else +#error "Need to implement for your platform." +#endif + + scrolledLayerMatrix.translate3d((int)floorf(0.5 * visibleRect.width()) - scrollDelta.x(), + (int)floorf(0.5 * visibleRect.height()) + scaleFactor * scrollDelta.y(), 0); scrolledLayerMatrix.scale3d(1, -1, 1); // Switch shaders to avoid RGB swizzling. useShaderProgram(ScrollLayerProgram); glUniform1i(m_shaderPrograms[ScrollLayerProgram].m_samplerLocation, 0); + checkGLError(); drawTexturedQuad(scrolledLayerMatrix, visibleRect.width(), visibleRect.height(), 1); + checkGLError(); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, contentRect.width(), contentRect.height()); @@ -381,31 +428,52 @@ void LayerRendererChromium::drawLayers(const IntRect& updateRect, const IntRect& // Copy the contents of the updated rect to the root layer texture. glTexSubImage2D(GL_TEXTURE_2D, 0, updateRect.x(), updateRect.y(), updateRect.width(), updateRect.height(), GL_RGBA, GL_UNSIGNED_BYTE, pixels); checkGLError(); +#elif PLATFORM(CG) + // Get the contents of the updated rect. + ASSERT(static_cast<int>(CGBitmapContextGetWidth(m_rootLayerCGContext.get())) == updateRect.width() && static_cast<int>(CGBitmapContextGetHeight(m_rootLayerCGContext.get())) == updateRect.height()); + void* pixels = m_rootLayerBackingStore.data(); + + checkGLError(); + // Copy the contents of the updated rect to the root layer texture. + // The origin is at the lower left in Core Graphics' coordinate system. We need to correct for this here. + glTexSubImage2D(GL_TEXTURE_2D, 0, + updateRect.x(), m_rootLayerTextureHeight - updateRect.y() - updateRect.height(), + updateRect.width(), updateRect.height(), + GL_RGBA, GL_UNSIGNED_BYTE, pixels); + checkGLError(); #else -#error Must port to your platform +#error "Need to implement for your platform." #endif } glClearColor(0, 0, 1, 1); + checkGLError(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + checkGLError(); // Render the root layer using a quad that takes up the entire visible area of the window. useShaderProgram(ContentLayerProgram); + checkGLError(); glUniform1i(m_samplerLocation, 0); + checkGLError(); TransformationMatrix layerMatrix; - layerMatrix.translate3d(visibleRect.width() / 2, visibleRect.height() / 2, 0); + layerMatrix.translate3d(visibleRect.width() * 0.5f, visibleRect.height() * 0.5f, 0); drawTexturedQuad(layerMatrix, visibleRect.width(), visibleRect.height(), 1); + checkGLError(); // If culling is enabled then we will cull the backface. glCullFace(GL_BACK); + checkGLError(); // The orthographic projection is setup such that Y starts at zero and // increases going down the page so we need to adjust the winding order of // front facing triangles. glFrontFace(GL_CW); + checkGLError(); // The shader used to render layers returns pre-multiplied alpha colors // so we need to send the blending mode appropriately. glEnable(GL_BLEND); + checkGLError(); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); checkGLError(); @@ -623,6 +691,7 @@ void LayerRendererChromium::drawLayer(LayerChromium* layer) if (layer->contentsDirty()) { // Update the backing texture contents for any dirty portion of the layer. layer->updateTextureContents(textureId); + m_gles2Context->makeCurrent(); } if (layer->doubleSided()) @@ -668,6 +737,9 @@ bool LayerRendererChromium::initializeSharedGLObjects() " gl_Position = matrix * a_position; \n" " v_texCoord = a_texCoord; \n" "} \n"; + // Note differences between Skia and Core Graphics versions: + // - Skia uses BGRA and origin is upper left + // - Core Graphics uses RGBA and origin is lower left char fragmentShaderString[] = "precision mediump float; \n" "varying vec2 v_texCoord; \n" @@ -675,8 +747,15 @@ bool LayerRendererChromium::initializeSharedGLObjects() "uniform float alpha; \n" "void main() \n" "{ \n" +#if PLATFORM(SKIA) " vec4 texColor = texture2D(s_texture, v_texCoord); \n" " gl_FragColor = vec4(texColor.z, texColor.y, texColor.x, texColor.w) * alpha; \n" +#elif PLATFORM(CG) + " vec4 texColor = texture2D(s_texture, vec2(v_texCoord.x, 1.0 - v_texCoord.y)); \n" + " gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha; \n" +#else +#error "Need to implement for your platform." +#endif "} \n"; // Fragment shader used for rendering the scrolled root layer quad. It differs @@ -692,9 +771,9 @@ bool LayerRendererChromium::initializeSharedGLObjects() " gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w); \n" "} \n"; - // WebGL layers need to be flipped vertically and their colors shouldn't be + // Canvas layers need to be flipped vertically and their colors shouldn't be // swizzled. - char webGLFragmentShaderString[] = + char canvasFragmentShaderString[] = "precision mediump float; \n" "varying vec2 v_texCoord; \n" "uniform sampler2D s_texture; \n" @@ -741,11 +820,11 @@ bool LayerRendererChromium::initializeSharedGLObjects() } LayerChromium::setShaderProgramId(ContentLayerProgram); - if (!createLayerShader(WebGLLayerProgram, vertexShaderString, webGLFragmentShaderString)) { - LOG_ERROR("Failed to create shader program for WebGL layers"); + if (!createLayerShader(CanvasLayerProgram, vertexShaderString, canvasFragmentShaderString)) { + LOG_ERROR("Failed to create shader program for Canvas layers"); return false; } - WebGLLayerChromium::setShaderProgramId(WebGLLayerProgram); + CanvasLayerChromium::setShaderProgramId(CanvasLayerProgram); if (!createLayerShader(ScrollLayerProgram, vertexShaderString, scrollFragmentShaderString)) { LOG_ERROR("Failed to create shader program for scrolling layer"); @@ -760,7 +839,7 @@ bool LayerRendererChromium::initializeSharedGLObjects() // Specify the attrib location for the position and texCoord and make it the same for all programs to // avoid binding re-binding the vertex attributes. bindCommonAttribLocations(ContentLayerProgram); - bindCommonAttribLocations(WebGLLayerProgram); + bindCommonAttribLocations(CanvasLayerProgram); bindCommonAttribLocations(DebugBorderProgram); bindCommonAttribLocations(ScrollLayerProgram); @@ -775,7 +854,7 @@ bool LayerRendererChromium::initializeSharedGLObjects() // Create a texture object to hold the contents of the root layer. m_rootLayerTextureId = createLayerTexture(); - if (m_rootLayerTextureId == -1) { + if (!m_rootLayerTextureId) { LOG_ERROR("Failed to create texture for root layer"); return false; } |