Title: [98567] trunk/Source
Revision
98567
Author
[email protected]
Date
2011-10-27 07:23:49 -0700 (Thu, 27 Oct 2011)

Log Message

Disable blending when drawing opaque layers
https://bugs.webkit.org/show_bug.cgi?id=70085

Patch by Antoine Labour <[email protected]> on 2011-10-27
Reviewed by James Robinson.

Covered by compositing/ tests, as well as a new unit test:
CCLayerTreeHostImplTest.blendingOffWhenDrawingOpaqueLayers

* platform/graphics/chromium/LayerChromium.cpp:
(WebCore::LayerChromium::LayerChromium):
(WebCore::LayerChromium::pushPropertiesTo):
* platform/graphics/chromium/LayerRendererChromium.cpp:
(WebCore::LayerRendererChromium::drawLayer):
* platform/graphics/chromium/cc/CCLayerImpl.cpp:
(WebCore::CCLayerImpl::CCLayerImpl):
* platform/graphics/chromium/cc/CCLayerImpl.h:
(WebCore::CCLayerImpl::setOpaque):
(WebCore::CCLayerImpl::opaque):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (98566 => 98567)


--- trunk/Source/WebCore/ChangeLog	2011-10-27 14:03:32 UTC (rev 98566)
+++ trunk/Source/WebCore/ChangeLog	2011-10-27 14:23:49 UTC (rev 98567)
@@ -1,3 +1,24 @@
+2011-10-27  Antoine Labour  <[email protected]>
+
+        Disable blending when drawing opaque layers
+        https://bugs.webkit.org/show_bug.cgi?id=70085
+
+        Reviewed by James Robinson.
+
+        Covered by compositing/ tests, as well as a new unit test:
+        CCLayerTreeHostImplTest.blendingOffWhenDrawingOpaqueLayers
+
+        * platform/graphics/chromium/LayerChromium.cpp:
+        (WebCore::LayerChromium::LayerChromium):
+        (WebCore::LayerChromium::pushPropertiesTo):
+        * platform/graphics/chromium/LayerRendererChromium.cpp:
+        (WebCore::LayerRendererChromium::drawLayer):
+        * platform/graphics/chromium/cc/CCLayerImpl.cpp:
+        (WebCore::CCLayerImpl::CCLayerImpl):
+        * platform/graphics/chromium/cc/CCLayerImpl.h:
+        (WebCore::CCLayerImpl::setOpaque):
+        (WebCore::CCLayerImpl::opaque):
+
 2011-10-27  Joshua Bell  <[email protected]>
 
         IndexedDB: Passing empty array to IDBDatabase.transaction should raise exception

Modified: trunk/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp (98566 => 98567)


--- trunk/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp	2011-10-27 14:03:32 UTC (rev 98566)
+++ trunk/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp	2011-10-27 14:23:49 UTC (rev 98567)
@@ -288,6 +288,7 @@
     layer->setMasksToBounds(m_masksToBounds);
     layer->setMaxScrollPosition(m_maxScrollPosition);
     layer->setName(m_name);
+    layer->setOpaque(m_opaque);
     layer->setOpacity(m_opacity);
     layer->setPosition(m_position);
     layer->setPreserves3D(preserves3D());

Modified: trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp (98566 => 98567)


--- trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp	2011-10-27 14:03:32 UTC (rev 98566)
+++ trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp	2011-10-27 14:23:49 UTC (rev 98567)
@@ -587,8 +587,15 @@
     else
         GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST));
 
+    bool opaque = layer->opaque() && layer->drawOpacity() == 1;
+    if (opaque)
+        GLC(m_context.get(), m_context->disable(GraphicsContext3D::BLEND));
+
     layer->draw(this);
 
+    if (opaque)
+        GLC(m_context.get(), m_context->enable(GraphicsContext3D::BLEND));
+
     // Draw the debug border if there is one.
     layer->drawDebugBorder(this);
 }

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp (98566 => 98567)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp	2011-10-27 14:03:32 UTC (rev 98566)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp	2011-10-27 14:23:49 UTC (rev 98567)
@@ -44,6 +44,7 @@
     , m_anchorPointZ(0)
     , m_doubleSided(true)
     , m_masksToBounds(false)
+    , m_opaque(false)
     , m_opacity(1.0)
     , m_preserves3D(false)
     , m_usesLayerScissor(false)

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h (98566 => 98567)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h	2011-10-27 14:03:32 UTC (rev 98566)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h	2011-10-27 14:23:49 UTC (rev 98567)
@@ -92,6 +92,9 @@
     void setMasksToBounds(bool masksToBounds) { m_masksToBounds = masksToBounds; }
     bool masksToBounds() const { return m_masksToBounds; }
 
+    void setOpaque(bool opaque) { m_opaque = opaque; }
+    bool opaque() const { return m_opaque; }
+
     void setOpacity(float opacity) { m_opacity = opacity; }
     float opacity() const { return m_opacity; }
 
@@ -209,6 +212,7 @@
 
     IntRect m_visibleLayerRect;
     bool m_masksToBounds;
+    bool m_opaque;
     float m_opacity;
     FloatPoint m_position;
     bool m_preserves3D;

Modified: trunk/Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp (98566 => 98567)


--- trunk/Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp	2011-10-27 14:03:32 UTC (rev 98566)
+++ trunk/Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp	2011-10-27 14:23:49 UTC (rev 98567)
@@ -26,11 +26,15 @@
 
 #include "cc/CCLayerTreeHostImpl.h"
 
+#include "GraphicsContext3DPrivate.h"
+#include "LayerRendererChromium.h"
+#include "MockWebGraphicsContext3D.h"
 #include "cc/CCLayerImpl.h"
 #include "cc/CCSingleThreadProxy.h"
 #include <gtest/gtest.h>
 
 using namespace WebCore;
+using namespace WebKit;
 
 namespace {
 
@@ -151,4 +155,139 @@
     ASSERT(m_didRequestCommit);
 }
 
+class BlendStateTrackerContext: public MockWebGraphicsContext3D {
+public:
+    BlendStateTrackerContext() : m_blend(false) { }
+
+    virtual bool initialize(Attributes, WebView*, bool renderDirectlyToWebView) { return true; }
+
+    virtual void enable(WGC3Denum cap)
+    {
+        if (cap == GraphicsContext3D::BLEND)
+            m_blend = true;
+    }
+
+    virtual void disable(WGC3Denum cap)
+    {
+        if (cap == GraphicsContext3D::BLEND)
+            m_blend = false;
+    }
+
+    bool blend() const { return m_blend; }
+
+private:
+    bool m_blend;
+};
+
+class BlendStateCheckLayer : public CCLayerImpl {
+public:
+    static PassRefPtr<BlendStateCheckLayer> create(int id) { return adoptRef(new BlendStateCheckLayer(id)); }
+
+    virtual void draw(LayerRendererChromium* renderer)
+    {
+        m_drawn = true;
+        BlendStateTrackerContext* context = static_cast<BlendStateTrackerContext*>(GraphicsContext3DPrivate::extractWebGraphicsContext3D(renderer->context()));
+        EXPECT_EQ(m_blend, context->blend());
+        EXPECT_EQ(m_hasRenderSurface, !!renderSurface());
+    }
+
+    void setExpectation(bool blend, bool hasRenderSurface)
+    {
+        m_blend = blend;
+        m_hasRenderSurface = hasRenderSurface;
+        m_drawn = false;
+    }
+
+    bool drawn() const { return m_drawn; }
+
+private:
+    explicit BlendStateCheckLayer(int id)
+        : CCLayerImpl(id)
+        , m_blend(false)
+        , m_hasRenderSurface(false)
+        , m_drawn(false)
+    {
+        setAnchorPoint(FloatPoint(0, 0));
+        setBounds(IntSize(10, 10));
+        setDrawsContent(true);
+    }
+
+    bool m_blend;
+    bool m_hasRenderSurface;
+    bool m_drawn;
+};
+
+TEST_F(CCLayerTreeHostImplTest, blendingOffWhenDrawingOpaqueLayers)
+{
+    GraphicsContext3D::Attributes attrs;
+    RefPtr<GraphicsContext3D> context = GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(new BlendStateTrackerContext()), attrs, 0, GraphicsContext3D::RenderDirectlyToHostWindow, GraphicsContext3DPrivate::ForUseOnThisThread);
+    m_hostImpl->initializeLayerRenderer(context);
+    m_hostImpl->setViewport(IntSize(10, 10));
+
+    RefPtr<CCLayerImpl> root = CCLayerImpl::create(0);
+    root->setAnchorPoint(FloatPoint(0, 0));
+    root->setBounds(IntSize(10, 10));
+    root->setDrawsContent(false);
+    m_hostImpl->setRootLayer(root);
+
+    RefPtr<BlendStateCheckLayer> layer1 = BlendStateCheckLayer::create(1);
+    root->addChild(layer1);
+
+    // Opaque layer, drawn without blending.
+    layer1->setOpaque(true);
+    layer1->setExpectation(false, false);
+    m_hostImpl->drawLayers();
+    EXPECT_TRUE(layer1->drawn());
+
+    // Layer with translucent content, drawn with blending.
+    layer1->setOpaque(false);
+    layer1->setExpectation(true, false);
+    m_hostImpl->drawLayers();
+    EXPECT_TRUE(layer1->drawn());
+
+    // Layer with translucent opacity, drawn with blending.
+    layer1->setOpaque(true);
+    layer1->setOpacity(0.5);
+    layer1->setExpectation(true, false);
+    m_hostImpl->drawLayers();
+    EXPECT_TRUE(layer1->drawn());
+
+    RefPtr<BlendStateCheckLayer> layer2 = BlendStateCheckLayer::create(2);
+    layer1->addChild(layer2);
+
+    // 2 opaque layers, drawn without blending.
+    layer1->setOpaque(true);
+    layer1->setOpacity(1);
+    layer1->setExpectation(false, false);
+    layer2->setOpaque(true);
+    layer2->setOpacity(1);
+    layer2->setExpectation(false, false);
+    m_hostImpl->drawLayers();
+    EXPECT_TRUE(layer1->drawn());
+    EXPECT_TRUE(layer2->drawn());
+
+    // Parent layer with translucent content, drawn with blending.
+    // Child layer with opaque content, drawn without blending.
+    layer1->setOpaque(false);
+    layer1->setExpectation(true, false);
+    layer2->setExpectation(false, false);
+    m_hostImpl->drawLayers();
+    EXPECT_TRUE(layer1->drawn());
+    EXPECT_TRUE(layer2->drawn());
+
+    // Parent layer with translucent opacity and opaque content. Since it has a
+    // drawing child, it's drawn to a render surface which carries the opacity,
+    // so it's itself drawn without blending.
+    // Child layer with opaque content, drawn without blending (parent surface
+    // carries the inherited opacity).
+    layer1->setOpaque(true);
+    layer1->setOpacity(0.5);
+    layer1->setExpectation(false, true);
+    layer2->setExpectation(false, false);
+    m_hostImpl->drawLayers();
+    EXPECT_TRUE(layer1->drawn());
+    EXPECT_TRUE(layer2->drawn());
+}
+
+
 } // namespace

Modified: trunk/Source/WebKit/chromium/tests/MockWebGraphicsContext3D.h (98566 => 98567)


--- trunk/Source/WebKit/chromium/tests/MockWebGraphicsContext3D.h	2011-10-27 14:03:32 UTC (rev 98566)
+++ trunk/Source/WebKit/chromium/tests/MockWebGraphicsContext3D.h	2011-10-27 14:23:49 UTC (rev 98567)
@@ -26,6 +26,7 @@
 #ifndef MockWebGraphicsContext3D_h
 #define MockWebGraphicsContext3D_h
 
+#include "GraphicsContext3D.h"
 #include "WebGraphicsContext3D.h"
 
 namespace WebKit {
@@ -84,7 +85,11 @@
     virtual void bufferData(WGC3Denum target, WGC3Dsizeiptr size, const void* data, WGC3Denum usage) { }
     virtual void bufferSubData(WGC3Denum target, WGC3Dintptr offset, WGC3Dsizeiptr size, const void* data) { }
 
-    virtual WGC3Denum checkFramebufferStatus(WGC3Denum target) { return 0; }
+    virtual WGC3Denum checkFramebufferStatus(WGC3Denum target)
+    {
+        return WebCore::GraphicsContext3D::FRAMEBUFFER_COMPLETE;
+    }
+
     virtual void clear(WGC3Dbitfield mask) { }
     virtual void clearColor(WGC3Dclampf red, WGC3Dclampf green, WGC3Dclampf blue, WGC3Dclampf alpha) { }
     virtual void clearDepth(WGC3Dclampf depth) { }
@@ -123,11 +128,28 @@
     virtual WGC3Denum getError() { return 0; }
     virtual void getFloatv(WGC3Denum pname, WGC3Dfloat* value) { }
     virtual void getFramebufferAttachmentParameteriv(WGC3Denum target, WGC3Denum attachment, WGC3Denum pname, WGC3Dint* value) { }
-    virtual void getIntegerv(WGC3Denum pname, WGC3Dint* value) { }
-    virtual void getProgramiv(WebGLId program, WGC3Denum pname, WGC3Dint* value) { }
+
+    virtual void getIntegerv(WGC3Denum pname, WGC3Dint* value)
+    {
+        if (pname == WebCore::GraphicsContext3D::MAX_TEXTURE_SIZE)
+            *value = 1024;
+    }
+
+    virtual void getProgramiv(WebGLId program, WGC3Denum pname, WGC3Dint* value)
+    {
+        if (pname == WebCore::GraphicsContext3D::LINK_STATUS)
+            *value = 1;
+    }
+
     virtual WebString getProgramInfoLog(WebGLId program) { return WebString(); }
     virtual void getRenderbufferParameteriv(WGC3Denum target, WGC3Denum pname, WGC3Dint* value) { }
-    virtual void getShaderiv(WebGLId shader, WGC3Denum pname, WGC3Dint* value) { }
+
+    virtual void getShaderiv(WebGLId shader, WGC3Denum pname, WGC3Dint* value)
+    {
+        if (pname == WebCore::GraphicsContext3D::COMPILE_STATUS)
+            *value = 1;
+    }
+
     virtual WebString getShaderInfoLog(WebGLId shader) { return WebString(); }
 
     virtual WebString getShaderSource(WebGLId shader) { return WebString(); }
@@ -212,12 +234,12 @@
 
     virtual void viewport(WGC3Dint x, WGC3Dint y, WGC3Dsizei width, WGC3Dsizei height) { }
 
-    virtual WebGLId createBuffer() { return 0; }
-    virtual WebGLId createFramebuffer() { return 0; }
-    virtual WebGLId createProgram() { return 0; }
-    virtual WebGLId createRenderbuffer() { return 0; }
-    virtual WebGLId createShader(WGC3Denum) { return 0; }
-    virtual WebGLId createTexture() { return 0; }
+    virtual WebGLId createBuffer() { return 1; }
+    virtual WebGLId createFramebuffer() { return 1; }
+    virtual WebGLId createProgram() { return 1; }
+    virtual WebGLId createRenderbuffer() { return 1; }
+    virtual WebGLId createShader(WGC3Denum) { return 1; }
+    virtual WebGLId createTexture() { return 1; }
 
     virtual void deleteBuffer(WebGLId) { }
     virtual void deleteFramebuffer(WebGLId) { }
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to