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();