[webkit-reviews] review denied: [Bug 44926] Multiple accelerated 2D canvases should be able to use the same GraphicsContext3D : [Attachment 66013] Patch
bugzilla-daemon at webkit.org
bugzilla-daemon at webkit.org
Tue Aug 31 11:43:18 PDT 2010
Kenneth Russell <kbr at google.com> has denied review:
Bug 44926: Multiple accelerated 2D canvases should be able to use the same
GraphicsContext3D
https://bugs.webkit.org/show_bug.cgi?id=44926
Attachment 66013: Patch
https://bugs.webkit.org/attachment.cgi?id=66013&action=review
------- Additional Comments from Kenneth Russell <kbr at google.com>
This looks very good overall. There are a couple of relatively minor issues
where PassRefPtr is used in a return value where it shouldn't be (see "Function
results" in http://webkit.org/coding/RefPtr.html ) for which I'm marking this
patch r-, but after these are cleaned up I'll be happy to r+ it.
> diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
> index
ddcd52e9676ba66bb03c410afff59e2261f7d830..94147a54b8123231a1af74267031e26ad174b
08f 100644
> --- a/WebCore/ChangeLog
> +++ b/WebCore/ChangeLog
> @@ -1,3 +1,173 @@
> +2010-08-30 James Robinson <jamesr at chromium.org>
> +
> + Reviewed by NOBODY (OOPS!).
> +
> + Multiple accelerated 2D canvases should be able to use the same
GraphicsContext3D
> + https://bugs.webkit.org/show_bug.cgi?id=44926
> +
> + This allows many accelerated 2d canvases to render using a single
underlying GraphicsContext3D.
> + It introduces a new class SharedContext3D that manages several
callers. This class could
> + also cache the current state to avoid issuing redundant calls,
although in this first cut it doesn't.
> + The SharedContext3D is provided through the ChromeClient so that its
lifetime can be tied to that
> + of the platform-specific compositor infrastructure.
> +
> + Accelerated 2d canvases maintain a reference to a SharedContext3D
and have ownership of a CanvasFramebuffer,
> + which represents the canvas's rendering target. The compositing
layer for an accelerated 2d canvas is
> + aware only of the canvas's CanvasFramebuffer. This means that WebGL
and 2d canvases are no longer treated
> + as the same time of layer by the compositor.
time -> type
> + Covered by existing canvas tests.
> +
> + I've divided the per file/function changes into three sections:
> + - Platform-independent application logic outside WebCore/platform
> + - Platform-independent infrastructure in WebCore/platform
> + - Platform-specific changes
> +
> + * html/canvas/CanvasRenderingContext.cpp:
> + * html/canvas/CanvasRenderingContext.h:
> + (WebCore::CanvasRenderingContext::paintsIntoCanvasBuffer):
> + * html/canvas/CanvasRenderingContext2D.cpp:
> + (WebCore::CanvasRenderingContext2D::CanvasRenderingContext2D):
> + (WebCore::CanvasRenderingContext2D::paintsIntoCanvasBuffer):
> + (WebCore::CanvasRenderingContext2D::reset):
> + (WebCore::CanvasRenderingContext2D::drawImage):
> + (WebCore::CanvasRenderingContext2D::didDraw):
> + * html/canvas/CanvasRenderingContext2D.h:
> + (WebCore::CanvasRenderingContext2D::framebuffer):
> + * html/canvas/WebGLRenderingContext.cpp:
> + (WebCore::WebGLRenderingContext::paintsIntoCanvasBuffer):
> + * html/canvas/WebGLRenderingContext.h:
> + (WebCore::WebGLRenderingContext::graphicsContext3D):
> + * loader/EmptyClients.h:
> + (WebCore::EmptyChromeClient::attachRootGraphicsLayer):
> + (WebCore::EmptyChromeClient::setNeedsOneShotDrawingSynchronization):
> + (WebCore::EmptyChromeClient::scheduleCompositingLayerSync):
> + (WebCore::EmptyChromeClient::getSharedContext3D):
> + * page/ChromeClient.h:
> + * rendering/RenderLayerBacking.cpp:
> + (WebCore::RenderLayerBacking::updateGraphicsLayerConfiguration):
> + Cross-platform infrastructure in WebCore/platform:
Could you put some sort of prefix on these separator lines to distinguish them
from the autogenerated output?
> + * WebCore.gypi:
> + * platform/graphics/GraphicsContext.h:
> + * platform/graphics/GraphicsContext3D.h:
> + * platform/graphics/GraphicsLayer.h:
> + (WebCore::GraphicsLayer::setContentsToWebGL):
> + (WebCore::GraphicsLayer::setContentsToCanvas2D):
> + * platform/graphics/gpu/CanvasFramebuffer.cpp: Added.
> + (WebCore::CanvasFramebuffer::CanvasFramebuffer):
> + (WebCore::CanvasFramebuffer::~CanvasFramebuffer):
> + (WebCore::CanvasFramebuffer::bind):
> + (WebCore::CanvasFramebuffer::swapBuffers):
> + (WebCore::CanvasFramebuffer::setWillSwapBuffersCallback):
> + (WebCore::CanvasFramebuffer::create):
> + * platform/graphics/gpu/CanvasFramebuffer.h: Added.
> + (WebCore::CanvasFramebuffer::textureIdForCompositor):
> + (WebCore::CanvasFramebuffer::textureIdForCanvas):
> + * platform/graphics/gpu/SharedContext3D.cpp: Added.
> + (WebCore::affineTo3x3):
> + (WebCore::SharedContext3D::create):
> + (WebCore::SharedContext3D::SharedContext3D):
> + (WebCore::SharedContext3D::~SharedContext3D):
> + (WebCore::SharedContext3D::scissor):
> + (WebCore::SharedContext3D::enable):
> + (WebCore::SharedContext3D::disable):
> + (WebCore::SharedContext3D::clearColor):
> + (WebCore::SharedContext3D::clear):
> + (WebCore::SharedContext3D::drawArrays):
> + (WebCore::SharedContext3D::getError):
> + (WebCore::SharedContext3D::getIntegerv):
> + (WebCore::SharedContext3D::createFramebuffer):
> + (WebCore::SharedContext3D::createTexture):
> + (WebCore::SharedContext3D::deleteFramebuffer):
> + (WebCore::SharedContext3D::deleteTexture):
> + (WebCore::SharedContext3D::deleteCompositorTexture):
> + (WebCore::SharedContext3D::framebufferTexture2D):
> + (WebCore::SharedContext3D::texParameteri):
> + (WebCore::SharedContext3D::texImage2D):
> + (WebCore::SharedContext3D::texSubImage2D):
> + (WebCore::SharedContext3D::readPixels):
> + (WebCore::SharedContext3D::getTexture):
> + (WebCore::SharedContext3D::applyCompositeOperator):
> + (WebCore::SharedContext3D::useQuadVertices):
> + (WebCore::SharedContext3D::setActiveTexture):
> + (WebCore::SharedContext3D::bindTexture):
> + (WebCore::SharedContext3D::useFillSolidProgram):
> + (WebCore::SharedContext3D::useTextureProgram):
> + (WebCore::SharedContext3D::bindFramebuffer):
> + (WebCore::SharedContext3D::setViewport):
> + (WebCore::SharedContext3D::supportsBGRA):
> + (WebCore::SharedContext3D::createCompositorTexture):
> + (WebCore::SharedContext3D::copyTextureToCompositor):
> + (WebCore::SharedContext3D::paintsIntoCanvasBuffer):
> + * platform/graphics/gpu/SharedContext3D.h: Added.
> + * platform/graphics/gpu/Texture.cpp:
> + Mac-specific changes:
> + * platform/graphics/mac/GraphicsLayerCA.h:
> + * platform/graphics/mac/GraphicsLayerCA.mm:
> + (WebCore::GraphicsLayerCA::setContentsToWebGL):
> + Chromium-specific changes:
> + * platform/graphics/chromium/Canvas2DLayerChromium.cpp: Added.
> + (WebCore::Canvas2DLayerChromium::create):
> + (WebCore::Canvas2DLayerChromium::Canvas2DLayerChromium):
> + (WebCore::Canvas2DLayerChromium::updateContents):
> + (WebCore::Canvas2DLayerChromium::setCanvasFramebuffer):
> + (WebCore::Canvas2DLayerChromium::textureId):
> + * platform/graphics/chromium/Canvas2DLayerChromium.h: Added.
> + (WebCore::Canvas2DLayerChromium::drawsContent):
> + * platform/graphics/chromium/CanvasLayerChromium.cpp:
> + CanvasLayerChromium is now a base class for WebGLLayerChromium and
Canvas2DLayerChromium.
> + (WebCore::CanvasLayerChromium::CanvasLayerChromium):
> + (WebCore::CanvasLayerChromium::~CanvasLayerChromium):
> + (WebCore::CanvasLayerChromium::draw):
> + * platform/graphics/chromium/CanvasLayerChromium.h:
> + * platform/graphics/chromium/GLES2Canvas.cpp:
> + (WebCore::GLES2Canvas::GLES2Canvas):
> + (WebCore::GLES2Canvas::~GLES2Canvas):
> + (WebCore::GLES2Canvas::swapBuffers):
> + (WebCore::GLES2Canvas::bindFramebuffer):
> + (WebCore::GLES2Canvas::textureIdForCompositor):
> + (WebCore::GLES2Canvas::textureIdForCanvas):
> + (WebCore::GLES2Canvas::clearRect):
> + (WebCore::GLES2Canvas::fillRect):
> + (WebCore::GLES2Canvas::drawTexturedRect):
> + (WebCore::GLES2Canvas::drawTexturedRectTile):
> + (WebCore::GLES2Canvas::drawQuad):
> + (WebCore::GLES2Canvas::createTexture):
> + (WebCore::GLES2Canvas::getTexture):
> + * platform/graphics/chromium/GLES2Canvas.h:
> + (WebCore::GLES2Canvas::context):
> + * platform/graphics/chromium/GraphicsLayerChromium.cpp:
> + (WebCore::GraphicsLayerChromium::setContentsToWebGL):
> + (WebCore::GraphicsLayerChromium::setContentsToCanvas2D):
> + * platform/graphics/chromium/GraphicsLayerChromium.h:
> + * platform/graphics/chromium/LayerRendererChromium.cpp:
> + * platform/graphics/chromium/WebGLLayerChromium.cpp: Added.
> + (WebCore::WebGLLayerChromium::create):
> + (WebCore::WebGLLayerChromium::WebGLLayerChromium):
> + (WebCore::WebGLLayerChromium::updateContents):
> + (WebCore::WebGLLayerChromium::setContext):
> + * platform/graphics/chromium/WebGLLayerChromium.h: Added.
> + (WebCore::WebGLLayerChromium::drawsContent):
> + (WebCore::WebGLLayerChromium::textureId):
> + * platform/graphics/skia/GraphicsContextSkia.cpp:
> + (WebCore::GraphicsContext::setSharedContext3D):
> + (WebCore::GraphicsContext::textureIdForCompositor):
> + (WebCore::GraphicsContext::textureIdForCanvas):
> + * platform/graphics/skia/ImageBufferSkia.cpp:
> + (WebCore::ImageBuffer::draw):
> + * platform/graphics/skia/ImageSkia.cpp:
> + (WebCore::drawBitmapGLES2):
> + * platform/graphics/skia/PlatformContextSkia.cpp:
> + (WebCore::PlatformContextSkia::~PlatformContextSkia):
> + (WebCore::SwapBuffersCallbackImpl::create):
> + (WebCore::SwapBuffersCallbackImpl::willSwapBuffers):
> + (WebCore::SwapBuffersCallbackImpl::SwapBuffersCallbackImpl):
> + (WebCore::PlatformContextSkia::setSharedContext3D):
> + (WebCore::PlatformContextSkia::swapBuffers):
> + (WebCore::PlatformContextSkia::uploadSoftwareToHardware):
> + (WebCore::PlatformContextSkia::readbackHardwareToSoftware):
> + * platform/graphics/skia/PlatformContextSkia.h:
> +
> 2010-08-30 Chris Rogers <crogers at google.com>
>
> Reviewed by Kenneth Russell.
> diff --git a/WebCore/loader/EmptyClients.h b/WebCore/loader/EmptyClients.h
> index
270752dd7f8f01fa94f7c293d3cfe7fa95ed291f..eda55ba756bcd55507f6d4e79269d8eb0c5ae
2d3 100644
> --- a/WebCore/loader/EmptyClients.h
> +++ b/WebCore/loader/EmptyClients.h
> @@ -46,6 +46,10 @@
> #include "ResourceError.h"
> #include "SearchPopupMenu.h"
>
> +#if ENABLE(ACCELERATED_2D_CANVAS)
> +#include "SharedContext3D.h"
Is it possible to use a forward declaration instead?
> +#endif
> +
> /*
> This file holds empty Client stubs for use by WebCore.
> Viewless element needs to create a dummy Page->Frame->FrameView tree for
use in parsing or executing JavaScript.
> @@ -190,9 +194,13 @@ public:
> virtual void cancelGeolocationPermissionRequestForFrame(Frame*,
Geolocation*) {}
>
> #if USE(ACCELERATED_COMPOSITING)
> - virtual void attachRootGraphicsLayer(Frame*, GraphicsLayer*) {};
> - virtual void setNeedsOneShotDrawingSynchronization() {};
> - virtual void scheduleCompositingLayerSync() {};
> + virtual void attachRootGraphicsLayer(Frame*, GraphicsLayer*) {}
> + virtual void setNeedsOneShotDrawingSynchronization() {}
> + virtual void scheduleCompositingLayerSync() {}
> +#endif
> +
> +#if ENABLE(ACCELERATED_2D_CANVAS)
> + virtual PassRefPtr<SharedContext3D> getSharedContext3D() { return 0; }
> #endif
>
> #if PLATFORM(WIN)
> diff --git a/WebCore/platform/graphics/GraphicsContext.h
b/WebCore/platform/graphics/GraphicsContext.h
> index
93ef890062eda52899e4d33dd1091a2d32f4d08c..80d1e0201461515ae9050febc4cddbb67898a
d11 100644
> --- a/WebCore/platform/graphics/GraphicsContext.h
> +++ b/WebCore/platform/graphics/GraphicsContext.h
> @@ -122,16 +122,17 @@ namespace WebCore {
> const int cMisspellingLinePatternGapWidth = 1;
>
> class AffineTransform;
> + class CanvasFramebuffer;
> class Font;
> class Generator;
> class Gradient;
> - class GraphicsContext3D;
> class GraphicsContextPlatformPrivate;
> class GraphicsContextPrivate;
> class ImageBuffer;
> class KURL;
> class Path;
> class Pattern;
> + class SharedContext3D;
> class TextRun;
>
> // These bits can be ORed together for a total of 8 possible text
drawing modes.
> @@ -412,8 +413,12 @@ namespace WebCore {
> pattern getHaikuStrokeStyle();
> #endif
>
> - void setGraphicsContext3D(GraphicsContext3D*, const IntSize&);
> +#if PLATFORM(SKIA)
> + void setSharedContext3D(SharedContext3D*, CanvasFramebuffer*, const
IntSize&);
> void syncSoftwareCanvas();
> + unsigned textureIdForCompositor() const;
> + unsigned textureIdForCanvas() const;
> +#endif
How about a comment before this block of methods indicating that they're for
accelerated 2D canvas support?
>
> private:
> void savePlatformState();
> diff --git a/WebCore/platform/graphics/GraphicsContext3D.h
b/WebCore/platform/graphics/GraphicsContext3D.h
> index
b583813886698ecb5605531be7f56b0a39d65069..009efe5d4baecba641c496abe100c70318d58
f20 100644
> --- a/WebCore/platform/graphics/GraphicsContext3D.h
> +++ b/WebCore/platform/graphics/GraphicsContext3D.h
> @@ -753,6 +753,10 @@ public:
>
> bool supportsBGRA();
>
> + unsigned createCompositorTexture(unsigned width, unsigned height);
> + void deleteCompositorTexture(unsigned compositorTexture);
> + void copyTextureToCompositor(unsigned sourceTexture, unsigned
compositorTexture);
A comment above these few methods indicating they're currently for accelerated
2d canvas support would be useful. Not sure whether it's worth #ifdef'ing them
under that flag to avoid the need to add them to all ports currently supporting
WebGL.
> +
> private:
> GraphicsContext3D(Attributes attrs, HostWindow* hostWindow);
>
> diff --git a/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp
b/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp
> new file mode 100644
> index
0000000000000000000000000000000000000000..d90b6f8b13f93eeb4e03fcfc545dd961a69e1
a4a
> --- /dev/null
> +++ b/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp
> @@ -0,0 +1,87 @@
> +/*
> + * Copyright (C) 2010 Google Inc. All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> + * met:
> + *
> + * * Redistributions of source code must retain the above copyright
> + * notice, this list of conditions and the following disclaimer.
> + * * Redistributions in binary form must reproduce the above
> + * copyright notice, this list of conditions and the following disclaimer
> + * in the documentation and/or other materials provided with the
> + * distribution.
> + * * Neither the name of Google Inc. nor the names of its
> + * contributors may be used to endorse or promote products derived from
> + * this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#include "config.h"
> +
> +#if USE(ACCELERATED_COMPOSITING)
> +
> +#include "Canvas2DLayerChromium.h"
> +
> +#include "CanvasFramebuffer.h"
> +#include "PlatformContextSkia.h"
> +
> +#include <GLES2/gl2.h>
> +
> +namespace WebCore {
> +
> +PassRefPtr<Canvas2DLayerChromium>
Canvas2DLayerChromium::create(CanvasFramebuffer* framebuffer,
GraphicsLayerChromium* owner)
> +{
> + return adoptRef(new Canvas2DLayerChromium(framebuffer, owner));
> +}
> +
> +Canvas2DLayerChromium::Canvas2DLayerChromium(CanvasFramebuffer* framebuffer,
GraphicsLayerChromium* owner)
> + : CanvasLayerChromium(owner)
> + , m_framebuffer(framebuffer)
> + , m_textureChanged(true)
> +{
> +}
> +
> +void Canvas2DLayerChromium::updateContents()
> +{
> + unsigned textureId = m_framebuffer->textureIdForCompositor();
> + if (m_textureChanged) {
> + glBindTexture(GL_TEXTURE_2D, textureId);
> + // Set the min-mag filters to linear and wrap modes to
GL_CLAMP_TO_EDGE
> + // to get around NPOT texture limitations of GLES.
> + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
> + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
> + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
> + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
> + m_textureChanged = false;
> + }
> + // Update the contents of the texture used by the compositor.
> + if (m_contentsDirty) {
> + m_framebuffer->swapBuffers();
> + m_contentsDirty = false;
> + }
> +}
> +
> +void Canvas2DLayerChromium::setCanvasFramebuffer(CanvasFramebuffer*
framebuffer)
> +{
> + m_framebuffer = framebuffer;
Do you need m_textureChanged = true here?
> +}
> +
> +unsigned Canvas2DLayerChromium::textureId()
> +{
> + return m_framebuffer->textureIdForCompositor();
> +}
> +
> +}
> +#endif // USE(ACCELERATED_COMPOSITING)
> diff --git a/WebCore/platform/graphics/chromium/GLES2Canvas.cpp
b/WebCore/platform/graphics/chromium/GLES2Canvas.cpp
> index
82d4c0b033a14f91e566f7b4eea08b06692ebbd3..e1d1967bf4c02871c4f8e71caa2a40de5468f
653 100644
> --- a/WebCore/platform/graphics/chromium/GLES2Canvas.cpp
> +++ b/WebCore/platform/graphics/chromium/GLES2Canvas.cpp
> @@ -32,10 +32,12 @@
>
> #include "GLES2Canvas.h"
>
> +#include "CanvasFramebuffer.h"
> #include "FloatRect.h"
> #include "GraphicsContext3D.h"
> #include "IntRect.h"
> #include "PlatformString.h"
> +#include "SharedContext3D.h"
> #include "SolidFillShader.h"
> #include "TexShader.h"
> #include "Texture.h"
> @@ -61,37 +63,50 @@ struct GLES2Canvas::State {
> AffineTransform m_ctm;
> };
>
> -GLES2Canvas::GLES2Canvas(GraphicsContext3D* context, const IntSize& size)
> - : m_context(context)
> +GLES2Canvas::GLES2Canvas(SharedContext3D* context, CanvasFramebuffer*
framebuffer, const IntSize& size)
> + : m_size(size)
> + , m_context(context)
> + , m_framebuffer(framebuffer)
> , m_state(0)
> - , m_quadVertices(0)
> - , m_solidFillShader(SolidFillShader::create(context))
> - , m_texShader(TexShader::create(context))
> {
> m_flipMatrix.translate(-1.0f, 1.0f);
> m_flipMatrix.scale(2.0f / size.width(), -2.0f / size.height());
>
> - m_context->reshape(size.width(), size.height());
> - m_context->viewport(0, 0, size.width(), size.height());
> -
> m_stateStack.append(State());
> m_state = &m_stateStack.last();
> -
> - // Force the source over composite mode to be applied.
> - m_lastCompositeOp = CompositeClear;
> - applyCompositeOperator(CompositeSourceOver);
> }
>
> GLES2Canvas::~GLES2Canvas()
> {
> - m_context->deleteBuffer(m_quadVertices);
> +}
> +
> +void GLES2Canvas::swapBuffers()
> +{
> + m_framebuffer->swapBuffers();
> +}
> +
> +void GLES2Canvas::bindFramebuffer()
> +{
> + m_framebuffer->bind();
> +}
> +
> +unsigned GLES2Canvas::textureIdForCompositor() const
> +{
> + return m_framebuffer->textureIdForCompositor();
> +}
> +
> +unsigned GLES2Canvas::textureIdForCanvas() const
> +{
> + return m_framebuffer->textureIdForCanvas();
> }
>
> void GLES2Canvas::clearRect(const FloatRect& rect)
> {
> + bindFramebuffer();
> if (m_state->m_ctm.isIdentity()) {
> - m_context->scissor(rect.x(), rect.y(), rect.width(), rect.height());
> + m_context->scissor(rect);
> m_context->enable(GraphicsContext3D::SCISSOR_TEST);
> + m_context->clearColor(Color(RGBA32(0)));
> m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT);
> m_context->disable(GraphicsContext3D::SCISSOR_TEST);
> } else {
> @@ -104,16 +119,17 @@ void GLES2Canvas::clearRect(const FloatRect& rect)
>
> void GLES2Canvas::fillRect(const FloatRect& rect, const Color& color,
ColorSpace colorSpace)
> {
> - applyCompositeOperator(m_state->m_compositeOp);
> -
> - m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER,
getQuadVertices());
> + m_context->applyCompositeOperator(m_state->m_compositeOp);
> + m_context->useQuadVertices();
>
> AffineTransform matrix(m_flipMatrix);
> matrix.multLeft(m_state->m_ctm);
> matrix.translate(rect.x(), rect.y());
> matrix.scale(rect.width(), rect.height());
> - m_solidFillShader->use(matrix, color);
>
> + m_context->useFillSolidProgram(color, matrix);
> +
> + bindFramebuffer();
> m_context->drawArrays(GraphicsContext3D::TRIANGLE_STRIP, 0, 4);
> }
>
> @@ -165,21 +181,33 @@ void GLES2Canvas::restore()
> m_state = &m_stateStack.last();
> }
>
> +void GLES2Canvas::drawTexturedRect(unsigned texture, const IntSize&
textureSize, const FloatRect& srcRect, const FloatRect& dstRect, ColorSpace
colorSpace, CompositeOperator compositeOp)
> +{
> + m_context->applyCompositeOperator(compositeOp);
> +
> + m_context->useQuadVertices();
> + m_context->setActiveTexture(GraphicsContext3D::TEXTURE0);
> +
> + m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, texture);
> +
> + drawQuad(textureSize, srcRect, dstRect, m_state->m_ctm,
m_state->m_alpha);
> +}
> +
> void GLES2Canvas::drawTexturedRect(Texture* texture, const FloatRect&
srcRect, const FloatRect& dstRect, ColorSpace colorSpace, CompositeOperator
compositeOp)
> {
> drawTexturedRect(texture, srcRect, dstRect, m_state->m_ctm,
m_state->m_alpha, colorSpace, compositeOp);
> }
>
> +
> void GLES2Canvas::drawTexturedRect(Texture* texture, const FloatRect&
srcRect, const FloatRect& dstRect, const AffineTransform& transform, float
alpha, ColorSpace colorSpace, CompositeOperator compositeOp)
> {
> - applyCompositeOperator(compositeOp);
> -
> - m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER,
getQuadVertices());
> - checkGLError("glBindBuffer");
> -
> + m_context->applyCompositeOperator(compositeOp);
> const TilingData& tiles = texture->tiles();
> IntRect tileIdxRect = tiles.overlappedTileIndices(srcRect);
>
> + m_context->useQuadVertices();
> + m_context->setActiveTexture(GraphicsContext3D::TEXTURE0);
> +
> for (int y = tileIdxRect.y(); y <= tileIdxRect.bottom(); y++) {
> for (int x = tileIdxRect.x(); x <= tileIdxRect.right(); x++)
> drawTexturedRectTile(texture, tiles.tileIndex(x, y), srcRect,
dstRect, transform, alpha);
> @@ -193,7 +221,6 @@ void GLES2Canvas::drawTexturedRectTile(Texture* texture,
int tile, const FloatRe
>
> const TilingData& tiles = texture->tiles();
>
> - m_context->activeTexture(GraphicsContext3D::TEXTURE0);
> texture->bindTile(tile);
>
> FloatRect srcRectClippedInTileSpace;
> @@ -202,18 +229,24 @@ void GLES2Canvas::drawTexturedRectTile(Texture*
texture, int tile, const FloatRe
>
> IntRect tileBoundsWithBorder = tiles.tileBoundsWithBorder(tile);
>
> + drawQuad(IntSize(tileBoundsWithBorder.width(),
tileBoundsWithBorder.height()), srcRectClippedInTileSpace, dstRectIntersected,
transform, alpha);
> +}
> +
> +void GLES2Canvas::drawQuad(const IntSize& textureSize, const FloatRect&
srcRect, const FloatRect& dstRect, const AffineTransform& transform, float
alpha)
> +{
> AffineTransform matrix(m_flipMatrix);
> matrix.multLeft(transform);
> - matrix.translate(dstRectIntersected.x(), dstRectIntersected.y());
> - matrix.scale(dstRectIntersected.width(), dstRectIntersected.height());
> + matrix.translate(dstRect.x(), dstRect.y());
> + matrix.scale(dstRect.width(), dstRect.height());
>
> AffineTransform texMatrix;
> - texMatrix.scale(1.0f / tileBoundsWithBorder.width(), 1.0f /
tileBoundsWithBorder.height());
> - texMatrix.translate(srcRectClippedInTileSpace.x(),
srcRectClippedInTileSpace.y());
> - texMatrix.scale(srcRectClippedInTileSpace.width(),
srcRectClippedInTileSpace.height());
> + texMatrix.scale(1.0f / textureSize.width(), 1.0f /
textureSize.height());
> + texMatrix.translate(srcRect.x(), srcRect.y());
> + texMatrix.scale(srcRect.width(), srcRect.height());
Have these changes to the math been verified?
> - m_texShader->use(matrix, texMatrix, 0, alpha);
> + bindFramebuffer();
>
> + m_context->useTextureProgram(alpha, matrix, texMatrix);
> m_context->drawArrays(GraphicsContext3D::TRIANGLE_STRIP, 0, 4);
> checkGLError("glDrawArrays");
> }
> @@ -223,98 +256,14 @@ void
GLES2Canvas::setCompositeOperation(CompositeOperator op)
> m_state->m_compositeOp = op;
> }
>
> -void GLES2Canvas::applyCompositeOperator(CompositeOperator op)
> -{
> - if (op == m_lastCompositeOp)
> - return;
> -
> - switch (op) {
> - case CompositeClear:
> - m_context->enable(GraphicsContext3D::BLEND);
> - m_context->blendFunc(GraphicsContext3D::ZERO,
GraphicsContext3D::ZERO);
> - break;
> - case CompositeCopy:
> - m_context->disable(GraphicsContext3D::BLEND);
> - break;
> - case CompositeSourceOver:
> - m_context->enable(GraphicsContext3D::BLEND);
> - m_context->blendFunc(GraphicsContext3D::ONE,
GraphicsContext3D::ONE_MINUS_SRC_ALPHA);
> - break;
> - case CompositeSourceIn:
> - m_context->enable(GraphicsContext3D::BLEND);
> - m_context->blendFunc(GraphicsContext3D::DST_ALPHA,
GraphicsContext3D::ZERO);
> - break;
> - case CompositeSourceOut:
> - m_context->enable(GraphicsContext3D::BLEND);
> - m_context->blendFunc(GraphicsContext3D::ONE_MINUS_DST_ALPHA,
GraphicsContext3D::ZERO);
> - break;
> - case CompositeSourceAtop:
> - m_context->enable(GraphicsContext3D::BLEND);
> - m_context->blendFunc(GraphicsContext3D::DST_ALPHA,
GraphicsContext3D::ONE_MINUS_SRC_ALPHA);
> - break;
> - case CompositeDestinationOver:
> - m_context->enable(GraphicsContext3D::BLEND);
> - m_context->blendFunc(GraphicsContext3D::ONE_MINUS_DST_ALPHA,
GraphicsContext3D::ONE);
> - break;
> - case CompositeDestinationIn:
> - m_context->enable(GraphicsContext3D::BLEND);
> - m_context->blendFunc(GraphicsContext3D::ZERO,
GraphicsContext3D::SRC_ALPHA);
> - break;
> - case CompositeDestinationOut:
> - m_context->enable(GraphicsContext3D::BLEND);
> - m_context->blendFunc(GraphicsContext3D::ZERO,
GraphicsContext3D::ONE_MINUS_SRC_ALPHA);
> - break;
> - case CompositeDestinationAtop:
> - m_context->enable(GraphicsContext3D::BLEND);
> - m_context->blendFunc(GraphicsContext3D::ONE_MINUS_DST_ALPHA,
GraphicsContext3D::SRC_ALPHA);
> - break;
> - case CompositeXOR:
> - m_context->enable(GraphicsContext3D::BLEND);
> - m_context->blendFunc(GraphicsContext3D::ONE_MINUS_DST_ALPHA,
GraphicsContext3D::ONE_MINUS_SRC_ALPHA);
> - break;
> - case CompositePlusDarker:
> - case CompositeHighlight:
> - // unsupported
> - m_context->disable(GraphicsContext3D::BLEND);
> - break;
> - case CompositePlusLighter:
> - m_context->enable(GraphicsContext3D::BLEND);
> - m_context->blendFunc(GraphicsContext3D::ONE,
GraphicsContext3D::ONE);
> - break;
> - }
> - m_lastCompositeOp = op;
> -}
> -
> -unsigned GLES2Canvas::getQuadVertices()
> -{
> - if (!m_quadVertices) {
> - float vertices[] = { 0.0f, 0.0f, 1.0f,
> - 1.0f, 0.0f, 1.0f,
> - 0.0f, 1.0f, 1.0f,
> - 1.0f, 1.0f, 1.0f };
> - m_quadVertices = m_context->createBuffer();
> - m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER,
m_quadVertices);
> - m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER,
sizeof(vertices), vertices, GraphicsContext3D::STATIC_DRAW);
> - }
> - return m_quadVertices;
> -}
> -
> -Texture* GLES2Canvas::createTexture(NativeImagePtr ptr, Texture::Format
format, int width, int height)
> +PassRefPtr<Texture> GLES2Canvas::createTexture(NativeImagePtr ptr,
Texture::Format format, int width, int height)
If the ownership of the Texture object is not being transferred -- and it
doesn't look like it is, since the SharedContext3D conceptually owns the
created Texture -- then this should return Texture*, not PassRefPtr<Texture>.
> {
> - PassRefPtr<Texture> texture = m_textures.get(ptr);
> - if (texture)
> - return texture.get();
> -
> - texture = Texture::create(m_context, format, width, height);
> - Texture* t = texture.get();
> - m_textures.set(ptr, texture);
> - return t;
> + return m_context->createTexture(ptr, format, width, height);
> }
>
> -Texture* GLES2Canvas::getTexture(NativeImagePtr ptr)
> +PassRefPtr<Texture> GLES2Canvas::getTexture(NativeImagePtr ptr)
Similar ownership issue here -- this should return Texture*.
> {
> - PassRefPtr<Texture> texture = m_textures.get(ptr);
> - return texture ? texture.get() : 0;
> + return m_context->getTexture(ptr);
> }
>
> void GLES2Canvas::checkGLError(const char* header)
> diff --git a/WebCore/platform/graphics/chromium/GLES2Canvas.h
b/WebCore/platform/graphics/chromium/GLES2Canvas.h
> index
f49ac8ba18d1d34234b8d06278e7028bfe9697e1..af3c0538f05f4072e20d173fe023b03926f6a
69c 100644
> --- a/WebCore/platform/graphics/chromium/GLES2Canvas.h
> +++ b/WebCore/platform/graphics/chromium/GLES2Canvas.h
> @@ -44,17 +44,15 @@
>
> namespace WebCore {
>
> +class CanvasFramebuffer;
> +class SharedContext3D;
> class Color;
> class FloatRect;
> class GraphicsContext3D;
> -class SolidFillShader;
> -class TexShader;
> -
> -typedef HashMap<NativeImagePtr, RefPtr<Texture> > TextureHashMap;
>
> class GLES2Canvas : public Noncopyable {
> public:
> - GLES2Canvas(GraphicsContext3D*, const IntSize&);
> + GLES2Canvas(SharedContext3D*, CanvasFramebuffer*, const IntSize&);
> ~GLES2Canvas();
>
> void fillRect(const FloatRect&, const Color&, ColorSpace);
> @@ -74,28 +72,35 @@ public:
> // non-standard functions
> // These are not standard GraphicsContext functions, and should be
pushed
> // down into a PlatformContextGLES2 at some point.
> + void drawTexturedRect(unsigned texture, const IntSize& textureSize,
const FloatRect& srcRect, const FloatRect& dstRect, ColorSpace,
CompositeOperator);
> void drawTexturedRect(Texture*, const FloatRect& srcRect, const
FloatRect& dstRect, const AffineTransform&, float alpha, ColorSpace,
CompositeOperator);
> void drawTexturedRect(Texture*, const FloatRect& srcRect, const
FloatRect& dstRect, ColorSpace, CompositeOperator);
> - GraphicsContext3D* context() { return m_context; }
> - Texture* createTexture(NativeImagePtr, Texture::Format, int width, int
height);
> - Texture* getTexture(NativeImagePtr);
> + PassRefPtr<Texture> createTexture(NativeImagePtr, Texture::Format, int
width, int height);
> + PassRefPtr<Texture> getTexture(NativeImagePtr);
These should return Texture*.
> +
> + SharedContext3D* context() const { return m_context; }
> +
> + void swapBuffers();
> + void bindFramebuffer();
> +
> + unsigned textureIdForCompositor() const;
> + unsigned textureIdForCanvas() const;
>
> private:
> void drawTexturedRectTile(Texture* texture, int tile, const FloatRect&
srcRect, const FloatRect& dstRect, const AffineTransform&, float alpha);
> + void drawQuad(const IntSize& textureSize, const FloatRect& srcRect,
const FloatRect& dstRect, const AffineTransform&, float alpha);
> void applyCompositeOperator(CompositeOperator);
> void checkGLError(const char* header);
> - unsigned getQuadVertices();
>
> - GraphicsContext3D* m_context;
> + IntSize m_size;
> +
> + SharedContext3D* m_context;
> + CanvasFramebuffer* m_framebuffer;
> +
> struct State;
> WTF::Vector<State> m_stateStack;
> State* m_state;
> - unsigned m_quadVertices;
> - OwnPtr<SolidFillShader> m_solidFillShader;
> - OwnPtr<TexShader> m_texShader;
> AffineTransform m_flipMatrix;
> - TextureHashMap m_textures;
> - CompositeOperator m_lastCompositeOp; // This is the one last set, not
necessarily the one in the state stack.
> };
>
> }
> diff --git a/WebCore/platform/graphics/gpu/CanvasFramebuffer.cpp
b/WebCore/platform/graphics/gpu/CanvasFramebuffer.cpp
> new file mode 100644
> index
0000000000000000000000000000000000000000..fe4ddb471e222f853566bfc456f1e183adb7e
969
> --- /dev/null
> +++ b/WebCore/platform/graphics/gpu/CanvasFramebuffer.cpp
> @@ -0,0 +1,110 @@
> +/*
> + * Copyright (c) 2010, Google Inc. All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> + * met:
> + *
> + * * Redistributions of source code must retain the above copyright
> + * notice, this list of conditions and the following disclaimer.
> + * * Redistributions in binary form must reproduce the above
> + * copyright notice, this list of conditions and the following disclaimer
> + * in the documentation and/or other materials provided with the
> + * distribution.
> + * * Neither the name of Google Inc. nor the names of its
> + * contributors may be used to endorse or promote products derived from
> + * this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#include "config.h"
> +
> +#include "CanvasFramebuffer.h"
> +
> +#include "GraphicsContext3D.h"
> +#include "SharedContext3D.h"
> +
> +namespace WebCore {
> +
> +CanvasFramebuffer::CanvasFramebuffer(SharedContext3D* context, const
IntSize& size, unsigned framebuffer, unsigned offscreenColorTexture, unsigned
offscreenParentColorTexture)
> + : m_context(context)
> + , m_size(size)
> + , m_framebuffer(framebuffer)
> + , m_offscreenColorTexture(offscreenColorTexture)
> + , m_offscreenParentColorTexture(offscreenParentColorTexture)
> +{
> +}
> +
> +CanvasFramebuffer::~CanvasFramebuffer()
> +{
> + m_context->deleteTexture(m_offscreenColorTexture);
> + m_context->deleteCompositorTexture(m_offscreenParentColorTexture);
> + m_context->deleteFramebuffer(m_framebuffer);
> +}
> +
> +void CanvasFramebuffer::bind()
> +{
> + m_context->bindFramebuffer(m_framebuffer);
> + m_context->setViewport(m_size);
> +}
> +
> +void CanvasFramebuffer::swapBuffers()
> +{
> + if (m_willSwapBuffersCallback)
> + m_willSwapBuffersCallback->willSwapBuffers();
> + m_context->setViewport(m_size);
> + m_context->copyTextureToCompositor(m_offscreenColorTexture,
m_offscreenParentColorTexture);
> +}
> +
> +void
CanvasFramebuffer::setWillSwapBuffersCallback(PassOwnPtr<SwapBuffersCallback>
callback)
> +{
> + m_willSwapBuffersCallback = callback;
> +}
> +
> +PassOwnPtr<CanvasFramebuffer> CanvasFramebuffer::create(SharedContext3D*
context, const IntSize& size)
> +{
> + unsigned framebuffer = context->createFramebuffer();
> + ASSERT(framebuffer);
> + if (!framebuffer)
> + return 0;
> + context->bindFramebuffer(framebuffer);
> +
> + // Color texture
> + unsigned offscreenColorTexture = context->createTexture();
> + ASSERT(offscreenColorTexture);
> + if (!offscreenColorTexture) {
> + context->deleteFramebuffer(framebuffer);
> + return 0;
> + }
> + context->bindTexture(GraphicsContext3D::TEXTURE_2D,
offscreenColorTexture);
> + context->texParameteri(GraphicsContext3D::TEXTURE_2D,
GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::NEAREST);
> + context->texParameteri(GraphicsContext3D::TEXTURE_2D,
GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::NEAREST);
> + context->texParameteri(GraphicsContext3D::TEXTURE_2D,
GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE);
> + context->texParameteri(GraphicsContext3D::TEXTURE_2D,
GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE);
> + context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0,
GraphicsContext3D::RGBA, size.width(), size.height(), 0,
GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, 0);
> +
> + unsigned offscreenParentColorTexture =
context->createCompositorTexture(size);
> + ASSERT(offscreenParentColorTexture);
> + if (!offscreenParentColorTexture) {
> + context->deleteTexture(offscreenColorTexture);
> + context->deleteFramebuffer(framebuffer);
> + return 0;
> + }
> +
> + context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER,
GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D,
offscreenColorTexture, 0);
> +
> + return new CanvasFramebuffer(context, size, framebuffer,
offscreenColorTexture, offscreenParentColorTexture);
return adoptPtr(new CanvasFrameBuffer(...));
> +}
> +
> +} // namespace WebCore
> diff --git a/WebCore/platform/graphics/gpu/SharedContext3D.cpp
b/WebCore/platform/graphics/gpu/SharedContext3D.cpp
> new file mode 100644
> index
0000000000000000000000000000000000000000..3b738f01f7281392937fed5e0df257cc9cfb9
2f4
> --- /dev/null
> +++ b/WebCore/platform/graphics/gpu/SharedContext3D.cpp
> @@ -0,0 +1,325 @@
> +/*
> + * Copyright (c) 2010, Google Inc. All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> + * met:
> + *
> + * * Redistributions of source code must retain the above copyright
> + * notice, this list of conditions and the following disclaimer.
> + * * Redistributions in binary form must reproduce the above
> + * copyright notice, this list of conditions and the following disclaimer
> + * in the documentation and/or other materials provided with the
> + * distribution.
> + * * Neither the name of Google Inc. nor the names of its
> + * contributors may be used to endorse or promote products derived from
> + * this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#include "config.h"
> +
> +#include "SharedContext3D.h"
> +
> +#include "AffineTransform.h"
> +#include "CanvasFramebuffer.h"
> +#include "Color.h"
> +#include "FloatRect.h"
> +#include "GraphicsContext3D.h"
> +#include "GraphicsTypes.h"
> +#include "IntSize.h"
> +#include "SolidFillShader.h"
> +#include "TexShader.h"
> +
> +#include <wtf/text/CString.h>
> +#include <wtf/text/WTFString.h>
> +
> +namespace WebCore {
> +
> +static inline void affineTo3x3(const AffineTransform& transform, float
mat[9])
> +{
> + mat[0] = transform.a();
> + mat[1] = transform.b();
> + mat[2] = 0.0f;
> + mat[3] = transform.c();
> + mat[4] = transform.d();
> + mat[5] = 0.0f;
> + mat[6] = transform.e();
> + mat[7] = transform.f();
> + mat[8] = 1.0f;
> +}
> +
> +// static
> +PassRefPtr<SharedContext3D>
SharedContext3D::create(PassOwnPtr<GraphicsContext3D> context)
> +{
> + return adoptRef(new SharedContext3D(context));
> +}
> +
> +SharedContext3D::SharedContext3D(PassOwnPtr<GraphicsContext3D> context)
> + : m_context(context)
> + , m_quadVertices(0)
> + , m_solidFillShader(SolidFillShader::create(m_context.get()))
> + , m_texShader(TexShader::create(m_context.get()))
> +
> +{
> +}
> +
> +SharedContext3D::~SharedContext3D()
> +{
> + m_context->deleteBuffer(m_quadVertices);
> +}
> +
> +void SharedContext3D::scissor(const FloatRect& rect)
> +{
> + m_context->scissor(rect.x(), rect.y(), rect.width(), rect.height());
> +}
> +
> +void SharedContext3D::enable(unsigned capacity)
> +{
> + m_context->enable(capacity);
> +}
> +
> +void SharedContext3D::disable(unsigned capacity)
> +{
> + m_context->disable(capacity);
> +}
> +
> +void SharedContext3D::clearColor(const Color& color)
> +{
> + float rgba[4];
> + color.getRGBA(rgba[0], rgba[1], rgba[2], rgba[3]);
> + m_context->clearColor(rgba[0], rgba[1], rgba[2], rgba[3]);
> +}
> +
> +void SharedContext3D::clear(unsigned mask)
> +{
> + m_context->clear(mask);
> +}
> +
> +void SharedContext3D::drawArrays(unsigned long mode, long first, long count)
> +{
> + m_context->drawArrays(mode, first, count);
> +}
> +
> +unsigned long SharedContext3D::getError()
> +{
> + return m_context->getError();
> +}
> +
> +void SharedContext3D::getIntegerv(unsigned long pname, int* value)
> +{
> + m_context->getIntegerv(pname, value);
> +}
> +
> +unsigned SharedContext3D::createFramebuffer()
> +{
> + return m_context->createFramebuffer();
> +}
> +
> +unsigned SharedContext3D::createTexture()
> +{
> + return m_context->createTexture();
> +}
> +
> +void SharedContext3D::deleteFramebuffer(unsigned framebuffer)
> +{
> + m_context->deleteFramebuffer(framebuffer);
> +}
> +
> +void SharedContext3D::deleteTexture(unsigned texture)
> +{
> + m_context->deleteTexture(texture);
> +}
> +
> +void SharedContext3D::deleteCompositorTexture(unsigned texture)
> +{
> + m_context->deleteCompositorTexture(texture);
> +}
> +
> +void SharedContext3D::framebufferTexture2D(unsigned long target, unsigned
long attachment, unsigned long textarget, unsigned texture, long level)
> +{
> + m_context->framebufferTexture2D(target, attachment, textarget, texture,
level);
> +}
> +
> +void SharedContext3D::texParameteri(unsigned target, unsigned pname, int
param)
> +{
> + m_context->texParameteri(target, pname, param);
> +}
> +
> +int SharedContext3D::texImage2D(unsigned target, unsigned level, unsigned
internalformat, unsigned width, unsigned height, unsigned border, unsigned
format, unsigned type, void* pixels)
> +{
> + m_context->texImage2D(target, level, internalformat, width, height,
border, format, type, pixels);
> +}
> +
> +int SharedContext3D::texSubImage2D(unsigned target, unsigned level, unsigned
xoffset, unsigned yoffset, unsigned width, unsigned height, unsigned format,
unsigned type, void* pixels)
> +{
> + m_context->texSubImage2D(target, level, xoffset, yoffset, width, height,
format, type, pixels);
> +}
> +
> +void SharedContext3D::readPixels(long x, long y, unsigned long width,
unsigned long height, unsigned long format, unsigned long type, void* data)
> +{
> + m_context->readPixels(x, y, width, height, format, type, data);
> +}
> +
> +PassRefPtr<Texture> SharedContext3D::createTexture(NativeImagePtr ptr,
Texture::Format format, int width, int height)
Since this class owns the Texture objects (ownership is not being transferred),
this should return Texture*, not PassRefPtr<Texture>.
> +{
> + RefPtr<Texture> texture;
> + if (ptr)
> + texture = m_textures.get(ptr);
> + if (texture)
> + return texture.get();
> +
> + texture = Texture::create(m_context.get(), format, width, height);
> + Texture* t = texture.get();
> + if (ptr)
> + m_textures.set(ptr, texture);
> + return t;
> +}
> +
> +PassRefPtr<Texture> SharedContext3D::getTexture(NativeImagePtr ptr)
Should return Texture*.
> +{
> + RefPtr<Texture> texture = m_textures.get(ptr);
> + return texture ? texture.get() : 0;
> +}
> +
> +
> +void SharedContext3D::applyCompositeOperator(CompositeOperator op)
> +{
> + switch (op) {
> + case CompositeClear:
> + m_context->enable(GraphicsContext3D::BLEND);
> + m_context->blendFunc(GraphicsContext3D::ZERO,
GraphicsContext3D::ZERO);
> + break;
> + case CompositeCopy:
> + m_context->disable(GraphicsContext3D::BLEND);
> + break;
> + case CompositeSourceOver:
> + m_context->enable(GraphicsContext3D::BLEND);
> + m_context->blendFunc(GraphicsContext3D::ONE,
GraphicsContext3D::ONE_MINUS_SRC_ALPHA);
> + break;
> + case CompositeSourceIn:
> + m_context->enable(GraphicsContext3D::BLEND);
> + m_context->blendFunc(GraphicsContext3D::DST_ALPHA,
GraphicsContext3D::ZERO);
> + break;
> + case CompositeSourceOut:
> + m_context->enable(GraphicsContext3D::BLEND);
> + m_context->blendFunc(GraphicsContext3D::ONE_MINUS_DST_ALPHA,
GraphicsContext3D::ZERO);
> + break;
> + case CompositeSourceAtop:
> + m_context->enable(GraphicsContext3D::BLEND);
> + m_context->blendFunc(GraphicsContext3D::DST_ALPHA,
GraphicsContext3D::ONE_MINUS_SRC_ALPHA);
> + break;
> + case CompositeDestinationOver:
> + m_context->enable(GraphicsContext3D::BLEND);
> + m_context->blendFunc(GraphicsContext3D::ONE_MINUS_DST_ALPHA,
GraphicsContext3D::ONE);
> + break;
> + case CompositeDestinationIn:
> + m_context->enable(GraphicsContext3D::BLEND);
> + m_context->blendFunc(GraphicsContext3D::ZERO,
GraphicsContext3D::SRC_ALPHA);
> + break;
> + case CompositeDestinationOut:
> + m_context->enable(GraphicsContext3D::BLEND);
> + m_context->blendFunc(GraphicsContext3D::ZERO,
GraphicsContext3D::ONE_MINUS_SRC_ALPHA);
> + break;
> + case CompositeDestinationAtop:
> + m_context->enable(GraphicsContext3D::BLEND);
> + m_context->blendFunc(GraphicsContext3D::ONE_MINUS_DST_ALPHA,
GraphicsContext3D::SRC_ALPHA);
> + break;
> + case CompositeXOR:
> + m_context->enable(GraphicsContext3D::BLEND);
> + m_context->blendFunc(GraphicsContext3D::ONE_MINUS_DST_ALPHA,
GraphicsContext3D::ONE_MINUS_SRC_ALPHA);
> + break;
> + case CompositePlusDarker:
> + case CompositeHighlight:
> + // unsupported
> + m_context->disable(GraphicsContext3D::BLEND);
> + break;
> + case CompositePlusLighter:
> + m_context->enable(GraphicsContext3D::BLEND);
> + m_context->blendFunc(GraphicsContext3D::ONE,
GraphicsContext3D::ONE);
> + break;
> + }
> +}
> +
> +void SharedContext3D::useQuadVertices()
> +{
> + if (!m_quadVertices) {
> + float vertices[] = { 0.0f, 0.0f, 1.0f,
> + 1.0f, 0.0f, 1.0f,
> + 0.0f, 1.0f, 1.0f,
> + 1.0f, 1.0f, 1.0f };
> + m_quadVertices = m_context->createBuffer();
> + m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER,
m_quadVertices);
> + m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER,
sizeof(vertices), vertices, GraphicsContext3D::STATIC_DRAW);
> + } else {
> + m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER,
m_quadVertices);
> + }
> +}
> +
> +void SharedContext3D::setActiveTexture(unsigned textureUnit)
> +{
> + m_context->activeTexture(textureUnit);
> +}
> +
> +void SharedContext3D::bindTexture(unsigned target, unsigned texture)
> +{
> + if (target != GraphicsContext3D::TEXTURE_2D) {
> + m_context->bindTexture(target, texture);
> + return;
> + }
> +
> + m_context->bindTexture(target, texture);
> +}
> +
> +void SharedContext3D::useFillSolidProgram(const Color& color, const
AffineTransform& transform)
> +{
> + m_solidFillShader->use(transform, color);
> +}
> +
> +void SharedContext3D::useTextureProgram(float alpha, const AffineTransform&
transform, const AffineTransform& texTransform)
> +{
> + m_texShader->use(transform, texTransform, 0, alpha);
> +}
> +
> +void SharedContext3D::bindFramebuffer(unsigned framebuffer)
> +{
> + m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, framebuffer);
> +}
> +
> +void SharedContext3D::setViewport(const IntSize& size)
> +{
> + m_context->viewport(0, 0, size.width(), size.height());
> +}
> +
> +bool SharedContext3D::supportsBGRA()
> +{
> + return m_context->supportsBGRA();
> +}
> +
> +unsigned SharedContext3D::createCompositorTexture(const IntSize& size)
> +{
> + return m_context->createCompositorTexture(size.width(), size.height());
> +}
> +
> +void SharedContext3D::copyTextureToCompositor(unsigned source, unsigned
destination)
> +{
> + m_context->copyTextureToCompositor(source, destination);
> +}
> +
> +bool SharedContext3D::paintsIntoCanvasBuffer() const
> +{
> + return m_context->paintsIntoCanvasBuffer();
> +}
> +
> +} // namespace WebCore
> diff --git a/WebCore/platform/graphics/gpu/SharedContext3D.h
b/WebCore/platform/graphics/gpu/SharedContext3D.h
> new file mode 100644
> index
0000000000000000000000000000000000000000..8abcb316dd27b98e7a4684adec208587adcbb
f8f
> --- /dev/null
> +++ b/WebCore/platform/graphics/gpu/SharedContext3D.h
> @@ -0,0 +1,121 @@
> +/*
> + * Copyright (c) 2010, Google Inc. All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> + * met:
> + *
> + * * Redistributions of source code must retain the above copyright
> + * notice, this list of conditions and the following disclaimer.
> + * * Redistributions in binary form must reproduce the above
> + * copyright notice, this list of conditions and the following disclaimer
> + * in the documentation and/or other materials provided with the
> + * distribution.
> + * * Neither the name of Google Inc. nor the names of its
> + * contributors may be used to endorse or promote products derived from
> + * this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#ifndef SharedContext3D_h
> +#define SharedContext3D_h
> +
> +#include "GraphicsTypes.h"
> +#include "ImageSource.h"
> +#include "Texture.h"
> +
> +#include <wtf/HashMap.h>
> +#include <wtf/OwnPtr.h>
> +#include <wtf/RefCounted.h>
> +#include <wtf/RefPtr.h>
> +
> +namespace WebCore {
> +
> +class AffineTransform;
> +class CanvasFramebuffer;
> +class Color;
> +class GraphicsContext3D;
> +class FloatRect;
> +class IntSize;
> +class SolidFillShader;
> +class TexShader;
> +
> +typedef HashMap<NativeImagePtr, RefPtr<Texture> > TextureHashMap;
> +
> +class SharedContext3D : public RefCounted<SharedContext3D> {
> +public:
> + static PassRefPtr<SharedContext3D>
create(PassOwnPtr<GraphicsContext3D>);
> + ~SharedContext3D();
> +
> + // Functions that delegate directly to GraphicsContext3D, with caching
> + void bindFramebuffer(unsigned framebuffer);
> + void setViewport(const IntSize&);
> + void scissor(const FloatRect&);
> + void enable(unsigned capacity);
> + void disable(unsigned capacity);
> + void clearColor(const Color&);
> + void clear(unsigned mask);
> + void drawArrays(unsigned long mode, long first, long count);
> + unsigned long getError();
> + void getIntegerv(unsigned long pname, int* value);
> +
> + unsigned createFramebuffer();
> + unsigned createTexture();
> +
> + void deleteFramebuffer(unsigned framebuffer);
> + void deleteTexture(unsigned texture);
> + void deleteCompositorTexture(unsigned texture);
> +
> + void framebufferTexture2D(unsigned long target, unsigned long
attachment, unsigned long textarget, unsigned, long level);
> + void texParameteri(unsigned target, unsigned pname, int param);
> + int texImage2D(unsigned target, unsigned level, unsigned internalformat,
unsigned width, unsigned height, unsigned border, unsigned format, unsigned
type, void* pixels);
> + int texSubImage2D(unsigned target, unsigned level, unsigned xoffset,
unsigned yoffset, unsigned width, unsigned height, unsigned format, unsigned
type, void* pixels);
> +
> + void readPixels(long x, long y, unsigned long width, unsigned long
height, unsigned long format, unsigned long type, void* data);
> +
> + bool supportsBGRA();
> + unsigned createCompositorTexture(const IntSize&);
> + void copyTextureToCompositor(unsigned, unsigned);
> +
> + bool paintsIntoCanvasBuffer() const;
> +
> + // Shared logic for canvas 2d
> + void applyCompositeOperator(CompositeOperator);
> + void useQuadVertices();
> +
> + void useFillSolidProgram(const Color&, const AffineTransform&);
> + void useTextureProgram(float alpha, const AffineTransform&, const
AffineTransform&);
> +
> + void setActiveTexture(unsigned textureUnit);
> + void bindTexture(unsigned target, unsigned texture);
> +
> + PassRefPtr<Texture> createTexture(NativeImagePtr, Texture::Format, int
width, int height);
> + PassRefPtr<Texture> getTexture(NativeImagePtr);
Should return Texture*, not PassRefPtr<Texture>.
> +
> +private:
> + SharedContext3D(PassOwnPtr<GraphicsContext3D> context);
> +
> + OwnPtr<GraphicsContext3D> m_context;
> +
> + unsigned m_quadVertices;
> +
> + OwnPtr<SolidFillShader> m_solidFillShader;
> + OwnPtr<TexShader> m_texShader;
> +
> + TextureHashMap m_textures;
> +};
> +
> +} // namespace WebCore
> +
> +#endif // SharedContext3D_h
> diff --git a/WebCore/platform/graphics/skia/ImageSkia.cpp
b/WebCore/platform/graphics/skia/ImageSkia.cpp
> index
aed289fe3c155aa5d3596d494b60893e4c016bb6..c517a8a808ba9f6efb0b821ef158dc4ddb99e
73f 100644
> --- a/WebCore/platform/graphics/skia/ImageSkia.cpp
> +++ b/WebCore/platform/graphics/skia/ImageSkia.cpp
> @@ -47,6 +47,7 @@
> #include "SkRect.h"
> #include "SkShader.h"
> #include "SkiaUtils.h"
> +#include "Texture.h"
>
> #include "skia/ext/image_operations.h"
> #include "skia/ext/platform_canvas.h"
> @@ -411,7 +412,7 @@ static void drawBitmapGLES2(GraphicsContext* ctxt,
NativeImageSkia* bitmap, cons
> {
> ctxt->platformContext()->prepareForHardwareDraw();
> GLES2Canvas* gpuCanvas = ctxt->platformContext()->gpuCanvas();
> - Texture* texture = gpuCanvas->getTexture(bitmap);
> + RefPtr<Texture> texture = gpuCanvas->getTexture(bitmap);
Because getTexture() will no longer return PassRefPtr, this doesn't need to
change.
> if (!texture) {
> ASSERT(bitmap->config() == SkBitmap::kARGB_8888_Config);
> ASSERT(bitmap->rowBytes() == bitmap->width() * 4);
> @@ -420,7 +421,7 @@ static void drawBitmapGLES2(GraphicsContext* ctxt,
NativeImageSkia* bitmap, cons
> ASSERT(bitmap->getPixels());
> texture->load(bitmap->getPixels());
> }
> - gpuCanvas->drawTexturedRect(texture, srcRect, dstRect, styleColorSpace,
compositeOp);
> + gpuCanvas->drawTexturedRect(texture.get(), srcRect, dstRect,
styleColorSpace, compositeOp);
Same here.
> }
>
> // ================================================
> diff --git a/WebKit/chromium/src/ChromeClientImpl.cpp
b/WebKit/chromium/src/ChromeClientImpl.cpp
> index
e6f14007180d8d3bf6128b130dc28abaaec1f90a..42424453c34691358b8371d2d7f0d3a49c283
4bb 100644
> --- a/WebKit/chromium/src/ChromeClientImpl.cpp
> +++ b/WebKit/chromium/src/ChromeClientImpl.cpp
> @@ -59,6 +59,7 @@
> #include "SearchPopupMenuChromium.h"
> #include "ScriptController.h"
> #include "SecurityOrigin.h"
> +#include "SharedContext3D.h"
> #include "WebGeolocationService.h"
> #if USE(V8)
> #include "V8Proxy.h"
> @@ -751,6 +752,11 @@ void ChromeClientImpl::scheduleCompositingLayerSync()
> }
> #endif
>
> +PassRefPtr<WebCore::SharedContext3D> ChromeClientImpl::getSharedContext3D()
See below about lack of ownership transfer.
> +{
> + return m_webView->getSharedContext3D();
> +}
> +
> bool ChromeClientImpl::supportsFullscreenForNode(const WebCore::Node* node)
> {
> if (m_webView->client() &&
node->hasTagName(WebCore::HTMLNames::videoTag))
> diff --git a/WebKit/chromium/src/ChromeClientImpl.h
b/WebKit/chromium/src/ChromeClientImpl.h
> index
bff9f9047fa7c7f3abd704d94785d9c1facf7740..53db94f79af605fc0c9c09a21fb329375dc5f
97e 100644
> --- a/WebKit/chromium/src/ChromeClientImpl.h
> +++ b/WebKit/chromium/src/ChromeClientImpl.h
> @@ -152,6 +152,8 @@ public:
> virtual void scheduleCompositingLayerSync();
> #endif
>
> + virtual PassRefPtr<WebCore::SharedContext3D> getSharedContext3D();
Because ownership isn't being transferred, this should return
WebCore::SharedContext3D* rather than PassRefPtr<...>.
> +
> virtual bool supportsFullscreenForNode(const WebCore::Node*);
> virtual void enterFullscreenForNode(WebCore::Node*);
> virtual void exitFullscreenForNode(WebCore::Node*);
> diff --git a/WebKit/chromium/src/WebViewImpl.cpp
b/WebKit/chromium/src/WebViewImpl.cpp
> index
5065f5eb9b64083fc3b1e174f42815c5737b4839..d2331a3f3e5ab62e3a7d554cd7dd848c2090c
e6d 100644
> --- a/WebKit/chromium/src/WebViewImpl.cpp
> +++ b/WebKit/chromium/src/WebViewImpl.cpp
> @@ -58,6 +58,7 @@
> #include "GLES2Context.h"
> #include "GLES2ContextInternal.h"
> #include "GraphicsContext.h"
> +#include "GraphicsContext3D.h"
> #include "HTMLInputElement.h"
> #include "HTMLMediaElement.h"
> #include "HitTestResult.h"
> @@ -86,6 +87,7 @@
> #include "SecurityOrigin.h"
> #include "SelectionController.h"
> #include "Settings.h"
> +#include "SharedContext3D.h"
> #include "Timer.h"
> #include "TypingCommand.h"
> #include "UserGestureIndicator.h"
> @@ -2211,14 +2213,16 @@ PassOwnPtr<GLES2Context>
WebViewImpl::getOnscreenGLES2Context()
> return GLES2Context::create(GLES2ContextInternal::create(gles2Context(),
false));
> }
>
> -PassOwnPtr<GLES2Context> WebViewImpl::getOffscreenGLES2Context()
> +PassRefPtr<SharedContext3D> WebViewImpl::getSharedContext3D()
Should return SharedContext3D* since ownership is not being transferred.
> {
> - WebGLES2Context* context = webKitClient()->createGLES2Context();
> - if (!context)
> - return 0;
> - if (!context->initialize(0, gles2Context()))
> - return 0;
> - return GLES2Context::create(GLES2ContextInternal::create(context,
true));
> + if (!m_sharedContext3D) {
> + GraphicsContext3D::Attributes attr;
> + attr.stencil = true;
> + OwnPtr<GraphicsContext3D> context = GraphicsContext3D::create(attr,
m_page->chrome());
> + m_sharedContext3D = SharedContext3D::create(context.release());
> + }
> +
> + return m_sharedContext3D;
> }
>
> // Returns the GLES2 context associated with this View. If one doesn't exist
> diff --git a/WebKit/chromium/src/WebViewImpl.h
b/WebKit/chromium/src/WebViewImpl.h
> index
c29612123f4514c94dd7d970c73114a4beeec355..4ad74fb12da3ff55f8c82ed22a0e3a89ff1ba
2fd 100644
> --- a/WebKit/chromium/src/WebViewImpl.h
> +++ b/WebKit/chromium/src/WebViewImpl.h
> @@ -329,10 +329,10 @@ public:
> // Offscreen contexts render offscreen but can share resources with the
> // onscreen context and thus can be composited.
> PassOwnPtr<WebCore::GLES2Context> getOnscreenGLES2Context();
> - PassOwnPtr<WebCore::GLES2Context> getOffscreenGLES2Context();
>
> // Returns an onscreen context
> virtual WebGLES2Context* gles2Context();
> + virtual PassRefPtr<WebCore::SharedContext3D> getSharedContext3D();
SharedContext3D*.
>
> WebCore::PopupContainer* selectPopup() const { return
m_selectPopup.get(); }
>
> @@ -521,6 +521,8 @@ private:
>
> OwnPtr<WebGLES2Context> m_gles2Context;
>
> + RefPtr<WebCore::SharedContext3D> m_sharedContext3D;
> +
> OwnPtr<DeviceOrientationClientProxy> m_deviceOrientationClientProxy;
> };
>
More information about the webkit-reviews
mailing list