summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordongseong.hwang@intel.com <dongseong.hwang@intel.com>2014-11-26 14:44:31 +0000
committerdongseong.hwang@intel.com <dongseong.hwang@intel.com>2014-11-26 14:44:31 +0000
commitfc086bf405a6ec1a1929f3a574f5be7b0c92fecb (patch)
tree51593ae03bca397b249a4bc24103541ea98915c7
parente8b077f83290d7b0b2edaa30c02944e01be42e41 (diff)
downloadchromium_src-fc086bf405a6ec1a1929f3a574f5be7b0c92fecb.zip
chromium_src-fc086bf405a6ec1a1929f3a574f5be7b0c92fecb.tar.gz
chromium_src-fc086bf405a6ec1a1929f3a574f5be7b0c92fecb.tar.bz2
WebGL: clarify which Front or Back buffer is used by each API.
WebGL has double buffers. Front buffer is the buffer used by the compositor and back buffer is the target buffer of WebGL. Following list shows what each API needs. Front buffer - Blink renderer, e.g. HTMLCanvasElement::paint(), CSSCanvasValue::image(), Editor::copyImage(), HTMLCanvasElement::imageSourceURL() - the Compositor, i.e. DrawingBuffer::prepareMailbox() Back buffer - Canvas, e.g. WebGLRenderingContextBase::texImage2D(canvas), CanvasRenderingContext2D::drawImage(canvas), CanvasRenderingContext2D::createPattern(canvas), HTMLCanvasElement::toDataURL() First of all, fix the bug of HTMLCanvasElement::imageSourceURL() when premultipliedAlpha == false. Currently, HTMLCanvasElement::imageSourceURL() always returns back buffer. Simplify code of texImage2D() and texSubImage2D() as copiedImage() can copy both Front and Back buffer. TEST=fast/canvas/webgl/canvas-to-data-url.html BUG=331181 Review URL: https://codereview.chromium.org/749653002 git-svn-id: svn://svn.chromium.org/blink/trunk@186032 bbb929c8-8fbe-4397-9dbb-9b2b20218538
-rw-r--r--third_party/WebKit/LayoutTests/fast/canvas/webgl/canvas-to-data-url-expected.txt14
-rw-r--r--third_party/WebKit/LayoutTests/fast/canvas/webgl/canvas-to-data-url.html60
-rw-r--r--third_party/WebKit/Source/core/css/CSSCanvasValue.cpp2
-rw-r--r--third_party/WebKit/Source/core/editing/Editor.cpp2
-rw-r--r--third_party/WebKit/Source/core/frame/ImageBitmap.cpp2
-rw-r--r--third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp37
-rw-r--r--third_party/WebKit/Source/core/html/HTMLCanvasElement.h7
-rw-r--r--third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h3
-rw-r--r--third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.cpp32
-rw-r--r--third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.h4
-rw-r--r--third_party/WebKit/Source/platform/graphics/GraphicsTypes3D.h8
-rw-r--r--third_party/WebKit/Source/platform/graphics/ImageBuffer.cpp4
-rw-r--r--third_party/WebKit/Source/platform/graphics/ImageBuffer.h2
-rw-r--r--third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp27
-rw-r--r--third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.h5
15 files changed, 144 insertions, 65 deletions
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/webgl/canvas-to-data-url-expected.txt b/third_party/WebKit/LayoutTests/fast/canvas/webgl/canvas-to-data-url-expected.txt
new file mode 100644
index 0000000..4b0327b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/canvas/webgl/canvas-to-data-url-expected.txt
@@ -0,0 +1,14 @@
+PASS successfullyParsed is true
+
+TEST COMPLETE
+Check if back buffer (toDataURL) is equal to front buffer (getImageSourceURL)
+1) when drawingBuffer is preserved.
+PASS preserve_canvas3D.toDataURL('image/png') == window.internals.getImageSourceURL(preserve_canvas3D) is true
+2) when drawingBuffer is not preserved.
+PASS nonpreserve_canvas3D.toDataURL('image/png') == window.internals.getImageSourceURL(nonpreserve_canvas3D) is true
+Check if back buffer (toDataURL) is equal to front buffer (getImageSourceURL) one frame after drawing webgl contents.
+1) when drawingBuffer is preserved.
+PASS preserve_canvas3D.toDataURL('image/png') == window.internals.getImageSourceURL(preserve_canvas3D) is true
+2) when drawingBuffer is not preserved. They must be different.
+PASS nonpreserve_canvas3D.toDataURL('image/png') != window.internals.getImageSourceURL(nonpreserve_canvas3D) is true
+
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/webgl/canvas-to-data-url.html b/third_party/WebKit/LayoutTests/fast/canvas/webgl/canvas-to-data-url.html
new file mode 100644
index 0000000..20ab459
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/canvas/webgl/canvas-to-data-url.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<html>
+<body>
+<canvas id="preserve-canvas3d" width="10" height="10"></canvas>
+<canvas id="nonpreserve-canvas3d" width="10" height="10"></canvas>
+<script src="../../../resources/js-test.js"></script>
+<script>
+if (window.testRunner) {
+ testRunner.dumpAsText();
+ testRunner.waitUntilDone();
+}
+
+var preserve_canvas3D;
+var nonpreserve_canvas3D;
+
+function renderWebGL(gl) {
+ gl.clearColor(0.5, 1, 0.3, 0.1);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+}
+
+function asyncTest() {
+ debug("Check if back buffer (toDataURL) is equal to front buffer (getImageSourceURL) one frame after drawing webgl contents.")
+ debug("1) when drawingBuffer is preserved.")
+ shouldBeTrue("preserve_canvas3D.toDataURL('image/png') == window.internals.getImageSourceURL(preserve_canvas3D)");
+ debug("2) when drawingBuffer is not preserved. They must be different.")
+ shouldBeTrue("nonpreserve_canvas3D.toDataURL('image/png') != window.internals.getImageSourceURL(nonpreserve_canvas3D)");
+ if (window.testRunner)
+ testRunner.notifyDone();
+}
+
+function startTestAfterFirstPaint() {
+ preserve_canvas3D = document.getElementById('preserve-canvas3d');
+ var preserve_gl = preserve_canvas3D.getContext('webgl', {preserveDrawingBuffer: true, premultipliedAlpha: false});
+ nonpreserve_canvas3D = document.getElementById('nonpreserve-canvas3d');
+ var nonpreserve_gl = nonpreserve_canvas3D.getContext('webgl', {preserveDrawingBuffer: false, premultipliedAlpha: false});
+
+ // prepare webgl contents.
+ renderWebGL(preserve_gl);
+ renderWebGL(nonpreserve_gl);
+
+ debug("Check if back buffer (toDataURL) is equal to front buffer (getImageSourceURL)")
+ debug("1) when drawingBuffer is preserved.")
+ shouldBeTrue("preserve_canvas3D.toDataURL('image/png') == window.internals.getImageSourceURL(preserve_canvas3D)");
+ debug("2) when drawingBuffer is not preserved.")
+ shouldBeTrue("nonpreserve_canvas3D.toDataURL('image/png') == window.internals.getImageSourceURL(nonpreserve_canvas3D)");
+
+ if (window.testRunner) {
+ testRunner.waitUntilDone();
+ testRunner.displayAsyncThen(asyncTest);
+ } else {
+ window.requestAnimationFrame(asyncTest);
+ }
+}
+
+window.onload = function () {
+ window.requestAnimationFrame(startTestAfterFirstPaint);
+}
+</script>
+</body>
+</html>
diff --git a/third_party/WebKit/Source/core/css/CSSCanvasValue.cpp b/third_party/WebKit/Source/core/css/CSSCanvasValue.cpp
index 9d35c9d..1c089e6 100644
--- a/third_party/WebKit/Source/core/css/CSSCanvasValue.cpp
+++ b/third_party/WebKit/Source/core/css/CSSCanvasValue.cpp
@@ -91,7 +91,7 @@ PassRefPtr<Image> CSSCanvasValue::image(RenderObject* renderer, const IntSize& /
HTMLCanvasElement* elt = element(&renderer->document());
if (!elt || !elt->buffer())
return nullptr;
- return elt->copiedImage();
+ return elt->copiedImage(FrontBuffer);
}
bool CSSCanvasValue::equals(const CSSCanvasValue& other) const
diff --git a/third_party/WebKit/Source/core/editing/Editor.cpp b/third_party/WebKit/Source/core/editing/Editor.cpp
index 4f4ec16..992dd86 100644
--- a/third_party/WebKit/Source/core/editing/Editor.cpp
+++ b/third_party/WebKit/Source/core/editing/Editor.cpp
@@ -429,7 +429,7 @@ static Image* imageFromNode(const Node& node)
return nullptr;
if (renderer->isCanvas())
- return toHTMLCanvasElement(node).copiedImage();
+ return toHTMLCanvasElement(node).copiedImage(FrontBuffer);
if (renderer->isImage()) {
RenderImage* renderImage = toRenderImage(renderer);
diff --git a/third_party/WebKit/Source/core/frame/ImageBitmap.cpp b/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
index d5ffd02..50290cb 100644
--- a/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
+++ b/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
@@ -82,7 +82,7 @@ ImageBitmap::ImageBitmap(HTMLCanvasElement* canvas, const IntRect& cropRect)
{
CanvasRenderingContext* sourceContext = canvas->renderingContext();
if (sourceContext && sourceContext->is3d())
- sourceContext->paintRenderingResultsToCanvas(CanvasRenderingContext::Back);
+ sourceContext->paintRenderingResultsToCanvas(BackBuffer);
IntRect srcRect = intersection(cropRect, IntRect(IntPoint(), canvas->size()));
m_bitmapRect = IntRect(IntPoint(std::max(0, -cropRect.x()), std::max(0, -cropRect.y())), srcRect.size());
diff --git a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
index 4194576..7bc7781 100644
--- a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
@@ -357,7 +357,7 @@ void HTMLCanvasElement::paint(GraphicsContext* context, const LayoutRect& r)
if (m_context) {
if (!paintsIntoCanvasBuffer() && !document().printing())
return;
- m_context->paintRenderingResultsToCanvas(CanvasRenderingContext::Front);
+ m_context->paintRenderingResultsToCanvas(FrontBuffer);
}
if (hasImageBuffer()) {
@@ -405,10 +405,10 @@ String HTMLCanvasElement::toEncodingMimeType(const String& mimeType)
const AtomicString HTMLCanvasElement::imageSourceURL() const
{
- return AtomicString(toDataURLInternal("image/png", 0, true));
+ return AtomicString(toDataURLInternal("image/png", 0, FrontBuffer));
}
-String HTMLCanvasElement::toDataURLInternal(const String& mimeType, const double* quality, bool isSaving) const
+String HTMLCanvasElement::toDataURLInternal(const String& mimeType, const double* quality, SourceDrawingBuffer sourceBuffer) const
{
if (m_size.isEmpty() || !canCreateImageBuffer(size()))
return String("data:,");
@@ -419,14 +419,13 @@ String HTMLCanvasElement::toDataURLInternal(const String& mimeType, const double
return ImageDataToDataURL(ImageDataBuffer(imageData->size(), imageData->data()), encodingMimeType, quality);
}
- // Try to get ImageData first, as that may avoid lossy conversions.
- RefPtrWillBeRawPtr<ImageData> imageData = getImageData();
-
- if (imageData)
- return ImageDataToDataURL(ImageDataBuffer(imageData->size(), imageData->data()), encodingMimeType, quality);
-
if (m_context->is3d()) {
- m_context->paintRenderingResultsToCanvas(isSaving ? CanvasRenderingContext::Front : CanvasRenderingContext::Back);
+ // Get non-premultiplied data because of inaccurate premultiplied alpha conversion of buffer()->toDataURL().
+ RefPtrWillBeRawPtr<ImageData> imageData =
+ toWebGLRenderingContext(m_context.get())->paintRenderingResultsToImageData(sourceBuffer);
+ if (imageData)
+ return ImageDataToDataURL(ImageDataBuffer(imageData->size(), imageData->data()), encodingMimeType, quality);
+ m_context->paintRenderingResultsToCanvas(sourceBuffer);
}
return buffer()->toDataURL(encodingMimeType, quality);
@@ -439,14 +438,7 @@ String HTMLCanvasElement::toDataURL(const String& mimeType, const double* qualit
return String();
}
- return toDataURLInternal(mimeType, quality);
-}
-
-PassRefPtrWillBeRawPtr<ImageData> HTMLCanvasElement::getImageData() const
-{
- if (!m_context || !m_context->is3d())
- return nullptr;
- return toWebGLRenderingContext(m_context.get())->paintRenderingResultsToImageData();
+ return toDataURLInternal(mimeType, quality, BackBuffer);
}
SecurityOrigin* HTMLCanvasElement::securityOrigin() const
@@ -687,12 +679,11 @@ void HTMLCanvasElement::ensureUnacceleratedImageBuffer()
m_didFailToCreateImageBuffer = !m_imageBuffer;
}
-Image* HTMLCanvasElement::copiedImage() const
+Image* HTMLCanvasElement::copiedImage(SourceDrawingBuffer sourceBuffer) const
{
if (!m_copiedImage && buffer()) {
- if (m_context && m_context->is3d()) {
- m_context->paintRenderingResultsToCanvas(CanvasRenderingContext::Front);
- }
+ if (m_context && m_context->is3d())
+ m_context->paintRenderingResultsToCanvas(sourceBuffer);
m_copiedImage = buffer()->copyImage(CopyBackingStore, Unscaled);
updateExternallyAllocatedMemory();
}
@@ -759,7 +750,7 @@ PassRefPtr<Image> HTMLCanvasElement::getSourceImageForCanvas(SourceImageMode mod
}
if (m_context && m_context->is3d()) {
- m_context->paintRenderingResultsToCanvas(CanvasRenderingContext::Back);
+ m_context->paintRenderingResultsToCanvas(BackBuffer);
*status = ExternalSourceImageStatus;
// can't create SkImage from WebGLImageBufferSurface (contains only SkBitmap)
diff --git a/third_party/WebKit/Source/core/html/HTMLCanvasElement.h b/third_party/WebKit/Source/core/html/HTMLCanvasElement.h
index feddebb..ba89f02 100644
--- a/third_party/WebKit/Source/core/html/HTMLCanvasElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLCanvasElement.h
@@ -34,10 +34,10 @@
#include "platform/geometry/FloatRect.h"
#include "platform/geometry/IntSize.h"
#include "platform/graphics/GraphicsTypes.h"
+#include "platform/graphics/GraphicsTypes3D.h"
#include "platform/graphics/ImageBufferClient.h"
#include "platform/heap/Handle.h"
#include "public/platform/WebThread.h"
-#include "wtf/Forward.h"
#define CanvasDefaultInterpolationQuality InterpolationLow
@@ -119,9 +119,8 @@ public:
void ensureUnacceleratedImageBuffer();
ImageBuffer* buffer() const;
- Image* copiedImage() const;
+ Image* copiedImage(SourceDrawingBuffer) const;
void clearCopiedImage();
- PassRefPtrWillBeRawPtr<ImageData> getImageData() const;
SecurityOrigin* securityOrigin() const;
bool originClean() const { return m_originClean; }
@@ -187,7 +186,7 @@ private:
void updateExternallyAllocatedMemory() const;
- String toDataURLInternal(const String& mimeType, const double* quality, bool isSaving = false) const;
+ String toDataURLInternal(const String& mimeType, const double* quality, SourceDrawingBuffer) const;
WillBeHeapHashSet<RawPtrWillBeWeakMember<CanvasObserver>> m_observers;
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h
index b03358e..8b4054b 100644
--- a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h
+++ b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h
@@ -58,8 +58,7 @@ public:
virtual bool hasAlpha() const { return true; }
virtual void setIsHidden(bool) = 0;
- enum SourceBuffer { Front, Back };
- virtual void paintRenderingResultsToCanvas(SourceBuffer) { }
+ virtual void paintRenderingResultsToCanvas(SourceDrawingBuffer) { }
virtual blink::WebLayer* platformLayer() const { return nullptr; }
diff --git a/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.cpp b/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.cpp
index 83001cc..2292f69 100644
--- a/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.cpp
+++ b/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.cpp
@@ -93,10 +93,14 @@
namespace blink {
+namespace {
+
const double secondsBetweenRestoreAttempts = 1.0;
const int maxGLErrorsAllowedToConsole = 256;
const unsigned maxGLActiveContexts = 16;
+} // namesapce
+
// FIXME: Oilpan: static vectors to heap allocated WebGLRenderingContextBase objects
// are kept here. This relies on the WebGLRenderingContextBase finalization to
// explicitly retire themselves from these vectors, but it'd be preferable if
@@ -891,7 +895,7 @@ void WebGLRenderingContextBase::setIsHidden(bool hidden)
drawingBuffer()->setIsHidden(hidden);
}
-void WebGLRenderingContextBase::paintRenderingResultsToCanvas(SourceBuffer source)
+void WebGLRenderingContextBase::paintRenderingResultsToCanvas(SourceDrawingBuffer sourceBuffer)
{
if (isContextLost())
return;
@@ -907,7 +911,7 @@ void WebGLRenderingContextBase::paintRenderingResultsToCanvas(SourceBuffer sourc
ScopedTexture2DRestorer restorer(this);
drawingBuffer()->commit();
- if (!canvas()->buffer()->copyRenderingResultsFromDrawingBuffer(drawingBuffer(), source == Front)) {
+ if (!canvas()->buffer()->copyRenderingResultsFromDrawingBuffer(drawingBuffer(), sourceBuffer)) {
canvas()->ensureUnacceleratedImageBuffer();
if (canvas()->hasImageBuffer())
drawingBuffer()->paintRenderingResultsToCanvas(canvas()->buffer());
@@ -919,7 +923,7 @@ void WebGLRenderingContextBase::paintRenderingResultsToCanvas(SourceBuffer sourc
drawingBuffer()->bind();
}
-PassRefPtrWillBeRawPtr<ImageData> WebGLRenderingContextBase::paintRenderingResultsToImageData()
+PassRefPtrWillBeRawPtr<ImageData> WebGLRenderingContextBase::paintRenderingResultsToImageData(SourceDrawingBuffer sourceBuffer)
{
if (isContextLost())
return nullptr;
@@ -927,15 +931,11 @@ PassRefPtrWillBeRawPtr<ImageData> WebGLRenderingContextBase::paintRenderingResul
clearIfComposited();
drawingBuffer()->commit();
int width, height;
- RefPtr<Uint8ClampedArray> imageDataPixels = drawingBuffer()->paintRenderingResultsToImageData(width, height);
+ RefPtr<Uint8ClampedArray> imageDataPixels =
+ drawingBuffer()->paintRenderingResultsToImageData(width, height, sourceBuffer);
if (!imageDataPixels)
return nullptr;
- if (m_framebufferBinding)
- webContext()->bindFramebuffer(GL_FRAMEBUFFER, objectOrZero(m_framebufferBinding.get()));
- else
- drawingBuffer()->bind();
-
return ImageData::create(IntSize(width, height), imageDataPixels);
}
@@ -3614,18 +3614,14 @@ void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLenum in
WebGLRenderingContextBase* gl = toWebGLRenderingContextBase(canvas->renderingContext());
ScopedTexture2DRestorer restorer(gl);
if (gl && gl->drawingBuffer()->copyToPlatformTexture(webContext(), texture->object(), internalformat, type,
- level, m_unpackPremultiplyAlpha, !m_unpackFlipY, DrawingBuffer::Back)) {
+ level, m_unpackPremultiplyAlpha, !m_unpackFlipY, BackBuffer)) {
texture->setLevelInfo(target, level, internalformat, canvas->width(), canvas->height(), type);
return;
}
}
}
- RefPtrWillBeRawPtr<ImageData> imageData = canvas->getImageData();
- if (imageData)
- texImage2D(target, level, internalformat, format, type, imageData.get(), exceptionState);
- else
- texImage2DImpl(target, level, internalformat, format, type, canvas->copiedImage(), WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
+ texImage2DImpl(target, level, internalformat, format, type, canvas->copiedImage(BackBuffer), WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
}
PassRefPtr<Image> WebGLRenderingContextBase::videoFrameToImage(HTMLVideoElement* video, BackingStoreCopy backingStoreCopy)
@@ -3859,11 +3855,7 @@ void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint
|| !validateTexFunc("texSubImage2D", TexSubImage2D, SourceHTMLCanvasElement, target, level, format, canvas->width(), canvas->height(), 0, format, type, xoffset, yoffset))
return;
- RefPtrWillBeRawPtr<ImageData> imageData = canvas->getImageData();
- if (imageData)
- texSubImage2D(target, level, xoffset, yoffset, format, type, imageData.get(), exceptionState);
- else
- texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas->copiedImage(), WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
+ texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas->copiedImage(BackBuffer), WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
}
void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
diff --git a/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.h b/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.h
index e6f989c..1809238 100644
--- a/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.h
+++ b/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.h
@@ -350,7 +350,7 @@ public:
void reshape(int width, int height);
void markLayerComposited();
- PassRefPtrWillBeRawPtr<ImageData> paintRenderingResultsToImageData();
+ PassRefPtrWillBeRawPtr<ImageData> paintRenderingResultsToImageData(SourceDrawingBuffer);
void removeSharedObject(WebGLSharedObject*);
void removeContextObject(WebGLContextObject*);
@@ -409,7 +409,7 @@ protected:
virtual bool is3d() const override { return true; }
virtual bool isAccelerated() const override { return true; }
virtual void setIsHidden(bool) override;
- virtual void paintRenderingResultsToCanvas(SourceBuffer) override;
+ virtual void paintRenderingResultsToCanvas(SourceDrawingBuffer) override;
virtual blink::WebLayer* platformLayer() const override;
void addSharedObject(WebGLSharedObject*);
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsTypes3D.h b/third_party/WebKit/Source/platform/graphics/GraphicsTypes3D.h
index 33349a4..d76bb1a 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsTypes3D.h
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsTypes3D.h
@@ -57,4 +57,10 @@ const unsigned GC3D_COMPRESSED_ATC_RGBA_INTERPOLATED_ALPHA_AMD = 0x87EE;
const unsigned GC3D_MAP_CHROMIUM = 0x78F1;
const unsigned GC3D_SCANOUT_CHROMIUM = 0x78F2;
-#endif
+namespace blink {
+
+enum SourceDrawingBuffer { FrontBuffer, BackBuffer };
+
+} // namespace blink
+
+#endif // GraphicsTypes3D_h
diff --git a/third_party/WebKit/Source/platform/graphics/ImageBuffer.cpp b/third_party/WebKit/Source/platform/graphics/ImageBuffer.cpp
index 635dde7..9b073d5 100644
--- a/third_party/WebKit/Source/platform/graphics/ImageBuffer.cpp
+++ b/third_party/WebKit/Source/platform/graphics/ImageBuffer.cpp
@@ -242,7 +242,7 @@ void ImageBuffer::didModifyBackingTexture()
m_surface->didModifyBackingTexture();
}
-bool ImageBuffer::copyRenderingResultsFromDrawingBuffer(DrawingBuffer* drawingBuffer, bool fromFrontBuffer)
+bool ImageBuffer::copyRenderingResultsFromDrawingBuffer(DrawingBuffer* drawingBuffer, SourceDrawingBuffer sourceBuffer)
{
if (!drawingBuffer)
return false;
@@ -256,7 +256,7 @@ bool ImageBuffer::copyRenderingResultsFromDrawingBuffer(DrawingBuffer* drawingBu
m_surface->invalidateCachedBitmap();
bool result = drawingBuffer->copyToPlatformTexture(context3D, tex, GL_RGBA,
- GL_UNSIGNED_BYTE, 0, true, false, fromFrontBuffer ? DrawingBuffer::Front : DrawingBuffer::Back);
+ GL_UNSIGNED_BYTE, 0, true, false, sourceBuffer);
if (result) {
m_surface->didModifyBackingTexture();
diff --git a/third_party/WebKit/Source/platform/graphics/ImageBuffer.h b/third_party/WebKit/Source/platform/graphics/ImageBuffer.h
index 53a2fbd..1d3b17f 100644
--- a/third_party/WebKit/Source/platform/graphics/ImageBuffer.h
+++ b/third_party/WebKit/Source/platform/graphics/ImageBuffer.h
@@ -124,7 +124,7 @@ public:
Platform3DObject getBackingTexture();
void didModifyBackingTexture();
- bool copyRenderingResultsFromDrawingBuffer(DrawingBuffer*, bool fromFrontBuffer = false);
+ bool copyRenderingResultsFromDrawingBuffer(DrawingBuffer*, SourceDrawingBuffer);
void flush();
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp
index 60a9d98..5996ff8 100644
--- a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp
+++ b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp
@@ -459,7 +459,7 @@ bool DrawingBuffer::initialize(const IntSize& size)
}
bool DrawingBuffer::copyToPlatformTexture(WebGraphicsContext3D* context, Platform3DObject texture, GLenum internalFormat,
- GLenum destType, GLint level, bool premultiplyAlpha, bool flipY, SourceBuffer source)
+ GLenum destType, GLint level, bool premultiplyAlpha, bool flipY, SourceDrawingBuffer sourceBuffer)
{
if (m_contentsChanged) {
if (m_multisampleMode != None) {
@@ -478,7 +478,7 @@ bool DrawingBuffer::copyToPlatformTexture(WebGraphicsContext3D* context, Platfor
// Contexts may be in a different share group. We must transfer the texture through a mailbox first
WebExternalTextureMailbox mailbox;
GLint textureId = 0;
- if (source == Front && m_frontColorBuffer.texInfo.textureId) {
+ if (sourceBuffer == FrontBuffer && m_frontColorBuffer.texInfo.textureId) {
textureId = m_frontColorBuffer.texInfo.textureId;
mailbox = m_frontColorBuffer.mailbox;
} else {
@@ -887,7 +887,7 @@ void DrawingBuffer::paintRenderingResultsToCanvas(ImageBuffer* imageBuffer)
paintFramebufferToCanvas(framebuffer(), size().width(), size().height(), !m_actualAttributes.premultipliedAlpha, imageBuffer);
}
-PassRefPtr<Uint8ClampedArray> DrawingBuffer::paintRenderingResultsToImageData(int& width, int& height)
+PassRefPtr<Uint8ClampedArray> DrawingBuffer::paintRenderingResultsToImageData(int& width, int& height, SourceDrawingBuffer sourceBuffer)
{
if (m_actualAttributes.premultipliedAlpha)
return nullptr;
@@ -903,10 +903,29 @@ PassRefPtr<Uint8ClampedArray> DrawingBuffer::paintRenderingResultsToImageData(in
RefPtr<Uint8ClampedArray> pixels = Uint8ClampedArray::createUninitialized(width * height * 4);
- m_context->bindFramebuffer(GL_FRAMEBUFFER, framebuffer());
+ GLint fbo = 0;
+ if (sourceBuffer == FrontBuffer && m_frontColorBuffer.texInfo.textureId) {
+ GLint fbo = m_context->createFramebuffer();
+ m_context->bindFramebuffer(GL_FRAMEBUFFER, fbo);
+ m_context->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_frontColorBuffer.texInfo.textureId, 0);
+ } else {
+ m_context->bindFramebuffer(GL_FRAMEBUFFER, framebuffer());
+ }
+
readBackFramebuffer(pixels->data(), width, height, ReadbackRGBA, WebGLImageConversion::AlphaDoNothing);
flipVertically(pixels->data(), width, height);
+ if (fbo) {
+ m_context->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
+ m_context->deleteFramebuffer(fbo);
+ }
+
+ if (m_framebufferBinding) {
+ restoreFramebufferBinding();
+ } else {
+ bind();
+ }
+
return pixels.release();
}
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.h b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.h
index c28f68f..7e0ce03 100644
--- a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.h
+++ b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.h
@@ -155,15 +155,14 @@ public:
virtual bool prepareMailbox(WebExternalTextureMailbox*, WebExternalBitmap*) override;
virtual void mailboxReleased(const WebExternalTextureMailbox&, bool lostResource = false) override;
- enum SourceBuffer { Front, Back };
// Destroys the TEXTURE_2D binding for the owned context
bool copyToPlatformTexture(WebGraphicsContext3D*, Platform3DObject texture, GLenum internalFormat,
- GLenum destType, GLint level, bool premultiplyAlpha, bool flipY, SourceBuffer);
+ GLenum destType, GLint level, bool premultiplyAlpha, bool flipY, SourceDrawingBuffer);
void setPackAlignment(GLint param);
void paintRenderingResultsToCanvas(ImageBuffer*);
- PassRefPtr<Uint8ClampedArray> paintRenderingResultsToImageData(int&, int&);
+ PassRefPtr<Uint8ClampedArray> paintRenderingResultsToImageData(int&, int&, SourceDrawingBuffer);
protected: // For unittests
DrawingBuffer(