Title: [92908] trunk/Source
Revision
92908
Author
[email protected]
Date
2011-08-11 20:32:16 -0700 (Thu, 11 Aug 2011)

Log Message

Readback composited webgl results for printing
https://bugs.webkit.org/show_bug.cgi?id=65658

Patch by John Bauman <[email protected]> on 2011-08-11
Reviewed by James Robinson.

Source/WebCore:

The real composited results may be locked inside the compositor
context's version of a texture because the drawing buffer was
automatically cleared, so read from there to get the actual presented
version to draw.

* html/canvas/WebGLRenderingContext.cpp:
(WebCore::WebGLRenderingContext::paintRenderingResultsToCanvas):
* platform/graphics/GraphicsContext3D.h:
* platform/graphics/chromium/Extensions3DChromium.h:
* platform/graphics/chromium/WebGLLayerChromium.cpp:
(WebCore::WebGLLayerChromium::paintRenderedResultsToCanvas):
* platform/graphics/chromium/WebGLLayerChromium.h:
* platform/graphics/opengl/GraphicsContext3DOpenGL.cpp:
(WebCore::GraphicsContext3D::paintCompositedResultsToCanvas):

Source/WebKit/chromium:

Add support for reading from the composited version of a canvas.

* public/WebGraphicsContext3D.h:
* src/Extensions3DChromium.cpp:
(WebCore::Extensions3DChromium::paintFramebufferToCanvas):
* src/GraphicsContext3DChromium.cpp:
(WebCore::GraphicsContext3DInternal::GraphicsContext3DInternal):
(WebCore::GraphicsContext3DInternal::paintFramebufferToCanvas):
(WebCore::GraphicsContext3DInternal::paintRenderingResultsToCanvas):
(WebCore::GraphicsContext3DInternal::paintCompositedResultsToCanvas):
(WebCore::GraphicsContext3DInternal::paintRenderingResultsToImageData):
(WebCore::GraphicsContext3DInternal::reshape):
* src/GraphicsContext3DInternal.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (92907 => 92908)


--- trunk/Source/WebCore/ChangeLog	2011-08-12 03:14:32 UTC (rev 92907)
+++ trunk/Source/WebCore/ChangeLog	2011-08-12 03:32:16 UTC (rev 92908)
@@ -1,3 +1,25 @@
+2011-08-11  John Bauman  <[email protected]>
+
+        Readback composited webgl results for printing
+        https://bugs.webkit.org/show_bug.cgi?id=65658
+
+        Reviewed by James Robinson.
+
+        The real composited results may be locked inside the compositor
+        context's version of a texture because the drawing buffer was
+        automatically cleared, so read from there to get the actual presented
+        version to draw.
+
+        * html/canvas/WebGLRenderingContext.cpp:
+        (WebCore::WebGLRenderingContext::paintRenderingResultsToCanvas):
+        * platform/graphics/GraphicsContext3D.h:
+        * platform/graphics/chromium/Extensions3DChromium.h:
+        * platform/graphics/chromium/WebGLLayerChromium.cpp:
+        (WebCore::WebGLLayerChromium::paintRenderedResultsToCanvas):
+        * platform/graphics/chromium/WebGLLayerChromium.h:
+        * platform/graphics/opengl/GraphicsContext3DOpenGL.cpp:
+        (WebCore::GraphicsContext3D::paintCompositedResultsToCanvas):
+
 2011-08-11  Andrew Wason  <[email protected]>
 
         REGRESSION: Qt _javascript_ bridge signal connection fails

Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp (92907 => 92908)


--- trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp	2011-08-12 03:14:32 UTC (rev 92907)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp	2011-08-12 03:32:16 UTC (rev 92908)
@@ -566,9 +566,10 @@
 {
     // Until the canvas is written to by the application, the clear that
     // happened after it was composited should be ignored by the compositor.
-    if (m_context->layerComposited() && !m_attributes.preserveDrawingBuffer)
+    if (m_context->layerComposited() && !m_attributes.preserveDrawingBuffer) {
+        m_context->paintCompositedResultsToCanvas(this);
         canvas()->makePresentationCopy();
-    else
+    } else
         canvas()->clearPresentationCopy();
     clearIfComposited();
     if (!m_markedCanvasDirty && !m_layerCleared)

Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h (92907 => 92908)


--- trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h	2011-08-12 03:14:32 UTC (rev 92907)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h	2011-08-12 03:32:16 UTC (rev 92908)
@@ -96,6 +96,7 @@
 #endif
 class HostWindow;
 class Image;
+class ImageBuffer;
 class ImageData;
 #if USE(CAIRO)
 class PlatformContextCairo;
@@ -780,8 +781,8 @@
     void reshape(int width, int height);
 
 #if USE(CG)
-    void paintToCanvas(const unsigned char* imagePixels, int imageWidth, int imageHeight,
-                       int canvasWidth, int canvasHeight, CGContextRef context);
+    static void paintToCanvas(const unsigned char* imagePixels, int imageWidth, int imageHeight,
+                              int canvasWidth, int canvasHeight, CGContextRef);
 #elif PLATFORM(GTK)
     void paintToCanvas(const unsigned char* imagePixels, int imageWidth, int imageHeight,
                        int canvasWidth, int canvasHeight, PlatformContextCairo* context);
@@ -791,8 +792,9 @@
     void markLayerComposited();
     bool layerComposited() const;
 
-    void paintRenderingResultsToCanvas(CanvasRenderingContext* context);
+    void paintRenderingResultsToCanvas(CanvasRenderingContext*);
     PassRefPtr<ImageData> paintRenderingResultsToImageData();
+    bool paintCompositedResultsToCanvas(CanvasRenderingContext*);
 
 #if PLATFORM(QT)
     bool paintsIntoCanvasBuffer() const { return true; }

Modified: trunk/Source/WebCore/platform/graphics/chromium/Extensions3DChromium.h (92907 => 92908)


--- trunk/Source/WebCore/platform/graphics/chromium/Extensions3DChromium.h	2011-08-12 03:14:32 UTC (rev 92907)
+++ trunk/Source/WebCore/platform/graphics/chromium/Extensions3DChromium.h	2011-08-12 03:32:16 UTC (rev 92908)
@@ -31,6 +31,7 @@
 namespace WebCore {
 
 class GraphicsContext3DInternal;
+class ImageBuffer;
 
 class Extensions3DChromium : public Extensions3D {
 public:
@@ -42,6 +43,7 @@
     //   GL_CHROMIUM_map_sub
     //   GL_CHROMIUM_swapbuffers_complete_callback
     //   GL_CHROMIUM_rate_limit_offscreen_context
+    //   GL_CHROMIUM_paint_framebuffer_canvas
 
     // Extensions3D methods.
     virtual bool supports(const String&);
@@ -78,6 +80,9 @@
     // GL_CHROMIUM_rate_limit_offscreen_context
     void rateLimitOffscreenContextCHROMIUM();
 
+    // GL_CHROMIUM_paint_framebuffer_canvas
+    void paintFramebufferToCanvas(int framebuffer, int width, int height, bool premultiplyAlpha, ImageBuffer*);
+
 private:
     // Instances of this class are strictly owned by the GraphicsContext3D implementation and do not
     // need to be instantiated by any other code.

Modified: trunk/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp (92907 => 92908)


--- trunk/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp	2011-08-12 03:14:32 UTC (rev 92907)
+++ trunk/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp	2011-08-12 03:32:16 UTC (rev 92908)
@@ -99,6 +99,25 @@
     }
 }
 
+bool WebGLLayerChromium::paintRenderedResultsToCanvas(ImageBuffer* imageBuffer)
+{
+    if (m_textureUpdated || !layerRenderer() || !drawsContent())
+        return false;
+
+    IntSize framebufferSize = m_context->getInternalFramebufferSize();
+    ASSERT(layerRendererContext());
+
+    // This would ideally be done in the webgl context, but that isn't possible yet.
+    Platform3DObject framebuffer = layerRendererContext()->createFramebuffer();
+    layerRendererContext()->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, framebuffer);
+    layerRendererContext()->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, m_textureId, 0);
+
+    Extensions3DChromium* extensions = static_cast<Extensions3DChromium*>(layerRendererContext()->getExtensions());
+    extensions->paintFramebufferToCanvas(framebuffer, framebufferSize.width(), framebufferSize.height(), !m_context->getContextAttributes().premultipliedAlpha, imageBuffer);
+    layerRendererContext()->deleteFramebuffer(framebuffer);
+    return true;
+}
+
 void WebGLLayerChromium::setTextureUpdated()
 {
     m_textureUpdated = true;

Modified: trunk/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.h (92907 => 92908)


--- trunk/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.h	2011-08-12 03:14:32 UTC (rev 92907)
+++ trunk/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.h	2011-08-12 03:32:16 UTC (rev 92908)
@@ -52,6 +52,7 @@
     virtual bool drawsContent() const;
     virtual void updateCompositorResources();
     void setTextureUpdated();
+    bool paintRenderedResultsToCanvas(ImageBuffer*);
 
     void setContext(const GraphicsContext3D* context);
     GraphicsContext3D* context() { return m_context; }

Modified: trunk/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp (92907 => 92908)


--- trunk/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp	2011-08-12 03:14:32 UTC (rev 92907)
+++ trunk/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp	2011-08-12 03:32:16 UTC (rev 92908)
@@ -151,6 +151,12 @@
 }
 #endif
 
+bool GraphicsContext3D::paintCompositedResultsToCanvas(CanvasRenderingContext*)
+{
+    // Not needed at the moment, so return that nothing was done.
+    return false;
+}
+
 PassRefPtr<ImageData> GraphicsContext3D::paintRenderingResultsToImageData()
 {
     // Reading premultiplied alpha would involve unpremultiplying, which is

Modified: trunk/Source/WebKit/chromium/ChangeLog (92907 => 92908)


--- trunk/Source/WebKit/chromium/ChangeLog	2011-08-12 03:14:32 UTC (rev 92907)
+++ trunk/Source/WebKit/chromium/ChangeLog	2011-08-12 03:32:16 UTC (rev 92908)
@@ -1,3 +1,24 @@
+2011-08-11  John Bauman  <[email protected]>
+
+        Readback composited webgl results for printing
+        https://bugs.webkit.org/show_bug.cgi?id=65658
+
+        Reviewed by James Robinson.
+
+        Add support for reading from the composited version of a canvas.
+
+        * public/WebGraphicsContext3D.h:
+        * src/Extensions3DChromium.cpp:
+        (WebCore::Extensions3DChromium::paintFramebufferToCanvas):
+        * src/GraphicsContext3DChromium.cpp:
+        (WebCore::GraphicsContext3DInternal::GraphicsContext3DInternal):
+        (WebCore::GraphicsContext3DInternal::paintFramebufferToCanvas):
+        (WebCore::GraphicsContext3DInternal::paintRenderingResultsToCanvas):
+        (WebCore::GraphicsContext3DInternal::paintCompositedResultsToCanvas):
+        (WebCore::GraphicsContext3DInternal::paintRenderingResultsToImageData):
+        (WebCore::GraphicsContext3DInternal::reshape):
+        * src/GraphicsContext3DInternal.h:
+
 2011-08-05  Nat Duca  <[email protected]>
 
         [chromium] Make WebViewImpl point at CCLayerTreeHost and related separation

Modified: trunk/Source/WebKit/chromium/public/WebGraphicsContext3D.h (92907 => 92908)


--- trunk/Source/WebKit/chromium/public/WebGraphicsContext3D.h	2011-08-12 03:14:32 UTC (rev 92907)
+++ trunk/Source/WebKit/chromium/public/WebGraphicsContext3D.h	2011-08-12 03:32:16 UTC (rev 92908)
@@ -138,7 +138,7 @@
     // the memory region pointed to by "pixels" with size "bufferSize". It is
     // expected that the storage for "pixels" covers (4 * width * height) bytes.
     // Returns true on success.
-    virtual bool readBackFramebuffer(unsigned char* pixels, size_t bufferSize) = 0;
+    virtual bool readBackFramebuffer(unsigned char* pixels, size_t bufferSize, WebGLId framebuffer, int width, int height) = 0;
 
     // Returns the id of the texture which is used for storing the contents of
     // the framebuffer associated with this context. This texture is accessible

Modified: trunk/Source/WebKit/chromium/src/Extensions3DChromium.cpp (92907 => 92908)


--- trunk/Source/WebKit/chromium/src/Extensions3DChromium.cpp	2011-08-12 03:14:32 UTC (rev 92907)
+++ trunk/Source/WebKit/chromium/src/Extensions3DChromium.cpp	2011-08-12 03:32:16 UTC (rev 92908)
@@ -125,6 +125,11 @@
     m_internal->rateLimitOffscreenContextCHROMIUM();
 }
 
+void Extensions3DChromium::paintFramebufferToCanvas(int framebuffer, int width, int height, bool premultiplyAlpha, ImageBuffer* imageBuffer)
+{
+    m_internal->paintFramebufferToCanvas(framebuffer, width, height, premultiplyAlpha, imageBuffer);
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(WEBGL)

Modified: trunk/Source/WebKit/chromium/src/GraphicsContext3DChromium.cpp (92907 => 92908)


--- trunk/Source/WebKit/chromium/src/GraphicsContext3DChromium.cpp	2011-08-12 03:14:32 UTC (rev 92907)
+++ trunk/Source/WebKit/chromium/src/GraphicsContext3DChromium.cpp	2011-08-12 03:32:16 UTC (rev 92908)
@@ -90,7 +90,7 @@
 #if USE(SKIA)
     , m_grContext(0)
 #elif USE(CG)
-    , m_renderOutput(0)
+    , m_renderOutputSize(0)
 #else
 #error Must port to your platform
 #endif
@@ -99,10 +99,6 @@
 
 GraphicsContext3DInternal::~GraphicsContext3DInternal()
 {
-#if USE(CG)
-    if (m_renderOutput)
-        delete[] m_renderOutput;
-#endif
 #if USE(SKIA)
     if (m_grContext) {
         m_grContext->contextDestroyed();
@@ -205,16 +201,15 @@
     return m_layerComposited;
 }
 
-void GraphicsContext3DInternal::paintRenderingResultsToCanvas(CanvasRenderingContext* context)
+void GraphicsContext3DInternal::paintFramebufferToCanvas(int framebuffer, int width, int height, bool premultiplyAlpha, ImageBuffer* imageBuffer)
 {
-    HTMLCanvasElement* canvas = context->canvas();
-    ImageBuffer* imageBuffer = canvas->buffer();
     unsigned char* pixels = 0;
+    size_t bufferSize = 4 * width * height;
 #if USE(SKIA)
     const SkBitmap* canvasBitmap = imageBuffer->context()->platformContext()->bitmap();
     const SkBitmap* readbackBitmap = 0;
     ASSERT(canvasBitmap->config() == SkBitmap::kARGB_8888_Config);
-    if (canvasBitmap->width() == m_impl->width() && canvasBitmap->height() == m_impl->height()) {
+    if (canvasBitmap->width() == width && canvasBitmap->height() == height) {
         // This is the fastest and most common case. We read back
         // directly into the canvas's backing store.
         readbackBitmap = canvasBitmap;
@@ -223,10 +218,10 @@
         // We need to allocate a temporary bitmap for reading back the
         // pixel data. We will then use Skia to rescale this bitmap to
         // the size of the canvas's backing store.
-        if (m_resizingBitmap.width() != m_impl->width() || m_resizingBitmap.height() != m_impl->height()) {
+        if (m_resizingBitmap.width() != width || m_resizingBitmap.height() != height) {
             m_resizingBitmap.setConfig(SkBitmap::kARGB_8888_Config,
-                                       m_impl->width(),
-                                       m_impl->height());
+                                       width,
+                                       height);
             if (!m_resizingBitmap.allocPixels())
                 return;
         }
@@ -237,17 +232,19 @@
     SkAutoLockPixels bitmapLock(*readbackBitmap);
     pixels = static_cast<unsigned char*>(readbackBitmap->getPixels());
 #elif USE(CG)
-    if (m_renderOutput)
-        pixels = m_renderOutput;
+    if (!m_renderOutput || m_renderOutputSize != bufferSize) {
+        m_renderOutput = adoptArrayPtr(new unsigned char[bufferSize]);
+        m_renderOutputSize = bufferSize;
+    }
+
+    pixels = m_renderOutput.get();
 #else
 #error Must port to your platform
 #endif
 
-    m_impl->readBackFramebuffer(pixels, 4 * m_impl->width() * m_impl->height());
+    m_impl->readBackFramebuffer(pixels, 4 * width * height, framebuffer, width, height);
 
-    if (!m_impl->getContextAttributes().premultipliedAlpha) {
-        size_t bufferSize = 4 * m_impl->width() * m_impl->height();
-
+    if (premultiplyAlpha) {
         for (size_t i = 0; i < bufferSize; i += 4) {
             pixels[i + 0] = std::min(255, pixels[i + 0] * pixels[i + 3] / 255);
             pixels[i + 1] = std::min(255, pixels[i + 1] * pixels[i + 3] / 255);
@@ -265,15 +262,27 @@
         canvas.drawBitmapRect(m_resizingBitmap, 0, dst);
     }
 #elif USE(CG)
-    if (m_renderOutput && context->is3d()) {
-        WebGLRenderingContext* webGLContext = static_cast<WebGLRenderingContext*>(context);
-        webGLContext->graphicsContext3D()->paintToCanvas(m_renderOutput, m_impl->width(), m_impl->height(), canvas->width(), canvas->height(), imageBuffer->context()->platformContext());
-    }
+    GraphicsContext3D::paintToCanvas(pixels, width, height, imageBuffer->width(), imageBuffer->height(), imageBuffer->context()->platformContext());
 #else
 #error Must port to your platform
 #endif
 }
 
+void GraphicsContext3DInternal::paintRenderingResultsToCanvas(CanvasRenderingContext* context)
+{
+    ImageBuffer* imageBuffer = context->canvas()->buffer();
+    paintFramebufferToCanvas(0, m_impl->width(), m_impl->height(), !m_impl->getContextAttributes().premultipliedAlpha, imageBuffer);
+}
+
+bool GraphicsContext3DInternal::paintCompositedResultsToCanvas(CanvasRenderingContext* context)
+{
+#if USE(ACCELERATED_COMPOSITING)
+    if (platformLayer())
+        return platformLayer()->paintRenderedResultsToCanvas(context->canvas()->buffer());
+#endif
+    return false;
+}
+
 PassRefPtr<ImageData> GraphicsContext3DInternal::paintRenderingResultsToImageData()
 {
     if (m_impl->getContextAttributes().premultipliedAlpha)
@@ -283,7 +292,7 @@
     unsigned char* pixels = imageData->data()->data()->data();
     size_t bufferSize = 4 * m_impl->width() * m_impl->height();
 
-    m_impl->readBackFramebuffer(pixels, bufferSize);
+    m_impl->readBackFramebuffer(pixels, bufferSize, 0, m_impl->width(), m_impl->height());
 
     for (size_t i = 0; i < bufferSize; i += 4)
         std::swap(pixels[i], pixels[i + 2]);
@@ -303,17 +312,6 @@
         return;
 
     m_impl->reshape(width, height);
-
-#if USE(CG)
-    // Need to reallocate the client-side backing store.
-    // FIXME: make this more efficient.
-    if (m_renderOutput) {
-        delete[] m_renderOutput;
-        m_renderOutput = 0;
-    }
-    int rowBytes = width * 4;
-    m_renderOutput = new unsigned char[height * rowBytes];
-#endif // USE(CG)
 }
 
 IntSize GraphicsContext3DInternal::getInternalFramebufferSize() const
@@ -1168,6 +1166,7 @@
 
 DELEGATE_TO_INTERNAL_1(paintRenderingResultsToCanvas, CanvasRenderingContext*)
 DELEGATE_TO_INTERNAL_R(paintRenderingResultsToImageData, PassRefPtr<ImageData>)
+DELEGATE_TO_INTERNAL_1R(paintCompositedResultsToCanvas, CanvasRenderingContext*, bool)
 
 bool GraphicsContext3D::paintsIntoCanvasBuffer() const
 {

Modified: trunk/Source/WebKit/chromium/src/GraphicsContext3DInternal.h (92907 => 92908)


--- trunk/Source/WebKit/chromium/src/GraphicsContext3DInternal.h	2011-08-12 03:14:32 UTC (rev 92907)
+++ trunk/Source/WebKit/chromium/src/GraphicsContext3DInternal.h	2011-08-12 03:32:16 UTC (rev 92908)
@@ -29,6 +29,7 @@
 #include "Extensions3DChromium.h"
 #include "GraphicsContext3D.h"
 #include <wtf/HashSet.h>
+#include <wtf/OwnArrayPtr.h>
 #include <wtf/OwnPtr.h>
 #if USE(SKIA)
 #include "SkBitmap.h"
@@ -80,8 +81,10 @@
     void markLayerComposited();
 
     void paintRenderingResultsToCanvas(CanvasRenderingContext*);
+    void paintFramebufferToCanvas(int framebuffer, int width, int height, bool premultiplyAlpha, ImageBuffer*);
     PassRefPtr<ImageData> paintRenderingResultsToImageData();
     bool paintsIntoCanvasBuffer() const;
+    bool paintCompositedResultsToCanvas(CanvasRenderingContext*);
 
     void prepareTexture();
 
@@ -310,7 +313,8 @@
 #endif
 
 #if USE(CG)
-    unsigned char* m_renderOutput;
+    OwnArrayPtr<unsigned char> m_renderOutput;
+    size_t m_renderOutputSize;
 #endif
 
     void initializeExtensions();
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to