[chromium] Paint scrollbars on WebKit thread and composite those textures
authorenne@google.com <enne@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 12 Jun 2012 23:04:17 +0000 (23:04 +0000)
committerenne@google.com <enne@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 12 Jun 2012 23:04:17 +0000 (23:04 +0000)
https://bugs.webkit.org/show_bug.cgi?id=88145

Reviewed by James Robinson.

Source/WebCore:

Scrollbars were previously painted and uploaded on the compositor
thread. This isn't possible to do for many scrollbar themes. This
patch changes ScrollbarLayerChromium to paint the scrollbar into two
parts: the thumb, and everything else. These are uploaded into
textures and synced over to the CCScrollbarImpl where they are
composited and drawn.

Mac and overlay scrollbars are still not enabled to have compositor
thread-updated scrollbars.

As a bonus, fix LayerRendererChromium::drawTextureQuad to draw quads
that do not fill the entire layer bounds.

Tested by existing layout and unit tests by removing the condition
that these scrollbar layers are only created when the threaded proxy
exists.

* page/scrolling/chromium/ScrollingCoordinatorChromium.cpp:
(WebCore::scrollbarLayerDidChange):
* platform/ScrollbarThemeComposite.cpp:
(WebCore::ScrollbarThemeComposite::thumbRect):
(WebCore):
* platform/ScrollbarThemeComposite.h:
(ScrollbarThemeComposite):
* platform/graphics/chromium/LayerRendererChromium.cpp:
(WebCore::LayerRendererChromium::drawTextureQuad):
* platform/graphics/chromium/ScrollbarLayerChromium.cpp:
(WebCore::ScrollbarLayerChromium::ScrollbarLayerChromium):
(WebCore::ScrollbarLayerChromium::theme):
(WebCore):
(WebCore::ScrollbarLayerChromium::pushPropertiesTo):
(ScrollbarBackgroundPainter):
(WebCore::ScrollbarBackgroundPainter::create):
(WebCore::ScrollbarBackgroundPainter::paint):
(WebCore::ScrollbarBackgroundPainter::ScrollbarBackgroundPainter):
(ScrollbarThumbPainter):
(WebCore::ScrollbarThumbPainter::create):
(WebCore::ScrollbarThumbPainter::paint):
(WebCore::ScrollbarThumbPainter::ScrollbarThumbPainter):
(WebCore::ScrollbarLayerChromium::setLayerTreeHost):
(WebCore::ScrollbarLayerChromium::createTextureUpdaterIfNeeded):
(WebCore::ScrollbarLayerChromium::updatePart):
(WebCore::ScrollbarLayerChromium::update):
* platform/graphics/chromium/ScrollbarLayerChromium.h:
(WebCore):
(ScrollbarLayerChromium):
* platform/graphics/chromium/cc/CCScrollbarLayerImpl.cpp:
(WebCore::CCScrollbarLayerImpl::CCScrollbarLayerImpl):
(WebCore::CCScrollbarLayerImpl::appendQuads):
* platform/graphics/chromium/cc/CCScrollbarLayerImpl.h:
(WebCore::CCScrollbarLayerImpl::setBackgroundTextureId):
(WebCore::CCScrollbarLayerImpl::setThumbTextureId):
(CCScrollbarLayerImpl):

Source/WebKit/chromium:

Remove scrollbarLayerLostContext test that no longer makes sense. The
compositor won't draw at all after a lost context if it has no
contents.

* tests/CCLayerTreeHostImplTest.cpp:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@120135 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/page/scrolling/chromium/ScrollingCoordinatorChromium.cpp
Source/WebCore/platform/ScrollbarThemeComposite.cpp
Source/WebCore/platform/ScrollbarThemeComposite.h
Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
Source/WebCore/platform/graphics/chromium/ScrollbarLayerChromium.cpp
Source/WebCore/platform/graphics/chromium/ScrollbarLayerChromium.h
Source/WebCore/platform/graphics/chromium/cc/CCScrollbarLayerImpl.cpp
Source/WebCore/platform/graphics/chromium/cc/CCScrollbarLayerImpl.h
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp

index c5b1fdc..4996ec5 100644 (file)
@@ -1,3 +1,64 @@
+2012-06-12  Adrienne Walker  <enne@google.com>
+
+        [chromium] Paint scrollbars on WebKit thread and composite those textures
+        https://bugs.webkit.org/show_bug.cgi?id=88145
+
+        Reviewed by James Robinson.
+
+        Scrollbars were previously painted and uploaded on the compositor
+        thread. This isn't possible to do for many scrollbar themes. This
+        patch changes ScrollbarLayerChromium to paint the scrollbar into two
+        parts: the thumb, and everything else. These are uploaded into
+        textures and synced over to the CCScrollbarImpl where they are
+        composited and drawn.
+
+        Mac and overlay scrollbars are still not enabled to have compositor
+        thread-updated scrollbars.
+
+        As a bonus, fix LayerRendererChromium::drawTextureQuad to draw quads
+        that do not fill the entire layer bounds.
+
+        Tested by existing layout and unit tests by removing the condition
+        that these scrollbar layers are only created when the threaded proxy
+        exists.
+
+        * page/scrolling/chromium/ScrollingCoordinatorChromium.cpp:
+        (WebCore::scrollbarLayerDidChange):
+        * platform/ScrollbarThemeComposite.cpp:
+        (WebCore::ScrollbarThemeComposite::thumbRect):
+        (WebCore):
+        * platform/ScrollbarThemeComposite.h:
+        (ScrollbarThemeComposite):
+        * platform/graphics/chromium/LayerRendererChromium.cpp:
+        (WebCore::LayerRendererChromium::drawTextureQuad):
+        * platform/graphics/chromium/ScrollbarLayerChromium.cpp:
+        (WebCore::ScrollbarLayerChromium::ScrollbarLayerChromium):
+        (WebCore::ScrollbarLayerChromium::theme):
+        (WebCore):
+        (WebCore::ScrollbarLayerChromium::pushPropertiesTo):
+        (ScrollbarBackgroundPainter):
+        (WebCore::ScrollbarBackgroundPainter::create):
+        (WebCore::ScrollbarBackgroundPainter::paint):
+        (WebCore::ScrollbarBackgroundPainter::ScrollbarBackgroundPainter):
+        (ScrollbarThumbPainter):
+        (WebCore::ScrollbarThumbPainter::create):
+        (WebCore::ScrollbarThumbPainter::paint):
+        (WebCore::ScrollbarThumbPainter::ScrollbarThumbPainter):
+        (WebCore::ScrollbarLayerChromium::setLayerTreeHost):
+        (WebCore::ScrollbarLayerChromium::createTextureUpdaterIfNeeded):
+        (WebCore::ScrollbarLayerChromium::updatePart):
+        (WebCore::ScrollbarLayerChromium::update):
+        * platform/graphics/chromium/ScrollbarLayerChromium.h:
+        (WebCore):
+        (ScrollbarLayerChromium):
+        * platform/graphics/chromium/cc/CCScrollbarLayerImpl.cpp:
+        (WebCore::CCScrollbarLayerImpl::CCScrollbarLayerImpl):
+        (WebCore::CCScrollbarLayerImpl::appendQuads):
+        * platform/graphics/chromium/cc/CCScrollbarLayerImpl.h:
+        (WebCore::CCScrollbarLayerImpl::setBackgroundTextureId):
+        (WebCore::CCScrollbarLayerImpl::setThumbTextureId):
+        (CCScrollbarLayerImpl):
+
 2012-06-12  Tony Chang  <tony@chromium.org>
 
         Replaced items in a flexbox should be coerced to display:block
index bce391f..0e77f3a 100644 (file)
@@ -120,14 +120,13 @@ static PassRefPtr<ScrollbarLayerChromium> createScrollbarLayer(Scrollbar* scroll
     if (!scrollbarGraphicsLayer->contentsOpaque())
         scrollbarGraphicsLayer->setContentsOpaque(isOpaqueRootScrollbar);
 
-    // Only certain platforms support the way that scrollbars are currently
-    // being painted on the impl thread. For example, Cocoa is not threadsafe.
-    bool platformSupported = false;
-#if OS(LINUX)
-    platformSupported = true;
+    // FIXME: Mac scrollbar themes are not thread-safe.
+    bool platformSupported = true;
+#if OS(DARWIN)
+    platformSupported = false;
 #endif
 
-    if (scrollbar->isCustomScrollbar() || !CCProxy::hasImplThread() || !platformSupported) {
+    if (!platformSupported || scrollbar->isOverlayScrollbar()) {
         scrollbarGraphicsLayer->setContentsToMedia(0);
         scrollbarGraphicsLayer->setDrawsContent(true);
         return 0;
index bc89bc6..b784cc3 100644 (file)
@@ -271,6 +271,20 @@ void ScrollbarThemeComposite::paintScrollCorner(ScrollView*, GraphicsContext* co
     context->fillRect(cornerRect, Color::white, ColorSpaceDeviceRGB);
 }
 
+IntRect ScrollbarThemeComposite::thumbRect(ScrollbarThemeClient* scrollbar)
+{
+    if (!hasThumb(scrollbar))
+        return IntRect();
+
+    IntRect track = trackRect(scrollbar);
+    IntRect startTrackRect;
+    IntRect thumbRect;
+    IntRect endTrackRect;
+    splitTrack(scrollbar, track, startTrackRect, thumbRect, endTrackRect);
+
+    return thumbRect;
+}
+
 void ScrollbarThemeComposite::paintOverhangAreas(ScrollView*, GraphicsContext* context, const IntRect& horizontalOverhangRect, const IntRect& verticalOverhangRect, const IntRect& dirtyRect)
 {    
     context->setFillColor(Color::white, ColorSpaceDeviceRGB);
index 8f62913..696db12 100644 (file)
@@ -32,27 +32,24 @@ namespace WebCore {
 
 class ScrollbarThemeComposite : public ScrollbarTheme {
 public:
+    // Implement ScrollbarTheme interface
     virtual bool paint(ScrollbarThemeClient*, GraphicsContext*, const IntRect& damageRect);
-
     virtual ScrollbarPart hitTest(ScrollbarThemeClient*, const PlatformMouseEvent&);
-
     virtual void invalidatePart(ScrollbarThemeClient*, ScrollbarPart);
-
     virtual int thumbPosition(ScrollbarThemeClient*);
     virtual int thumbLength(ScrollbarThemeClient*);
     virtual int trackPosition(ScrollbarThemeClient*);
     virtual int trackLength(ScrollbarThemeClient*);
-
     virtual void paintScrollCorner(ScrollView*, GraphicsContext*, const IntRect& cornerRect);
     virtual void paintOverhangAreas(ScrollView*, GraphicsContext*, const IntRect& horizontalOverhangArea, const IntRect& verticalOverhangArea, const IntRect& dirtyRect);
 
-protected:
     virtual bool hasButtons(ScrollbarThemeClient*) = 0;
     virtual bool hasThumb(ScrollbarThemeClient*) = 0;
 
     virtual IntRect backButtonRect(ScrollbarThemeClient*, ScrollbarPart, bool painting = false) = 0;
     virtual IntRect forwardButtonRect(ScrollbarThemeClient*, ScrollbarPart, bool painting = false) = 0;
     virtual IntRect trackRect(ScrollbarThemeClient*, bool painting = false) = 0;
+    virtual IntRect thumbRect(ScrollbarThemeClient*);
 
     virtual void splitTrack(ScrollbarThemeClient*, const IntRect& track, IntRect& startTrack, IntRect& thumb, IntRect& endTrack);
     
index 3e2088a..0e5af41 100644 (file)
@@ -1130,9 +1130,11 @@ void LayerRendererChromium::drawTextureQuad(const CCTextureDrawQuad* quad)
     if (!quad->premultipliedAlpha())
         GLC(context(), context()->blendFunc(GraphicsContext3D::SRC_ALPHA, GraphicsContext3D::ONE_MINUS_SRC_ALPHA));
 
-    const IntSize& bounds = quad->quadRect().size();
+    WebTransformationMatrix quadTransform = quad->quadTransform();
+    IntRect quadRect = quad->quadRect();
+    quadTransform.translate(quadRect.x() + quadRect.width() / 2.0, quadRect.y() + quadRect.height() / 2.0);
 
-    drawTexturedQuad(quad->layerTransform(), bounds.width(), bounds.height(), quad->opacity(), sharedGeometryQuad(), binding.matrixLocation, binding.alphaLocation, -1);
+    drawTexturedQuad(quadTransform, quadRect.width(), quadRect.height(), quad->opacity(), sharedGeometryQuad(), binding.matrixLocation, binding.alphaLocation, -1);
 
     if (!quad->premultipliedAlpha())
         GLC(m_context, m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA));
index 4f7ef93..f061580 100644 (file)
 
 #include "ScrollbarLayerChromium.h"
 
+#include "BitmapCanvasLayerTextureUpdater.h"
+#include "LayerPainterChromium.h"
 #include "Scrollbar.h"
+#include "ScrollbarThemeComposite.h"
+#include "cc/CCLayerTreeHost.h"
 #include "cc/CCScrollbarLayerImpl.h"
+#include "cc/CCTextureUpdater.h"
 
 namespace WebCore {
 
@@ -46,6 +51,7 @@ PassRefPtr<ScrollbarLayerChromium> ScrollbarLayerChromium::create(Scrollbar* scr
 ScrollbarLayerChromium::ScrollbarLayerChromium(Scrollbar* scrollbar, int scrollLayerId)
     : m_scrollbar(scrollbar)
     , m_scrollLayerId(scrollLayerId)
+    , m_textureFormat(GraphicsContext3D::INVALID_ENUM)
     , m_scrollbarOverlayStyle(scrollbar->scrollbarOverlayStyle())
     , m_isScrollableAreaActive(scrollbar->isScrollableAreaActive())
     , m_isScrollViewScrollbar(scrollbar->isScrollViewScrollbar())
@@ -54,6 +60,12 @@ ScrollbarLayerChromium::ScrollbarLayerChromium(Scrollbar* scrollbar, int scrollL
 {
 }
 
+ScrollbarThemeComposite* ScrollbarLayerChromium::theme() const
+{
+    // All Chromium scrollbars are ScrollbarThemeComposite-derived.
+    return static_cast<ScrollbarThemeComposite*>(m_scrollbar->theme());
+}
+
 void ScrollbarLayerChromium::pushPropertiesTo(CCLayerImpl* layer)
 {
     LayerChromium::pushPropertiesTo(layer);
@@ -62,6 +74,16 @@ void ScrollbarLayerChromium::pushPropertiesTo(CCLayerImpl* layer)
 
     scrollbarLayer->setScrollbarOverlayStyle(m_scrollbarOverlayStyle);
 
+    if (m_background && m_background->texture()->isReserved())
+        scrollbarLayer->setBackgroundTextureId(m_background->texture()->textureId());
+    else
+        scrollbarLayer->setBackgroundTextureId(0);
+
+    if (m_thumb && m_thumb->texture()->isReserved())
+        scrollbarLayer->setThumbTextureId(m_thumb->texture()->textureId());
+    else
+        scrollbarLayer->setThumbTextureId(0);
+
     Vector<IntRect> tickmarks;
     m_scrollbar->getTickmarks(tickmarks);
     scrollbarLayer->setTickmarks(tickmarks);
@@ -79,5 +101,157 @@ void ScrollbarLayerChromium::pushPropertiesTo(CCLayerImpl* layer)
     scrollbarLayer->setEnabled(m_scrollbar->enabled());
 }
 
+class ScrollbarBackgroundPainter : public LayerPainterChromium {
+    WTF_MAKE_NONCOPYABLE(ScrollbarBackgroundPainter);
+public:
+    static PassOwnPtr<ScrollbarBackgroundPainter> create(ScrollbarThemeClient* scrollbar, ScrollbarThemeComposite* theme)
+    {
+        return adoptPtr(new ScrollbarBackgroundPainter(scrollbar, theme));
+    }
+
+    virtual void paint(GraphicsContext& context, const IntRect& contentRect)
+    {
+        // The following is a simplification of ScrollbarThemeComposite::paint.
+        m_theme->paintScrollbarBackground(&context, m_scrollbar);
+
+        if (m_theme->hasButtons(m_scrollbar)) {
+            IntRect backButtonStartPaintRect = m_theme->backButtonRect(m_scrollbar, BackButtonStartPart, true);
+            m_theme->paintButton(&context, m_scrollbar, backButtonStartPaintRect, BackButtonStartPart);
+
+            IntRect backButtonEndPaintRect = m_theme->backButtonRect(m_scrollbar, BackButtonEndPart, true);
+            m_theme->paintButton(&context, m_scrollbar, backButtonEndPaintRect, BackButtonEndPart);
+
+            IntRect forwardButtonStartPaintRect = m_theme->forwardButtonRect(m_scrollbar, ForwardButtonStartPart, true);
+            m_theme->paintButton(&context, m_scrollbar, forwardButtonStartPaintRect, ForwardButtonStartPart);
+
+            IntRect forwardButtonEndPaintRect = m_theme->forwardButtonRect(m_scrollbar, ForwardButtonEndPart, true);
+            m_theme->paintButton(&context, m_scrollbar, forwardButtonEndPaintRect, ForwardButtonEndPart);
+        }
+
+        IntRect trackPaintRect = m_theme->trackRect(m_scrollbar, true);
+        m_theme->paintTrackBackground(&context, m_scrollbar, trackPaintRect);
+
+        bool thumbPresent = m_theme->hasThumb(m_scrollbar);
+        if (thumbPresent) {
+            // FIXME: There's no "paint the whole track" part. Drawing both the
+            // BackTrackPart and the ForwardTrackPart in their splitTrack rects
+            // ends up leaving a distinctive line. Painting one part as the
+            // entire track appears to be identical to painting both and
+            // covering up the split between them with the thumb.
+            m_theme->paintTrackPiece(&context, m_scrollbar, trackPaintRect, BackTrackPart);
+        }
+
+        m_theme->paintTickmarks(&context, m_scrollbar, trackPaintRect);
+    }
+private:
+    ScrollbarBackgroundPainter(ScrollbarThemeClient* scrollbar, ScrollbarThemeComposite* theme)
+        : m_scrollbar(scrollbar)
+        , m_theme(theme)
+    {
+    }
+
+    ScrollbarThemeClient* m_scrollbar;
+    ScrollbarThemeComposite* m_theme;
+};
+
+class ScrollbarThumbPainter : public LayerPainterChromium {
+    WTF_MAKE_NONCOPYABLE(ScrollbarThumbPainter);
+public:
+    static PassOwnPtr<ScrollbarThumbPainter> create(ScrollbarThemeClient* scrollbar, ScrollbarThemeComposite* theme)
+    {
+        return adoptPtr(new ScrollbarThumbPainter(scrollbar, theme));
+    }
+
+    virtual void paint(GraphicsContext& context, const IntRect& contentRect)
+    {
+        context.clearRect(contentRect);
+
+        // Consider the thumb to be at the origin when painting.
+        IntRect thumbRect = IntRect(IntPoint(), m_theme->thumbRect(m_scrollbar).size());
+        m_theme->paintThumb(&context, m_scrollbar, thumbRect);
+    }
+
+private:
+    ScrollbarThumbPainter(ScrollbarThemeClient* scrollbar, ScrollbarThemeComposite* theme)
+        : m_scrollbar(scrollbar)
+        , m_theme(theme)
+    {
+    }
+
+    ScrollbarThemeClient* m_scrollbar;
+    ScrollbarThemeComposite* m_theme;
+};
+
+void ScrollbarLayerChromium::setLayerTreeHost(CCLayerTreeHost* host)
+{
+    if (!host || host != layerTreeHost()) {
+        m_backgroundUpdater.clear();
+        m_background.clear();
+        m_thumbUpdater.clear();
+        m_thumb.clear();
+    }
+
+    LayerChromium::setLayerTreeHost(host);
+}
+
+void ScrollbarLayerChromium::createTextureUpdaterIfNeeded()
+{
+    bool useMapSubImage = layerTreeHost()->layerRendererCapabilities().usingMapSub;
+    m_textureFormat = layerTreeHost()->layerRendererCapabilities().bestTextureFormat;
+
+    if (!m_backgroundUpdater)
+        m_backgroundUpdater = BitmapCanvasLayerTextureUpdater::create(ScrollbarBackgroundPainter::create(m_scrollbar.get(), theme()), useMapSubImage);
+    if (!m_background)
+        m_background = m_backgroundUpdater->createTexture(layerTreeHost()->contentsTextureManager());
+
+    if (!m_thumbUpdater)
+        m_thumbUpdater = BitmapCanvasLayerTextureUpdater::create(ScrollbarThumbPainter::create(m_scrollbar.get(), theme()), useMapSubImage);
+    if (!m_thumb)
+        m_thumb = m_thumbUpdater->createTexture(layerTreeHost()->contentsTextureManager());
+}
+
+void ScrollbarLayerChromium::updatePart(LayerTextureUpdater* painter, LayerTextureUpdater::Texture* texture, const IntRect& rect, CCTextureUpdater& updater)
+{
+    bool textureValid = texture->texture()->isValid(rect.size(), m_textureFormat);
+    // Skip painting and uploading if there are no invalidations.
+    if (textureValid && m_updateRect.isEmpty()) {
+        texture->texture()->reserve(rect.size(), m_textureFormat);
+        return;
+    }
+
+    // ScrollbarLayerChromium doesn't support partial uploads, so any
+    // invalidation is treated a full layer invalidation.
+    if (layerTreeHost()->bufferedUpdates() && textureValid)
+        layerTreeHost()->deleteTextureAfterCommit(texture->texture()->steal());
+
+    if (!texture->texture()->reserve(rect.size(), m_textureFormat))
+        return;
+
+    // Paint and upload the entire part.
+    IntRect paintedOpaqueRect;
+    painter->prepareToUpdate(rect, rect.size(), false, 1, paintedOpaqueRect);
+    texture->prepareRect(rect);
+
+    IntRect destRect(IntPoint(), rect.size());
+    updater.appendUpdate(texture, rect, destRect);
+}
+
+void ScrollbarLayerChromium::update(CCTextureUpdater& updater, const CCOcclusionTracker*)
+{
+    if (contentBounds().isEmpty())
+        return;
+
+    createTextureUpdaterIfNeeded();
+
+    IntPoint scrollbarOrigin(m_scrollbar->x(), m_scrollbar->y());
+    IntRect contentRect(scrollbarOrigin, contentBounds());
+    updatePart(m_backgroundUpdater.get(), m_background.get(), contentRect, updater);
+
+    // Consider the thumb to be at the origin when painting.
+    IntRect thumbRect = IntRect(IntPoint(), theme()->thumbRect(m_scrollbar.get()).size());
+    if (!thumbRect.isEmpty())
+        updatePart(m_thumbUpdater.get(), m_thumb.get(), thumbRect, updater);
+}
+
 }
 #endif // USE(ACCELERATED_COMPOSITING)
index 8926a4d..af2215b 100644 (file)
 #if USE(ACCELERATED_COMPOSITING)
 
 #include "LayerChromium.h"
+#include "LayerTextureUpdater.h"
 #include "ScrollTypes.h"
 
 namespace WebCore {
 
 class Scrollbar;
+class ScrollbarThemeComposite;
+class CCTextureUpdater;
 
 class ScrollbarLayerChromium : public LayerChromium {
 public:
     virtual PassOwnPtr<CCLayerImpl> createCCLayerImpl();
     static PassRefPtr<ScrollbarLayerChromium> create(Scrollbar*, int scrollLayerId);
 
-    virtual void pushPropertiesTo(CCLayerImpl*);
+    // LayerChromium interface
+    virtual void update(CCTextureUpdater&, const CCOcclusionTracker*) OVERRIDE;
+    virtual void setLayerTreeHost(CCLayerTreeHost*) OVERRIDE;
+    virtual void pushPropertiesTo(CCLayerImpl*) OVERRIDE;
 
     int scrollLayerId() const { return m_scrollLayerId; }
     void setScrollLayerId(int id) { m_scrollLayerId = id; }
@@ -51,9 +57,22 @@ protected:
     ScrollbarLayerChromium(Scrollbar*, int scrollLayerId);
 
 private:
+    ScrollbarThemeComposite* theme() const;
+    void updatePart(LayerTextureUpdater*, LayerTextureUpdater::Texture*, const IntRect&, CCTextureUpdater&);
+    void createTextureUpdaterIfNeeded();
+
     RefPtr<Scrollbar> m_scrollbar;
     int m_scrollLayerId;
 
+    GC3Denum m_textureFormat;
+
+    RefPtr<LayerTextureUpdater> m_backgroundUpdater;
+    RefPtr<LayerTextureUpdater> m_thumbUpdater;
+
+    // All the parts of the scrollbar except the thumb
+    OwnPtr<LayerTextureUpdater::Texture> m_background;
+    OwnPtr<LayerTextureUpdater::Texture> m_thumb;
+
     ScrollbarOverlayStyle m_scrollbarOverlayStyle;
     bool m_isScrollableAreaActive;
     bool m_isScrollViewScrollbar;
index d19484c..45b16fa 100644 (file)
 
 #include "CCScrollbarLayerImpl.h"
 
-#include "CCTileDrawQuad.h"
 #include "LayerRendererChromium.h"
 #include "ManagedTexture.h"
 #include "PlatformCanvas.h"
 #include "ScrollbarTheme.h"
+#include "ScrollbarThemeComposite.h"
 #include "cc/CCQuadCuller.h"
+#include "cc/CCTextureDrawQuad.h"
 
 namespace WebCore {
 
@@ -47,74 +48,32 @@ CCScrollbarLayerImpl::CCScrollbarLayerImpl(int id)
     : CCLayerImpl(id)
     , m_scrollLayer(0)
     , m_scrollbar(this)
+    , m_backgroundTextureId(0)
+    , m_thumbTextureId(0)
 {
 }
 
-void CCScrollbarLayerImpl::willDraw(CCRenderer* layerRenderer, CCGraphicsContext* context)
-{
-    CCLayerImpl::willDraw(layerRenderer, context);
-
-    if (bounds().isEmpty() || contentBounds().isEmpty())
-        return;
-
-    if (!m_texture)
-        m_texture = ManagedTexture::create(layerRenderer->implTextureManager());
-
-    // The context could have been lost since the last frame and the old texture
-    // manager may no longer be valid.
-    m_texture->setTextureManager(layerRenderer->implTextureManager());
-
-    IntSize textureSize = contentBounds();
-    if (!m_texture->reserve(textureSize, GraphicsContext3D::RGBA))
-        return;
-
-    PlatformCanvas canvas;
-    canvas.resize(textureSize);
-    {
-        PlatformCanvas::Painter painter(&canvas, PlatformCanvas::Painter::GrayscaleText);
-        paint(painter.context());
-    }
-
-    {
-        PlatformCanvas::AutoLocker locker(&canvas);
-        m_texture->bindTexture(context, layerRenderer->implTextureAllocator());
-
-        // FIXME: Skia uses BGRA actually, we correct that with the swizzle pixel shader.
-        GraphicsContext3D* context3d = context->context3D();
-        if (!context3d) {
-            // FIXME: Implement this path for software compositing.
-            return;
-        }
-
-        GLC(context3d, context3d->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, m_texture->format(), canvas.size().width(), canvas.size().height(), 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, locker.pixels()));
-    }
-}
-
 void CCScrollbarLayerImpl::appendQuads(CCQuadCuller& quadList, const CCSharedQuadState* sharedQuadState, bool&)
 {
-    if (!m_texture->isReserved())
+    ScrollbarThemeComposite* theme = static_cast<ScrollbarThemeComposite*>(ScrollbarTheme::theme());
+    if (!theme)
         return;
 
-    IntRect quadRect(IntPoint(), bounds());
-    quadList.append(CCTileDrawQuad::create(sharedQuadState, quadRect, quadRect, m_texture->textureId(), IntPoint(), m_texture->size(), GraphicsContext3D::NEAREST, true, true, true, true, true));
-}
-
-void CCScrollbarLayerImpl::didDraw()
-{
-    CCLayerImpl::didDraw();
-
-    m_texture->unreserve();
-}
+    bool premultipledAlpha = false;
+    FloatRect uvRect(0, 0, 1, 1);
+    bool flipped = false;
 
-void CCScrollbarLayerImpl::paint(GraphicsContext* context)
-{
-    ScrollbarTheme* theme = ScrollbarTheme::theme(); // FIXME: should make impl-side clone if needed
+    IntRect thumbRect = theme->thumbRect(&m_scrollbar);
+    thumbRect.move(-m_scrollbar.x(), -m_scrollbar.y());
+    if (m_thumbTextureId && theme->hasThumb(&m_scrollbar) && !thumbRect.isEmpty())
+        quadList.append(CCTextureDrawQuad::create(sharedQuadState, thumbRect, m_thumbTextureId, premultipledAlpha, uvRect, flipped));
+    if (!m_backgroundTextureId)
+        return;
 
-    context->clearRect(IntRect(IntPoint(), contentBounds()));
-    theme->paint(&m_scrollbar, context, IntRect(IntPoint(), contentBounds()));
+    IntRect backgroundRect(IntPoint(), contentBounds());
+    quadList.append(CCTextureDrawQuad::create(sharedQuadState, backgroundRect, m_backgroundTextureId, premultipledAlpha, uvRect, flipped));
 }
 
-
 int CCScrollbarLayerImpl::CCScrollbar::x() const
 {
     return frameRect().x();
index f975c19..db3f334 100644 (file)
@@ -55,22 +55,19 @@ public:
 
     void setEnabled(bool enabled) { m_enabled = enabled; }
 
+    void setBackgroundTextureId(unsigned id) { m_backgroundTextureId = id; }
+    void setThumbTextureId(unsigned id) { m_thumbTextureId = id; }
 
     CCLayerImpl* scrollLayer() const { return m_scrollLayer; }
     void setScrollLayer(CCLayerImpl* scrollLayer) { m_scrollLayer = scrollLayer; }
 
-    virtual void willDraw(CCRenderer*, CCGraphicsContext*) OVERRIDE;
     virtual void appendQuads(CCQuadCuller&, const CCSharedQuadState*, bool& hadMissingTiles) OVERRIDE;
-    virtual void didDraw() OVERRIDE;
 
 protected:
     explicit CCScrollbarLayerImpl(int id);
 
-    virtual void paint(GraphicsContext*);
-
 private:
     CCLayerImpl* m_scrollLayer;
-    OwnPtr<ManagedTexture> m_texture;
 
     // nested class only to avoid namespace problem
     class CCScrollbar : public ScrollbarThemeClient {
@@ -128,6 +125,9 @@ private:
     };
     CCScrollbar m_scrollbar;
 
+    unsigned m_backgroundTextureId;
+    unsigned m_thumbTextureId;
+
     ScrollbarOverlayStyle m_scrollbarOverlayStyle;
     Vector<IntRect> m_tickmarks;
     bool m_isScrollableAreaActive;
index 30f959a..1992174 100644 (file)
@@ -1,3 +1,16 @@
+2012-06-12  Adrienne Walker  <enne@google.com>
+
+        [chromium] Paint scrollbars on WebKit thread and composite those textures
+        https://bugs.webkit.org/show_bug.cgi?id=88145
+
+        Reviewed by James Robinson.
+
+        Remove scrollbarLayerLostContext test that no longer makes sense. The
+        compositor won't draw at all after a lost context if it has no
+        contents.
+
+        * tests/CCLayerTreeHostImplTest.cpp:
+
 2012-06-12  Joshua Bell  <jsbell@chromium.org>
 
         IndexedDB: ObjectStore/Index shouldn't hold reference to backing store
index 0c5ff38..a61dd81 100644 (file)
@@ -1584,26 +1584,6 @@ private:
     ScrollbarLayerFakePaint(int id) : CCScrollbarLayerImpl(id) { }
 };
 
-TEST_F(CCLayerTreeHostImplTest, scrollbarLayerLostContext)
-{
-    m_hostImpl->setRootLayer(ScrollbarLayerFakePaint::create(0));
-    ScrollbarLayerFakePaint* scrollbar = static_cast<ScrollbarLayerFakePaint*>(m_hostImpl->rootLayer());
-    scrollbar->setBounds(IntSize(1, 1));
-    scrollbar->setContentBounds(IntSize(1, 1));
-    scrollbar->setDrawsContent(true);
-
-    for (int i = 0; i < 2; ++i) {
-        CCLayerTreeHostImpl::FrameData frame;
-        EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
-        ASSERT(frame.renderPasses.size() == 1);
-        CCRenderPass* renderPass = frame.renderPasses[0].get();
-        // Scrollbar layer should always generate quads, even after lost context
-        EXPECT_GT(renderPass->quadList().size(), 0u);
-        m_hostImpl->didDrawAllLayers(frame);
-        m_hostImpl->initializeLayerRenderer(createContext(), UnthrottledUploader);
-    }
-}
-
 // Fake WebGraphicsContext3D that will cause a failure if trying to use a
 // resource that wasn't created by it (resources created by
 // FakeWebGraphicsContext3D have an id of 1).