Title: [114147] trunk/Source/WebCore
Revision
114147
Author
shawnsi...@chromium.org
Date
2012-04-13 11:06:50 -0700 (Fri, 13 Apr 2012)

Log Message

[chromium] Support CCHeadsUpDisplay in threaded compositing mode
https://bugs.webkit.org/show_bug.cgi?id=67499

Reviewed by James Robinson.

No new tests because this code is debugging code itself.

The last item that was needed to make the CCHeadsUpDisplay work in
threaded compositing mode was to remove the font rendering code
used on the impl-side thread. To solve this, this patch adds a
CCFontAtlas that is initialized on the main thread (where the font
rendering takes place). Then, when the HUD draws text on the impl
thread, it uses the font atlas directly.

* WebCore.gypi:
* platform/graphics/chromium/LayerRendererChromium.cpp:
(WebCore::LayerRendererChromium::create):
(WebCore::LayerRendererChromium::initialize):
* platform/graphics/chromium/LayerRendererChromium.h:
(WebCore):
(LayerRendererChromium):
* platform/graphics/chromium/cc/CCFontAtlas.cpp: Added.
(WebCore):
(WebCore::CCFontAtlas::CCFontAtlas):
(WebCore::wrapPositionIfNeeded):
(WebCore::CCFontAtlas::generateAtlasForFont):
(WebCore::CCFontAtlas::initialize):
(WebCore::CCFontAtlas::drawText):
(WebCore::CCFontAtlas::drawOneLineOfTextInternal):
(WebCore::CCFontAtlas::drawDebugAtlas):
* platform/graphics/chromium/cc/CCFontAtlas.h: Added.
(WebCore):
(CCFontAtlas):
(WebCore::CCFontAtlas::create):
* platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp:
(WebCore::CCHeadsUpDisplay::CCHeadsUpDisplay):
(WebCore):
(WebCore::CCHeadsUpDisplay::showPlatformLayerTree):
(WebCore::CCHeadsUpDisplay::drawHudContents):
(WebCore::CCHeadsUpDisplay::drawFPSCounter):
(WebCore::CCHeadsUpDisplay::drawFPSCounterText):
(WebCore::CCHeadsUpDisplay::drawPlatformLayerTree):
* platform/graphics/chromium/cc/CCHeadsUpDisplay.h:
(WebCore::CCHeadsUpDisplay::create):
(CCHeadsUpDisplay):
* platform/graphics/chromium/cc/CCLayerTreeHost.cpp:
(WebCore::CCLayerTreeHost::initialize):
* platform/graphics/chromium/cc/CCLayerTreeHost.h:
(WebCore):
(WebCore::CCLayerTreeHost::headsUpDisplayFontAtlas):
(CCLayerTreeHost):
* platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp:
(WebCore::CCLayerTreeHostImpl::initializeLayerRenderer):
* platform/graphics/chromium/cc/CCLayerTreeHostImpl.h:
(WebCore):
(CCLayerTreeHostImpl):
* platform/graphics/chromium/cc/CCSingleThreadProxy.cpp:
(WebCore::CCSingleThreadProxy::initializeLayerRenderer):
(WebCore::CCSingleThreadProxy::recreateContext):
* platform/graphics/chromium/cc/CCThreadProxy.cpp:
(WebCore::CCThreadProxy::initializeLayerRendererOnImplThread):
(WebCore::CCThreadProxy::recreateContextOnImplThread):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (114146 => 114147)


--- trunk/Source/WebCore/ChangeLog	2012-04-13 18:06:15 UTC (rev 114146)
+++ trunk/Source/WebCore/ChangeLog	2012-04-13 18:06:50 UTC (rev 114147)
@@ -1,3 +1,68 @@
+2012-04-12  Shawn Singh  <shawnsi...@chromium.org>
+
+        [chromium] Support CCHeadsUpDisplay in threaded compositing mode
+        https://bugs.webkit.org/show_bug.cgi?id=67499
+
+        Reviewed by James Robinson.
+
+        No new tests because this code is debugging code itself.
+
+        The last item that was needed to make the CCHeadsUpDisplay work in
+        threaded compositing mode was to remove the font rendering code
+        used on the impl-side thread. To solve this, this patch adds a
+        CCFontAtlas that is initialized on the main thread (where the font
+        rendering takes place). Then, when the HUD draws text on the impl
+        thread, it uses the font atlas directly.
+
+        * WebCore.gypi:
+        * platform/graphics/chromium/LayerRendererChromium.cpp:
+        (WebCore::LayerRendererChromium::create):
+        (WebCore::LayerRendererChromium::initialize):
+        * platform/graphics/chromium/LayerRendererChromium.h:
+        (WebCore):
+        (LayerRendererChromium):
+        * platform/graphics/chromium/cc/CCFontAtlas.cpp: Added.
+        (WebCore):
+        (WebCore::CCFontAtlas::CCFontAtlas):
+        (WebCore::wrapPositionIfNeeded):
+        (WebCore::CCFontAtlas::generateAtlasForFont):
+        (WebCore::CCFontAtlas::initialize):
+        (WebCore::CCFontAtlas::drawText):
+        (WebCore::CCFontAtlas::drawOneLineOfTextInternal):
+        (WebCore::CCFontAtlas::drawDebugAtlas):
+        * platform/graphics/chromium/cc/CCFontAtlas.h: Added.
+        (WebCore):
+        (CCFontAtlas):
+        (WebCore::CCFontAtlas::create):
+        * platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp:
+        (WebCore::CCHeadsUpDisplay::CCHeadsUpDisplay):
+        (WebCore):
+        (WebCore::CCHeadsUpDisplay::showPlatformLayerTree):
+        (WebCore::CCHeadsUpDisplay::drawHudContents):
+        (WebCore::CCHeadsUpDisplay::drawFPSCounter):
+        (WebCore::CCHeadsUpDisplay::drawFPSCounterText):
+        (WebCore::CCHeadsUpDisplay::drawPlatformLayerTree):
+        * platform/graphics/chromium/cc/CCHeadsUpDisplay.h:
+        (WebCore::CCHeadsUpDisplay::create):
+        (CCHeadsUpDisplay):
+        * platform/graphics/chromium/cc/CCLayerTreeHost.cpp:
+        (WebCore::CCLayerTreeHost::initialize):
+        * platform/graphics/chromium/cc/CCLayerTreeHost.h:
+        (WebCore):
+        (WebCore::CCLayerTreeHost::headsUpDisplayFontAtlas):
+        (CCLayerTreeHost):
+        * platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp:
+        (WebCore::CCLayerTreeHostImpl::initializeLayerRenderer):
+        * platform/graphics/chromium/cc/CCLayerTreeHostImpl.h:
+        (WebCore):
+        (CCLayerTreeHostImpl):
+        * platform/graphics/chromium/cc/CCSingleThreadProxy.cpp:
+        (WebCore::CCSingleThreadProxy::initializeLayerRenderer):
+        (WebCore::CCSingleThreadProxy::recreateContext):
+        * platform/graphics/chromium/cc/CCThreadProxy.cpp:
+        (WebCore::CCThreadProxy::initializeLayerRendererOnImplThread):
+        (WebCore::CCThreadProxy::recreateContextOnImplThread):
+
 2012-04-13  Rob Flack  <fla...@chromium.org>
 
         Chromium: Should enable -webkit-image-set

Modified: trunk/Source/WebCore/WebCore.gypi (114146 => 114147)


--- trunk/Source/WebCore/WebCore.gypi	2012-04-13 18:06:15 UTC (rev 114146)
+++ trunk/Source/WebCore/WebCore.gypi	2012-04-13 18:06:50 UTC (rev 114147)
@@ -3607,6 +3607,8 @@
             'platform/graphics/chromium/cc/CCDelayBasedTimeSource.h',
             'platform/graphics/chromium/cc/CCDrawQuad.cpp',
             'platform/graphics/chromium/cc/CCDrawQuad.h',
+            'platform/graphics/chromium/cc/CCFontAtlas.cpp',
+            'platform/graphics/chromium/cc/CCFontAtlas.h',
             'platform/graphics/chromium/cc/CCFrameRateController.cpp',
             'platform/graphics/chromium/cc/CCFrameRateController.h',
             'platform/graphics/chromium/cc/CCGestureCurve.h',

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


--- trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp	2012-04-13 18:06:15 UTC (rev 114146)
+++ trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp	2012-04-13 18:06:50 UTC (rev 114147)
@@ -195,10 +195,10 @@
 };
 
 
-PassOwnPtr<LayerRendererChromium> LayerRendererChromium::create(LayerRendererChromiumClient* client, PassRefPtr<GraphicsContext3D> context)
+PassOwnPtr<LayerRendererChromium> LayerRendererChromium::create(LayerRendererChromiumClient* client, PassRefPtr<GraphicsContext3D> context, CCFontAtlas* headsUpDisplayFontAtlas)
 {
     OwnPtr<LayerRendererChromium> layerRenderer(adoptPtr(new LayerRendererChromium(client, context)));
-    if (!layerRenderer->initialize())
+    if (!layerRenderer->initialize(headsUpDisplayFontAtlas))
         return nullptr;
 
     return layerRenderer.release();
@@ -237,7 +237,7 @@
     LayerRendererChromiumClient* m_client;
 };
 
-bool LayerRendererChromium::initialize()
+bool LayerRendererChromium::initialize(CCFontAtlas* headsUpDisplayFontAtlas)
 {
     if (!m_context->makeContextCurrent())
         return false;
@@ -307,7 +307,7 @@
     if (!initializeSharedObjects())
         return false;
 
-    m_headsUpDisplay = CCHeadsUpDisplay::create(this);
+    m_headsUpDisplay = CCHeadsUpDisplay::create(this, headsUpDisplayFontAtlas);
 
     // Make sure the viewport and context gets initialized, even if it is to zero.
     viewportChanged();

Modified: trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h (114146 => 114147)


--- trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h	2012-04-13 18:06:15 UTC (rev 114146)
+++ trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h	2012-04-13 18:06:50 UTC (rev 114147)
@@ -54,6 +54,7 @@
 
 namespace WebCore {
 
+class CCFontAtlas;
 class CCHeadsUpDisplay;
 class CCLayerImpl;
 class CCRenderPass;
@@ -79,7 +80,7 @@
 class LayerRendererChromium {
     WTF_MAKE_NONCOPYABLE(LayerRendererChromium);
 public:
-    static PassOwnPtr<LayerRendererChromium> create(LayerRendererChromiumClient*, PassRefPtr<GraphicsContext3D>);
+    static PassOwnPtr<LayerRendererChromium> create(LayerRendererChromiumClient*, PassRefPtr<GraphicsContext3D>, CCFontAtlas*);
 
     ~LayerRendererChromium();
 
@@ -173,7 +174,7 @@
     bool isFramebufferDiscarded() const { return m_isFramebufferDiscarded; }
 
     LayerRendererChromium(LayerRendererChromiumClient*, PassRefPtr<GraphicsContext3D>);
-    bool initialize();
+    bool initialize(CCFontAtlas* headsUpDisplayFontAtlas = 0);
 
 private:
     void drawQuad(const CCDrawQuad*, const FloatRect& surfaceDamageRect);

Added: trunk/Source/WebCore/platform/graphics/chromium/cc/CCFontAtlas.cpp (0 => 114147)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCFontAtlas.cpp	                        (rev 0)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCFontAtlas.cpp	2012-04-13 18:06:50 UTC (rev 114147)
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+#include "CCFontAtlas.h"
+
+#include "CCProxy.h"
+#include "Font.h"
+#include "FontCache.h"
+#include "FontDescription.h"
+#include "GraphicsContext.h"
+#include "ImageBuffer.h"
+#include "TextRun.h"
+
+#define ATLAS_SIZE 128
+#define FONT_HEIGHT 14
+
+namespace WebCore {
+
+using namespace std;
+
+
+CCFontAtlas::CCFontAtlas()
+    : m_fontHeight(FONT_HEIGHT)
+{
+}
+
+static void wrapPositionIfNeeded(IntPoint& position, int textWidth, int textHeight)
+{
+    if (position.x() + textWidth > ATLAS_SIZE)
+        position = IntPoint(0, position.y() + textHeight);
+}
+
+void CCFontAtlas::generateAtlasForFont(GraphicsContext* atlasContext, const FontDescription& fontDescription, const Color& fontColor, const IntPoint& startingPosition, IntRect asciiToAtlasTable[128])
+{
+    ASSERT(CCProxy::isMainThread());
+    ASSERT(m_atlas);
+
+    FontCachePurgePreventer fontCachePurgePreventer;
+
+    IntPoint position = startingPosition;
+    int textHeight = fontDescription.computedPixelSize();
+    // This is a dirty little trick to account for overhang letters like g, p, j.
+    int inflation = textHeight / 3;
+
+    Font font(fontDescription, 0, 0);
+    font.update(0);
+
+    atlasContext->setStrokeColor(fontColor, ColorSpaceDeviceRGB);
+    atlasContext->setFillColor(fontColor, ColorSpaceDeviceRGB);
+
+    // First, draw a generic rect that will be used for special and unknown characters that have nothing else to render.
+    {
+        int textWidth = textHeight / 2;
+        wrapPositionIfNeeded(position, textWidth, textHeight + inflation);
+        atlasContext->strokeRect(FloatRect(FloatPoint(position.x() + 1, position.y() - textHeight + 1 + inflation), FloatSize(textWidth - 2, textHeight - 2 - inflation)), 1);
+
+        // Initialize the rect that would be copied when drawing this glyph from the atlas.
+        asciiToAtlasTable[0] = IntRect(IntPoint(position.x(), position.y() - textHeight), IntSize(textWidth, textHeight + inflation));
+
+        // Increment to the position where the next glyph will be placed.
+        position.setX(position.x() + textWidth);
+    }
+
+    // Then, draw the ASCII characters.
+    for (LChar i = 1; i < 128; ++i) {
+        if (i < 32) {
+            // Special characters will simply use the the default glyph.
+            asciiToAtlasTable[i] = asciiToAtlasTable[0];
+            continue;
+        }
+
+        String str;
+        str.append(i);
+        TextRun text(str);
+
+        int textWidth = round(font.width(text));
+        wrapPositionIfNeeded(position, textWidth, textHeight + inflation);
+        atlasContext->drawText(font, text, position);
+
+        // Initialize the rect that would be copied when drawing this glyph from the atlas.
+        asciiToAtlasTable[i] = IntRect(IntPoint(position.x(), position.y() - textHeight), IntSize(textWidth, textHeight + inflation));
+
+        // Increment to the position where the next glyph will be placed.
+        position.setX(position.x() + textWidth);
+    }
+}
+
+void CCFontAtlas::initialize()
+{
+    ASSERT(CCProxy::isMainThread());
+
+    // We expect this function to be called only once when the atlas did not exist yet. We should be aware if that's not true.
+    ASSERT(!m_atlas);
+
+    m_atlas = ImageBuffer::create(IntSize(ATLAS_SIZE, ATLAS_SIZE));
+    GraphicsContext* atlasContext = m_atlas->context();
+
+    // Clear the entire texture atlas to transparent before drawing fonts.
+    atlasContext->setFillColor(Color(0, 0, 0, 0), ColorSpaceDeviceRGB);
+    atlasContext->fillRect(FloatRect(0, 0, ATLAS_SIZE, ATLAS_SIZE));
+
+    // FIXME: monospace font does not work as expected.
+    FontDescription fontDescription;
+    fontDescription.setGenericFamily(FontDescription::MonospaceFamily);
+    fontDescription.setComputedSize(m_fontHeight);
+    generateAtlasForFont(atlasContext, fontDescription, Color(255, 0, 0), IntPoint(0, fontDescription.computedPixelSize()), m_asciiToRectTable);
+}
+
+void CCFontAtlas::drawText(GraphicsContext* targetContext, const String& text, const IntPoint& destPosition, const IntSize& clip) const
+{
+    ASSERT(CCProxy::isImplThread());
+    ASSERT(m_atlas);
+
+    Vector<String> lines;
+    text.split('\n', lines);
+
+    IntPoint position = destPosition;
+    for (size_t i = 0; i < lines.size(); ++i) {
+        drawOneLineOfTextInternal(targetContext, lines[i], position);
+        position.setY(position.y() + m_fontHeight);
+        if (position.y() > clip.height())
+            return;
+    }
+}
+
+void CCFontAtlas::drawOneLineOfTextInternal(GraphicsContext* targetContext, const String& textLine, const IntPoint& destPosition) const
+{
+    ASSERT(CCProxy::isImplThread());
+    ASSERT(m_atlas);
+
+    IntPoint position = destPosition;
+    for (unsigned i = 0; i < textLine.length(); ++i) {
+        // If the ASCII code is out of bounds, then index 0 is used, which is just a plain rectangle glyph.
+        int asciiIndex = (textLine[i] < 128) ? textLine[i] : 0;
+        IntRect glyphBounds = m_asciiToRectTable[asciiIndex];
+        targetContext->drawImageBuffer(m_atlas.get(), ColorSpaceDeviceRGB, position, glyphBounds);
+        position.setX(position.x() + glyphBounds.width());
+    }
+}
+
+void CCFontAtlas::drawDebugAtlas(GraphicsContext* targetContext, const IntPoint& destPosition) const
+{
+    ASSERT(CCProxy::isImplThread());
+    ASSERT(m_atlas);
+
+    targetContext->drawImageBuffer(m_atlas.get(), ColorSpaceDeviceRGB, destPosition, IntRect(IntPoint::zero(), IntSize(ATLAS_SIZE, ATLAS_SIZE)));
+}
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)

Added: trunk/Source/WebCore/platform/graphics/chromium/cc/CCFontAtlas.h (0 => 114147)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCFontAtlas.h	                        (rev 0)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCFontAtlas.h	2012-04-13 18:06:50 UTC (rev 114147)
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CCFontAtlas_h
+#define CCFontAtlas_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "ImageBuffer.h"
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class Color;
+class FontDescription;
+class IntPoint;
+class IntRect;
+class GraphicsContext;
+
+// This class provides basic ability to draw text onto the heads-up display.
+// It must be initialized on the main thread, and it can only draw text on the impl thread.
+class CCFontAtlas {
+    WTF_MAKE_NONCOPYABLE(CCFontAtlas);
+public:
+    static PassOwnPtr<CCFontAtlas> create()
+    {
+        return adoptPtr(new CCFontAtlas());
+    }
+
+    // Creates the font atlas.
+    // - Should only be called on the main thread.
+    void initialize();
+
+    // Draws multiple lines of text where each line of text is separated by '\n'.
+    // - Correct glyphs will be drawn for ASCII codes in the range 32-127; any characters
+    //   outside that range will be displayed as a default rectangle glyph.
+    // - IntSize clip is used to avoid wasting time drawing things that are outside the
+    //   target canvas bounds.
+    // - Should only be called only on the impl thread.
+    void drawText(GraphicsContext*, const String& text, const IntPoint& destPosition, const IntSize& clip) const;
+
+    // Draws the entire atlas at the specified position, just for debugging purposes.
+    void drawDebugAtlas(GraphicsContext*, const IntPoint& destPosition) const;
+
+private:
+    CCFontAtlas();
+
+    // Paints the font into the atlas, from left-to-right, top-to-bottom, starting at
+    // startingPosition. At the same time, it updates the ascii-to-IntRect mapping for
+    // each character. By doing things this way, it is possible to support variable-width
+    // fonts and multiple fonts on the same atlas.
+    void generateAtlasForFont(GraphicsContext*, const FontDescription&, const Color& fontColor, const IntPoint& startingPosition, IntRect asciiToAtlasTable[128]);
+
+    void drawOneLineOfTextInternal(GraphicsContext*, const String&, const IntPoint& destPosition) const;
+
+    // The actual texture atlas containing all the pre-rendered glyphs.
+    OwnPtr<ImageBuffer> m_atlas;
+
+    // The look-up tables mapping ascii characters to their IntRect locations on the atlas.
+    IntRect m_asciiToRectTable[128];
+
+    int m_fontHeight;
+};
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
+#endif

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp (114146 => 114147)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp	2012-04-13 18:06:15 UTC (rev 114146)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp	2012-04-13 18:06:50 UTC (rev 114147)
@@ -27,10 +27,8 @@
 #if USE(ACCELERATED_COMPOSITING)
 #include "CCHeadsUpDisplay.h"
 
+#include "CCFontAtlas.h"
 #include "Extensions3DChromium.h"
-#include "Font.h"
-#include "FontCache.h"
-#include "FontDescription.h"
 #include "GraphicsContext3D.h"
 #include "InspectorController.h"
 #include "LayerChromium.h"
@@ -48,20 +46,16 @@
 
 using namespace std;
 
-CCHeadsUpDisplay::CCHeadsUpDisplay(LayerRendererChromium* owner)
+CCHeadsUpDisplay::CCHeadsUpDisplay(LayerRendererChromium* owner, CCFontAtlas* headsUpDisplayFontAtlas)
     : m_currentFrameNumber(1)
     , m_layerRenderer(owner)
     , m_useMapSubForUploads(owner->contextSupportsMapSub())
+    , m_fontAtlas(headsUpDisplayFontAtlas)
 {
     m_beginTimeHistoryInSec[0] = currentTime();
     m_beginTimeHistoryInSec[1] = m_beginTimeHistoryInSec[0];
     for (int i = 2; i < kBeginFrameHistorySize; i++)
         m_beginTimeHistoryInSec[i] = 0;
-
-    // We can't draw text in threaded mode with the current mechanism.
-    // FIXME: Figure out a way to draw text in threaded mode.
-    if (!CCProxy::implThread())
-        initializeFonts();
 }
 
 CCHeadsUpDisplay::~CCHeadsUpDisplay()
@@ -71,24 +65,6 @@
 const double CCHeadsUpDisplay::kIdleSecondsTriggersReset = 0.5;
 const double CCHeadsUpDisplay::kFrameTooFast = 1.0 / 70;
 
-void CCHeadsUpDisplay::initializeFonts()
-{
-    ASSERT(!CCProxy::implThread());
-    FontDescription mediumFontDesc;
-    mediumFontDesc.setGenericFamily(FontDescription::MonospaceFamily);
-    mediumFontDesc.setComputedSize(12);
-
-    m_mediumFont = adoptPtr(new Font(mediumFontDesc, 0, 0));
-    m_mediumFont->update(0);
-
-    FontDescription smallFontDesc;
-    smallFontDesc.setGenericFamily(FontDescription::MonospaceFamily);
-    smallFontDesc.setComputedSize(10);
-
-    m_smallFont = adoptPtr(new Font(smallFontDesc, 0, 0));
-    m_smallFont->update(0);
-}
-
 // safeMod works on -1, returning m-1 in that case.
 static inline int safeMod(int number, int modulus)
 {
@@ -117,7 +93,7 @@
 
 bool CCHeadsUpDisplay::showPlatformLayerTree() const
 {
-    return settings().showPlatformLayerTree && !CCProxy::implThread();
+    return settings().showPlatformLayerTree;
 }
 
 void CCHeadsUpDisplay::draw()
@@ -204,9 +180,6 @@
     }
 
     int fpsCounterHeight = 40;
-    if (!CCProxy::implThread())
-        fpsCounterHeight += m_mediumFont->fontMetrics().floatHeight();
-
     int fpsCounterTop = 2;
     int platformLayerTreeTop;
     if (settings().showFPSCounter)
@@ -218,7 +191,7 @@
         drawFPSCounter(context, fpsCounterTop, fpsCounterHeight);
 
     if (showPlatformLayerTree())
-        drawPlatformLayerTree(context, platformLayerTreeTop);
+        drawPlatformLayerTree(context, hudSize, platformLayerTreeTop);
 }
 
 void CCHeadsUpDisplay::getAverageFPSAndStandardDeviation(double *average, double *standardDeviation) const
@@ -267,12 +240,12 @@
 
 void CCHeadsUpDisplay::drawFPSCounter(GraphicsContext* context, int top, int height)
 {
-    float textWidth = 0;
-    if (!CCProxy::implThread())
-        textWidth = drawFPSCounterText(context, top, height);
-
+    float textWidth = 170; // so text fits on linux.
     float graphWidth = kBeginFrameHistorySize;
 
+    // Draw the FPS text.
+    drawFPSCounterText(context, top, textWidth, height);
+
     // Draw FPS graph.
     const double loFPS = 0;
     const double hiFPS = 80;
@@ -308,46 +281,24 @@
     }
 }
 
-float CCHeadsUpDisplay::drawFPSCounterText(GraphicsContext* context, int top, int height)
+void CCHeadsUpDisplay::drawFPSCounterText(GraphicsContext* context, int top, int width, int height)
 {
-    ASSERT(!CCProxy::implThread());
-
-    FontCachePurgePreventer fontCachePurgePreventer;
     double averageFPS, stdDeviation;
-
     getAverageFPSAndStandardDeviation(&averageFPS, &stdDeviation);
 
-    String fps(String::format("FPS: %4.1f +/-%3.1f", averageFPS, stdDeviation));
-    TextRun text(fps);
-    float textWidth = m_mediumFont->width(text) + 2;
-
     // Draw background.
     context->setFillColor(Color(0, 0, 0, 255), ColorSpaceDeviceRGB);
-    double fontHeight = m_mediumFont->fontMetrics().floatHeight() + 2;
-    context->fillRect(FloatRect(2, top, textWidth, fontHeight));
+    context->fillRect(FloatRect(2, top, width, height));
 
     // Draw FPS text.
-    context->setFillColor(Color(200, 200, 200), ColorSpaceDeviceRGB);
-    context->drawText(*m_mediumFont, text, IntPoint(3, top + fontHeight - 4));
-
-    return textWidth;
+    if (m_fontAtlas)
+        m_fontAtlas->drawText(context, String::format("FPS: %4.1f +/- %3.1f", averageFPS, stdDeviation), IntPoint(10, height / 3), IntSize(width, height));
 }
 
-void CCHeadsUpDisplay::drawPlatformLayerTree(GraphicsContext* context, int top)
+void CCHeadsUpDisplay::drawPlatformLayerTree(GraphicsContext* context, const IntSize hudSize, int top)
 {
-    ASSERT(!CCProxy::implThread());
-
-    FontCachePurgePreventer fontCachePurgePreventer;
-
-    float smallFontHeight = m_smallFont->fontMetrics().floatHeight();
-    int y = top + smallFontHeight - 4;
-    context->setFillColor(Color(255, 0, 0), ColorSpaceDeviceRGB);
-    Vector<String> lines;
-    m_layerRenderer->layerTreeAsText().split('\n', lines);
-    for (size_t i = 0; i < lines.size(); ++i) {
-        context->drawText(*m_smallFont, TextRun(lines[i]), IntPoint(2, y));
-        y += smallFontHeight;
-    }
+    if (m_fontAtlas)
+        m_fontAtlas->drawText(context, m_layerRenderer->layerTreeAsText(), IntPoint(2, top), hudSize);
 }
 
 const CCSettings& CCHeadsUpDisplay::settings() const

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.h (114146 => 114147)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.h	2012-04-13 18:06:15 UTC (rev 114146)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.h	2012-04-13 18:06:50 UTC (rev 114147)
@@ -27,7 +27,7 @@
 
 #if USE(ACCELERATED_COMPOSITING)
 
-#include "Font.h"
+#include "CCFontAtlas.h"
 #include "ProgramBinding.h"
 #include "ShaderChromium.h"
 
@@ -43,9 +43,9 @@
 class CCHeadsUpDisplay {
     WTF_MAKE_NONCOPYABLE(CCHeadsUpDisplay);
 public:
-    static PassOwnPtr<CCHeadsUpDisplay> create(LayerRendererChromium* owner)
+    static PassOwnPtr<CCHeadsUpDisplay> create(LayerRendererChromium* owner, CCFontAtlas* headsUpDisplayFontAtlas)
     {
-        return adoptPtr(new CCHeadsUpDisplay(owner));
+        return adoptPtr(new CCHeadsUpDisplay(owner, headsUpDisplayFontAtlas));
     }
 
     ~CCHeadsUpDisplay();
@@ -61,11 +61,11 @@
     typedef ProgramBinding<VertexShaderPosTex, FragmentShaderRGBATexSwizzleAlpha> Program;
 
 private:
-    explicit CCHeadsUpDisplay(LayerRendererChromium* owner);
+    CCHeadsUpDisplay(LayerRendererChromium* owner, CCFontAtlas* headsUpDisplayFontAtlas);
     void drawHudContents(GraphicsContext*, const IntSize& hudSize);
     void drawFPSCounter(GraphicsContext*, int top, int height);
-    float drawFPSCounterText(GraphicsContext*, int top, int height);
-    void drawPlatformLayerTree(GraphicsContext*, int top);
+    void drawFPSCounterText(GraphicsContext*, int top, int width, int height);
+    void drawPlatformLayerTree(GraphicsContext*, const IntSize hudSize, int top);
     const CCSettings& settings() const;
     bool isBadFrame(int frameNumber) const;
     int frameIndex(int frameNumber) const;
@@ -73,8 +73,6 @@
 
     bool showPlatformLayerTree() const;
 
-    void initializeFonts();
-
     int m_currentFrameNumber;
 
     OwnPtr<ManagedTexture> m_hudTexture;
@@ -89,10 +87,9 @@
     static const double kFrameTooFast;
     static const int kNumMissedFramesForReset = 5;
 
-    OwnPtr<Font> m_smallFont;
-    OwnPtr<Font> m_mediumFont;
-
     bool m_useMapSubForUploads;
+
+    CCFontAtlas* m_fontAtlas;
 };
 
 }

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp (114146 => 114147)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp	2012-04-13 18:06:15 UTC (rev 114146)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp	2012-04-13 18:06:50 UTC (rev 114147)
@@ -32,6 +32,7 @@
 #include "Region.h"
 #include "TraceEvent.h"
 #include "TreeSynchronizer.h"
+#include "cc/CCFontAtlas.h"
 #include "cc/CCLayerAnimationController.h"
 #include "cc/CCLayerIterator.h"
 #include "cc/CCLayerTreeHostCommon.h"
@@ -99,6 +100,12 @@
     if (!m_proxy->initializeContext())
         return false;
 
+    // Only allocate the font atlas if we have reason to use the heads-up display.
+    if (m_settings.showFPSCounter || m_settings.showPlatformLayerTree) {
+        m_headsUpDisplayFontAtlas = CCFontAtlas::create();
+        m_headsUpDisplayFontAtlas->initialize();
+    }
+
     m_compositorIdentifier = m_proxy->compositorIdentifier();
     return true;
 }

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h (114146 => 114147)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h	2012-04-13 18:06:15 UTC (rev 114146)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h	2012-04-13 18:06:50 UTC (rev 114147)
@@ -43,6 +43,7 @@
 
 namespace WebCore {
 
+class CCFontAtlas;
 class CCLayerTreeHostImpl;
 class CCLayerTreeHostImplClient;
 class CCTextureUpdater;
@@ -220,6 +221,8 @@
     bool requestPartialTextureUpdate();
     void deleteTextureAfterCommit(PassOwnPtr<ManagedTexture>);
 
+    CCFontAtlas* headsUpDisplayFontAtlas() { return m_headsUpDisplayFontAtlas.get(); }
+
 protected:
     CCLayerTreeHost(CCLayerTreeHostClient*, const CCSettings&);
     bool initialize();
@@ -263,6 +266,9 @@
 
     CCSettings m_settings;
 
+    // This is owned by the main layer tree host because it needs to be initialized on the main thread.
+    OwnPtr<CCFontAtlas> m_headsUpDisplayFontAtlas;
+
     IntSize m_viewportSize;
     bool m_visible;
     typedef HashMap<GraphicsContext3D*, RefPtr<RateLimiter> > RateLimiterMap;

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp (114146 => 114147)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp	2012-04-13 18:06:15 UTC (rev 114146)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp	2012-04-13 18:06:50 UTC (rev 114147)
@@ -497,10 +497,10 @@
     m_timeSourceClientAdapter->setActive(shouldTickInBackground);
 }
 
-bool CCLayerTreeHostImpl::initializeLayerRenderer(PassRefPtr<GraphicsContext3D> context)
+bool CCLayerTreeHostImpl::initializeLayerRenderer(PassRefPtr<GraphicsContext3D> context, CCFontAtlas* headsUpDisplayFontAtlas)
 {
     OwnPtr<LayerRendererChromium> layerRenderer;
-    layerRenderer = LayerRendererChromium::create(this, context);
+    layerRenderer = LayerRendererChromium::create(this, context, headsUpDisplayFontAtlas);
 
     // Since we now have a new context/layerRenderer, we cannot continue to use the old
     // resources (i.e. renderSurfaces and texture IDs).

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h (114146 => 114147)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h	2012-04-13 18:06:15 UTC (rev 114146)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h	2012-04-13 18:06:50 UTC (rev 114147)
@@ -40,6 +40,7 @@
 
 class CCActiveGestureAnimation;
 class CCCompletionEvent;
+class CCFontAtlas;
 class CCPageScaleAnimation;
 class CCLayerImpl;
 class CCLayerTreeHostImplTimeSourceAdapter;
@@ -109,7 +110,7 @@
     void finishAllRendering();
     int frameNumber() const { return m_frameNumber; }
 
-    bool initializeLayerRenderer(PassRefPtr<GraphicsContext3D>);
+    bool initializeLayerRenderer(PassRefPtr<GraphicsContext3D>, CCFontAtlas* headsUpDisplayFontAtlas = 0);
     bool isContextLost();
     LayerRendererChromium* layerRenderer() { return m_layerRenderer.get(); }
     const LayerRendererCapabilities& layerRendererCapabilities() const;

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.cpp (114146 => 114147)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.cpp	2012-04-13 18:06:15 UTC (rev 114146)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.cpp	2012-04-13 18:06:50 UTC (rev 114147)
@@ -132,7 +132,7 @@
     ASSERT(m_contextBeforeInitialization);
     {
         DebugScopedSetImplThread impl;
-        bool ok = m_layerTreeHostImpl->initializeLayerRenderer(m_contextBeforeInitialization.release());
+        bool ok = m_layerTreeHostImpl->initializeLayerRenderer(m_contextBeforeInitialization.release(), m_layerTreeHost->headsUpDisplayFontAtlas());
         if (ok) {
             m_layerRendererInitialized = true;
             m_layerRendererCapabilitiesForMainThread = m_layerTreeHostImpl->layerRendererCapabilities();
@@ -156,7 +156,7 @@
     {
         DebugScopedSetImplThread impl;
         m_layerTreeHost->deleteContentsTexturesOnImplThread(m_layerTreeHostImpl->contentsTextureAllocator());
-        initialized = m_layerTreeHostImpl->initializeLayerRenderer(context);
+        initialized = m_layerTreeHostImpl->initializeLayerRenderer(context, m_layerTreeHost->headsUpDisplayFontAtlas());
         if (initialized) {
             m_layerRendererCapabilitiesForMainThread = m_layerTreeHostImpl->layerRendererCapabilities();
         }

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.cpp (114146 => 114147)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.cpp	2012-04-13 18:06:15 UTC (rev 114146)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.cpp	2012-04-13 18:06:50 UTC (rev 114147)
@@ -716,7 +716,7 @@
     TRACE_EVENT("CCThreadProxy::initializeLayerRendererOnImplThread", this, 0);
     ASSERT(isImplThread());
     ASSERT(m_contextBeforeInitializationOnImplThread);
-    *initializeSucceeded = m_layerTreeHostImpl->initializeLayerRenderer(m_contextBeforeInitializationOnImplThread.release());
+    *initializeSucceeded = m_layerTreeHostImpl->initializeLayerRenderer(m_contextBeforeInitializationOnImplThread.release(), m_layerTreeHost->headsUpDisplayFontAtlas());
     if (*initializeSucceeded) {
         *capabilities = m_layerTreeHostImpl->layerRendererCapabilities();
         if (capabilities->usingSwapCompleteCallback)
@@ -753,7 +753,7 @@
     TRACE_EVENT0("cc", "CCThreadProxy::recreateContextOnImplThread");
     ASSERT(isImplThread());
     m_layerTreeHost->deleteContentsTexturesOnImplThread(m_layerTreeHostImpl->contentsTextureAllocator());
-    *recreateSucceeded = m_layerTreeHostImpl->initializeLayerRenderer(adoptRef(contextPtr));
+    *recreateSucceeded = m_layerTreeHostImpl->initializeLayerRenderer(adoptRef(contextPtr), m_layerTreeHost->headsUpDisplayFontAtlas());
     if (*recreateSucceeded) {
         *capabilities = m_layerTreeHostImpl->layerRendererCapabilities();
         m_schedulerOnImplThread->didRecreateContext();
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to