Source/WebCore/ChangeLog

 12012-04-11 Shawn Singh <shawnsingh@chromium.org>
 2
 3 [chromium] Support CCHeadsUpDisplay in threaded compositing mode
 4 https://bugs.webkit.org/show_bug.cgi?id=67499
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 No new tests because this code is debugging code itself.
 9
 10 The last item that was needed to make the CCHeadsUpDisplay work in
 11 threaded compositing mode was to remove the font rendering code
 12 used on the impl-side thread. To solve this, this patch adds a
 13 CCFontAtlas that is initialized on the main thread (where the font
 14 rendering takes place). Then, when the HUD draws text on the impl
 15 thread, it uses the font atlas directly.
 16
 17 * WebCore.gypi:
 18 * platform/graphics/chromium/LayerRendererChromium.cpp:
 19 (WebCore::LayerRendererChromium::create):
 20 (WebCore::LayerRendererChromium::initialize):
 21 * platform/graphics/chromium/LayerRendererChromium.h:
 22 (WebCore):
 23 (LayerRendererChromium):
 24 * platform/graphics/chromium/cc/CCFontAtlas.cpp: Added.
 25 (WebCore):
 26 (WebCore::CCFontAtlas::CCFontAtlas):
 27 (WebCore::wrapPositionIfNeeded):
 28 (WebCore::CCFontAtlas::generateAtlasForFont):
 29 (WebCore::CCFontAtlas::initialize):
 30 (WebCore::CCFontAtlas::drawText):
 31 (WebCore::CCFontAtlas::drawOneLineOfTextInternal):
 32 (WebCore::CCFontAtlas::drawDebugAtlas):
 33 * platform/graphics/chromium/cc/CCFontAtlas.h: Added.
 34 (WebCore):
 35 (CCFontAtlas):
 36 (WebCore::CCFontAtlas::create):
 37 * platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp:
 38 (WebCore::CCHeadsUpDisplay::CCHeadsUpDisplay):
 39 (WebCore::CCHeadsUpDisplay::showPlatformLayerTree):
 40 (WebCore::CCHeadsUpDisplay::drawHudContents):
 41 (WebCore::CCHeadsUpDisplay::drawFPSCounter):
 42 (WebCore::CCHeadsUpDisplay::drawPlatformLayerTree):
 43 * platform/graphics/chromium/cc/CCHeadsUpDisplay.h:
 44 (WebCore):
 45 (WebCore::CCHeadsUpDisplay::create):
 46 (CCHeadsUpDisplay):
 47 * platform/graphics/chromium/cc/CCLayerTreeHost.cpp:
 48 (WebCore::CCLayerTreeHost::initialize):
 49 * platform/graphics/chromium/cc/CCLayerTreeHost.h:
 50 (WebCore):
 51 (WebCore::CCLayerTreeHost::headsUpDisplayFontAtlas):
 52 (CCLayerTreeHost):
 53 * platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp:
 54 (WebCore::CCLayerTreeHostImpl::initializeLayerRenderer):
 55 * platform/graphics/chromium/cc/CCLayerTreeHostImpl.h:
 56 (WebCore):
 57 (CCLayerTreeHostImpl):
 58 * platform/graphics/chromium/cc/CCSingleThreadProxy.cpp:
 59 (WebCore::CCSingleThreadProxy::initializeLayerRenderer):
 60 (WebCore::CCSingleThreadProxy::recreateContext):
 61 * platform/graphics/chromium/cc/CCThreadProxy.cpp:
 62 (WebCore::CCThreadProxy::initializeLayerRendererOnImplThread):
 63 (WebCore::CCThreadProxy::recreateContextOnImplThread):
 64
1652012-04-10 James Robinson <jamesr@chromium.org>
266
367 [chromium] Fold LayerChromium::updateCompositorResources into main update

Source/WebKit/chromium/ChangeLog

 12012-04-11 Shawn Singh <shawnsingh@chromium.org>
 2
 3 [chromium] Support CCHeadsUpDisplay in threaded compositing mode
 4 https://bugs.webkit.org/show_bug.cgi?id=67499
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 * tests/CCLayerTreeHostImplTest.cpp:
 9 (WebKitTests::TEST_F):
 10 * tests/LayerRendererChromiumTest.cpp:
 11 (LayerRendererChromiumTest::SetUp):
 12
1132012-04-10 James Robinson <jamesr@chromium.org>
214
315 [chromium] Fold LayerChromium::updateCompositorResources into main update

Source/WebCore/WebCore.gypi

35853585 'platform/graphics/chromium/cc/CCDelayBasedTimeSource.h',
35863586 'platform/graphics/chromium/cc/CCDrawQuad.cpp',
35873587 'platform/graphics/chromium/cc/CCDrawQuad.h',
 3588 'platform/graphics/chromium/cc/CCFontAtlas.cpp',
 3589 'platform/graphics/chromium/cc/CCFontAtlas.h',
35883590 'platform/graphics/chromium/cc/CCFrameRateController.cpp',
35893591 'platform/graphics/chromium/cc/CCFrameRateController.h',
35903592 'platform/graphics/chromium/cc/CCGestureCurve.h',

Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp

@@private:
193193};
194194
195195
196 PassOwnPtr<LayerRendererChromium> LayerRendererChromium::create(LayerRendererChromiumClient* client, PassRefPtr<GraphicsContext3D> context)
 196PassOwnPtr<LayerRendererChromium> LayerRendererChromium::create(LayerRendererChromiumClient* client, PassRefPtr<GraphicsContext3D> context, CCFontAtlas* headsUpDisplayFontAtlas)
197197{
198198 OwnPtr<LayerRendererChromium> layerRenderer(adoptPtr(new LayerRendererChromium(client, context)));
199  if (!layerRenderer->initialize())
 199 if (!layerRenderer->initialize(headsUpDisplayFontAtlas))
200200 return nullptr;
201201
202202 return layerRenderer.release();

@@private:
234234 LayerRendererChromiumClient* m_client;
235235};
236236
237 bool LayerRendererChromium::initialize()
 237bool LayerRendererChromium::initialize(CCFontAtlas* headsUpDisplayFontAtlas)
238238{
239239 if (!m_context->makeContextCurrent())
240240 return false;

@@bool LayerRendererChromium::initialize()
304304 if (!initializeSharedObjects())
305305 return false;
306306
307  m_headsUpDisplay = CCHeadsUpDisplay::create(this);
 307 m_headsUpDisplay = CCHeadsUpDisplay::create(this, headsUpDisplayFontAtlas);
308308
309309 // Make sure the viewport and context gets initialized, even if it is to zero.
310310 viewportChanged();

Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h

5454
5555namespace WebCore {
5656
 57class CCFontAtlas;
5758class CCHeadsUpDisplay;
5859class CCLayerImpl;
5960class CCRenderPass;

@@public:
7980class LayerRendererChromium {
8081 WTF_MAKE_NONCOPYABLE(LayerRendererChromium);
8182public:
82  static PassOwnPtr<LayerRendererChromium> create(LayerRendererChromiumClient*, PassRefPtr<GraphicsContext3D>);
 83 static PassOwnPtr<LayerRendererChromium> create(LayerRendererChromiumClient*, PassRefPtr<GraphicsContext3D>, CCFontAtlas*);
8384
8485 ~LayerRendererChromium();
8586

@@protected:
168169 bool isFramebufferDiscarded() const { return m_isFramebufferDiscarded; }
169170
170171 LayerRendererChromium(LayerRendererChromiumClient*, PassRefPtr<GraphicsContext3D>);
171  bool initialize();
 172 bool initialize(CCFontAtlas*);
172173
173174private:
174175 void drawQuad(const CCDrawQuad*, const FloatRect& surfaceDamageRect);

Source/WebCore/platform/graphics/chromium/cc/CCFontAtlas.cpp

 1/*
 2 * Copyright (C) 2012 Google Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 16 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 23 */
 24
 25#include "config.h"
 26
 27#if USE(ACCELERATED_COMPOSITING)
 28#include "CCFontAtlas.h"
 29
 30#include "CCProxy.h"
 31#include "Font.h"
 32#include "FontCache.h"
 33#include "FontDescription.h"
 34#include "GraphicsContext.h"
 35#include "ImageBuffer.h"
 36#include "TextRun.h"
 37
 38#define ATLAS_SIZE 128
 39#define FONT_HEIGHT 14
 40
 41namespace WebCore {
 42
 43using namespace std;
 44
 45
 46CCFontAtlas::CCFontAtlas()
 47 : m_fontHeight(FONT_HEIGHT)
 48{
 49}
 50
 51static void wrapPositionIfNeeded(IntPoint& position, int textWidth, int textHeight)
 52{
 53 if (position.x() + textWidth > ATLAS_SIZE)
 54 position = IntPoint(0, position.y() + textHeight);
 55}
 56
 57void CCFontAtlas::generateAtlasForFont(GraphicsContext* atlasContext, const FontDescription& fontDescription, const Color& fontColor, const IntPoint& startingPosition, IntRect asciiToAtlasTable[128])
 58{
 59 ASSERT(CCProxy::isMainThread());
 60 ASSERT(m_atlas);
 61
 62 FontCachePurgePreventer fontCachePurgePreventer;
 63
 64 IntPoint position = startingPosition;
 65 int textHeight = fontDescription.computedPixelSize();
 66 // This is a dirty little trick to account for overhang letters like g, p, j.
 67 int inflation = textHeight / 3;
 68
 69 Font font(fontDescription, 0, 0);
 70 font.update(0);
 71
 72 atlasContext->setStrokeColor(fontColor, ColorSpaceDeviceRGB);
 73 atlasContext->setFillColor(fontColor, ColorSpaceDeviceRGB);
 74
 75 // First, draw a generic rect that will be used for special and unknown characters that have nothing else to render.
 76 {
 77 int textWidth = textHeight / 2;
 78 wrapPositionIfNeeded(position, textWidth, textHeight + inflation);
 79 atlasContext->strokeRect(FloatRect(FloatPoint(position.x() + 1, position.y() - textHeight + 1 + inflation), FloatSize(textWidth - 2, textHeight - 2 - inflation)), 1);
 80
 81 // Initialize the rect that would be copied when drawing this glyph from the atlas.
 82 asciiToAtlasTable[0] = IntRect(IntPoint(position.x(), position.y() - textHeight), IntSize(textWidth, textHeight + inflation));
 83
 84 // Increment to the position where the next glyph will be placed.
 85 position.setX(position.x() + textWidth);
 86 }
 87
 88 // Then, draw the ASCII characters.
 89 for (int i = 1; i < 128; ++i) {
 90
 91 if (i < 32) {
 92 // Special characters will simply use the the default glyph.
 93 asciiToAtlasTable[i] = asciiToAtlasTable[0];
 94 continue;
 95 }
 96
 97 UChar c = static_cast<UChar>(i);
 98 String str;
 99 str.append(c);
 100 TextRun text(str);
 101
 102 int textWidth = round(font.width(text));
 103 wrapPositionIfNeeded(position, textWidth, textHeight + inflation);
 104 atlasContext->drawText(font, text, position);
 105
 106 // Initialize the rect that would be copied when drawing this glyph from the atlas.
 107 asciiToAtlasTable[i] = IntRect(IntPoint(position.x(), position.y() - textHeight), IntSize(textWidth, textHeight + inflation));
 108
 109 // Increment to the position where the next glyph will be placed.
 110 position.setX(position.x() + textWidth);
 111 }
 112}
 113
 114void CCFontAtlas::initialize()
 115{
 116 ASSERT(CCProxy::isMainThread());
 117
 118 // 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.
 119 ASSERT(!m_atlas);
 120
 121 m_atlas = ImageBuffer::create(IntSize(ATLAS_SIZE, ATLAS_SIZE));
 122 GraphicsContext* atlasContext = m_atlas->context();
 123
 124 // Clear the entire texture atlas to transparent before drawing fonts.
 125 atlasContext->setFillColor(Color(0, 0, 0, 0), ColorSpaceDeviceRGB);
 126 atlasContext->fillRect(FloatRect(0, 0, ATLAS_SIZE, ATLAS_SIZE));
 127
 128 // FIXME: monospace font does not work as expected.
 129 FontDescription fontDescription;
 130 fontDescription.setGenericFamily(FontDescription::MonospaceFamily);
 131 fontDescription.setComputedSize(m_fontHeight);
 132 generateAtlasForFont(atlasContext, fontDescription, Color(255, 0, 0), IntPoint(0, fontDescription.computedPixelSize()), m_asciiToRectTable);
 133}
 134
 135void CCFontAtlas::drawText(GraphicsContext* targetContext, const String& text, const IntPoint& destPosition, const IntSize& targetSize) const
 136{
 137 ASSERT(CCProxy::isImplThread());
 138 ASSERT(m_atlas);
 139
 140 Vector<String> lines;
 141 text.split('\n', lines);
 142
 143 IntPoint position = destPosition;
 144 for (size_t i = 0; i < lines.size(); ++i) {
 145 drawOneLineOfTextInternal(targetContext, lines[i], position);
 146 position.setY(position.y() + m_fontHeight);
 147 if (position.y() > targetSize.height())
 148 return;
 149 }
 150}
 151
 152void CCFontAtlas::drawOneLineOfTextInternal(GraphicsContext* targetContext, const String& textLine, const IntPoint& destPosition) const
 153{
 154 ASSERT(CCProxy::isImplThread());
 155 ASSERT(m_atlas);
 156
 157 IntPoint position = destPosition;
 158 for (unsigned i = 0; i < textLine.length(); ++i) {
 159 // If the ASCII code is out of bounds, then index 0 is used, which is just a plain rectangle glyph.
 160 int asciiIndex = (textLine[i] < 128) ? textLine[i] : 0;
 161 IntRect glyphBounds = m_asciiToRectTable[asciiIndex];
 162 targetContext->drawImageBuffer(m_atlas.get(), ColorSpaceDeviceRGB, position, glyphBounds);
 163 position.setX(position.x() + glyphBounds.width());
 164 }
 165}
 166
 167void CCFontAtlas::drawDebugAtlas(GraphicsContext* targetContext, const IntPoint& destPosition) const
 168{
 169 ASSERT(CCProxy::isImplThread());
 170 ASSERT(m_atlas);
 171
 172 targetContext->drawImageBuffer(m_atlas.get(), ColorSpaceDeviceRGB, destPosition, IntRect(IntPoint::zero(), IntSize(ATLAS_SIZE, ATLAS_SIZE)));
 173}
 174
 175} // namespace WebCore
 176
 177#endif // USE(ACCELERATED_COMPOSITING)

Source/WebCore/platform/graphics/chromium/cc/CCFontAtlas.h

 1/*
 2 * Copyright (C) 2012 Google Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 16 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 23 */
 24
 25#ifndef CCFontAtlas_h
 26#define CCFontAtlas_h
 27
 28#if USE(ACCELERATED_COMPOSITING)
 29
 30#include "ImageBuffer.h"
 31#include <wtf/OwnPtr.h>
 32#include <wtf/PassOwnPtr.h>
 33#include <wtf/text/WTFString.h>
 34
 35namespace WebCore {
 36
 37class Color;
 38class FontDescription;
 39class IntPoint;
 40class IntRect;
 41class GraphicsContext;
 42
 43// This class provides basic ability to draw text onto the heads-up display.
 44// It must be initialized on the main thread, and it can only draw text on the impl thread.
 45class CCFontAtlas {
 46 WTF_MAKE_NONCOPYABLE(CCFontAtlas);
 47public:
 48 static PassOwnPtr<CCFontAtlas> create()
 49 {
 50 return adoptPtr(new CCFontAtlas());
 51 }
 52
 53 // Creates the font atlas.
 54 // Should only be called on the main thread.
 55 void initialize();
 56
 57 // Draws multiple lines of text where each line of text is separated by '\n'.
 58 // Should only be called only on the impl thread.
 59 void drawText(GraphicsContext*, const String& text, const IntPoint& destPosition, const IntSize& targetSize) const;
 60
 61 // Draws the entire atlas at the specified position, just for debugging purposes.
 62 void drawDebugAtlas(GraphicsContext*, const IntPoint& destPosition) const;
 63
 64private:
 65 CCFontAtlas();
 66
 67 // Paints the font into the atlas, from left-to-right, top-to-bottom, starting at
 68 // startingPosition. At the same time, it updates the ascii-to-IntRect mapping for
 69 // each character. By doing things this way, it is possible to support variable-width
 70 // fonts and multiple fonts on the same atlas.
 71 void generateAtlasForFont(GraphicsContext*, const FontDescription&, const Color& fontColor, const IntPoint& startingPosition, IntRect asciiToAtlasTable[128]);
 72
 73 void drawOneLineOfTextInternal(GraphicsContext*, const String&, const IntPoint& destPosition) const;
 74
 75 // The actual texture atlas containing all the pre-rendered glyphs.
 76 OwnPtr<ImageBuffer> m_atlas;
 77
 78 // The look-up tables mapping ascii characters to their IntRect locations on the atlas.
 79 IntRect m_asciiToRectTable[128];
 80
 81 int m_fontHeight;
 82};
 83
 84} // namespace WebCore
 85
 86#endif // USE(ACCELERATED_COMPOSITING)
 87
 88#endif

Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp

2727#if USE(ACCELERATED_COMPOSITING)
2828#include "CCHeadsUpDisplay.h"
2929
 30#include "CCFontAtlas.h"
3031#include "Extensions3DChromium.h"
31 #include "Font.h"
32 #include "FontCache.h"
33 #include "FontDescription.h"
3432#include "GraphicsContext3D.h"
3533#include "InspectorController.h"
3634#include "LayerChromium.h"

@@namespace WebCore {
4846
4947using namespace std;
5048
51 CCHeadsUpDisplay::CCHeadsUpDisplay(LayerRendererChromium* owner)
 49CCHeadsUpDisplay::CCHeadsUpDisplay(LayerRendererChromium* owner, CCFontAtlas* headsUpDisplayFontAtlas)
5250 : m_currentFrameNumber(1)
5351 , m_filteredFrameTime(0)
5452 , m_layerRenderer(owner)
5553 , m_useMapSubForUploads(owner->contextSupportsMapSub())
 54 , m_fontAtlas(headsUpDisplayFontAtlas)
5655{
5756 m_beginTimeHistoryInSec[0] = currentTime();
5857 m_beginTimeHistoryInSec[1] = m_beginTimeHistoryInSec[0];
5958 for (int i = 2; i < kBeginFrameHistorySize; i++)
6059 m_beginTimeHistoryInSec[i] = 0;
61 
62  // We can't draw text in threaded mode with the current mechanism.
63  // FIXME: Figure out a way to draw text in threaded mode.
64  if (!CCProxy::implThread())
65  initializeFonts();
6660}
6761
6862CCHeadsUpDisplay::~CCHeadsUpDisplay()
6963{
7064}
7165
72 void CCHeadsUpDisplay::initializeFonts()
73 {
74  ASSERT(!CCProxy::implThread());
75  FontDescription mediumFontDesc;
76  mediumFontDesc.setGenericFamily(FontDescription::MonospaceFamily);
77  mediumFontDesc.setComputedSize(20);
78 
79  m_mediumFont = adoptPtr(new Font(mediumFontDesc, 0, 0));
80  m_mediumFont->update(0);
81 
82  FontDescription smallFontDesc;
83  smallFontDesc.setGenericFamily(FontDescription::MonospaceFamily);
84  smallFontDesc.setComputedSize(10);
85 
86  m_smallFont = adoptPtr(new Font(smallFontDesc, 0, 0));
87  m_smallFont->update(0);
88 }
89 
9066void CCHeadsUpDisplay::onFrameBegin(double timestamp)
9167{
9268 m_beginTimeHistoryInSec[m_currentFrameNumber % kBeginFrameHistorySize] = timestamp;

@@bool CCHeadsUpDisplay::enabled() const
10480
10581bool CCHeadsUpDisplay::showPlatformLayerTree() const
10682{
107  return settings().showPlatformLayerTree && !CCProxy::implThread();
 83 return settings().showPlatformLayerTree;
10884}
10985
11086void CCHeadsUpDisplay::draw()

@@void CCHeadsUpDisplay::drawHudContents(GraphicsContext* context, const IntSize&
193169 drawFPSCounter(context, fpsCounterTop, fpsCounterHeight);
194170
195171 if (showPlatformLayerTree())
196  drawPlatformLayerTree(context, platformLayerTreeTop);
 172 drawPlatformLayerTree(context, hudSize, platformLayerTreeTop);
197173}
198174
199175void CCHeadsUpDisplay::drawFPSCounter(GraphicsContext* context, int top, int height)

@@void CCHeadsUpDisplay::drawFPSCounter(GraphicsContext* context, int top, int hei
211187 } else
212188 m_filteredFrameTime = ((1.0 - alpha) * m_filteredFrameTime) + (alpha * secForLastFrame);
213189
214  float textWidth = 0;
215  if (!CCProxy::implThread())
216  textWidth = drawFPSCounterText(context, top, height);
217 
 190 float textWidth = 80;
218191 float graphWidth = kBeginFrameHistorySize;
219192
220  // Draw background for graph
 193 // Draw background for text and graph
221194 context->setFillColor(Color(0, 0, 0, 255), ColorSpaceDeviceRGB);
222  context->fillRect(FloatRect(2 + textWidth, top, graphWidth, height));
 195 context->fillRect(FloatRect(2, top, textWidth + graphWidth, height));
 196
 197 // Draw FPS text.
 198 if (m_fontAtlas)
 199 m_fontAtlas->drawText(context, String::format("FPS: %5.1f", 1.0 / m_filteredFrameTime), IntPoint(10, top + 4), IntSize(textWidth, height));
223200
224201 // Draw FPS graph.
225202 const double loFPS = 0.0;

@@void CCHeadsUpDisplay::drawFPSCounter(GraphicsContext* context, int top, int hei
246223 }
247224}
248225
249 float CCHeadsUpDisplay::drawFPSCounterText(GraphicsContext* context, int top, int height)
250 {
251  ASSERT(!CCProxy::implThread());
252 
253  FontCachePurgePreventer fontCachePurgePreventer;
254 
255  // Create & measure FPS text.
256  String text(String::format("FPS: %5.1f", 1.0 / m_filteredFrameTime));
257  TextRun run(text);
258  float textWidth = m_mediumFont->width(run) + 2.0f;
259 
260  // Draw background.
261  context->setFillColor(Color(0, 0, 0, 255), ColorSpaceDeviceRGB);
262  context->fillRect(FloatRect(2, top, textWidth, height));
263 
264  // Draw FPS text.
265  if (m_filteredFrameTime) {
266  context->setFillColor(Color(255, 0, 0), ColorSpaceDeviceRGB);
267  context->drawText(*m_mediumFont, run, IntPoint(3, top + height - 6));
268  }
269 
270  return textWidth;
271 }
272 
273 void CCHeadsUpDisplay::drawPlatformLayerTree(GraphicsContext* context, int top)
 226void CCHeadsUpDisplay::drawPlatformLayerTree(GraphicsContext* context, const IntSize& hudSize, int top)
274227{
275  ASSERT(!CCProxy::implThread());
276 
277  FontCachePurgePreventer fontCachePurgePreventer;
278 
279  float smallFontHeight = m_smallFont->fontMetrics().floatHeight();
280  int y = top + smallFontHeight - 4;
281  context->setFillColor(Color(255, 0, 0), ColorSpaceDeviceRGB);
282  Vector<String> lines;
283  m_layerRenderer->layerTreeAsText().split('\n', lines);
284  for (size_t i = 0; i < lines.size(); ++i) {
285  context->drawText(*m_smallFont, TextRun(lines[i]), IntPoint(2, y));
286  y += smallFontHeight;
287  }
 228 if (m_fontAtlas)
 229 m_fontAtlas->drawText(context, m_layerRenderer->layerTreeAsText(), IntPoint(2, top), hudSize);
288230}
289231
290232const CCSettings& CCHeadsUpDisplay::settings() const

Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.h

2727
2828#if USE(ACCELERATED_COMPOSITING)
2929
30 #include "Font.h"
3130#include "ProgramBinding.h"
3231#include "ShaderChromium.h"
3332
3433namespace WebCore {
3534
3635struct CCSettings;
 36class CCFontAtlas;
3737class GeometryBinding;
3838class GraphicsContext3D;
3939class LayerRendererChromium;

@@class ManagedTexture;
4343class CCHeadsUpDisplay {
4444 WTF_MAKE_NONCOPYABLE(CCHeadsUpDisplay);
4545public:
46  static PassOwnPtr<CCHeadsUpDisplay> create(LayerRendererChromium* owner)
 46 static PassOwnPtr<CCHeadsUpDisplay> create(LayerRendererChromium* owner, CCFontAtlas* headsUpDisplayFontAtlas)
4747 {
48  return adoptPtr(new CCHeadsUpDisplay(owner));
 48 return adoptPtr(new CCHeadsUpDisplay(owner, headsUpDisplayFontAtlas));
4949 }
5050
5151 ~CCHeadsUpDisplay();

@@public:
6161 typedef ProgramBinding<VertexShaderPosTex, FragmentShaderRGBATexSwizzleAlpha> Program;
6262
6363private:
64  explicit CCHeadsUpDisplay(LayerRendererChromium* owner);
 64 explicit CCHeadsUpDisplay(LayerRendererChromium* owner, CCFontAtlas* headsUpDisplayFontAtlas);
6565 void drawHudContents(GraphicsContext*, const IntSize& hudSize);
6666 void drawFPSCounter(GraphicsContext*, int top, int height);
67  float drawFPSCounterText(GraphicsContext*, int top, int height);
68  void drawPlatformLayerTree(GraphicsContext*, int top);
 67 void drawPlatformLayerTree(GraphicsContext*, const IntSize& hudSize, int top);
6968 const CCSettings& settings() const;
7069
7170 bool showPlatformLayerTree() const;
7271
73  void initializeFonts();
74 
7572 int m_currentFrameNumber;
7673
7774 double m_filteredFrameTime;

@@private:
8380 static const int kBeginFrameHistorySize = 64;
8481 double m_beginTimeHistoryInSec[kBeginFrameHistorySize];
8582
86  OwnPtr<Font> m_smallFont;
87  OwnPtr<Font> m_mediumFont;
88 
8983 bool m_useMapSubForUploads;
 84
 85 CCFontAtlas* m_fontAtlas;
9086};
9187
9288}

Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp

3232#include "Region.h"
3333#include "TraceEvent.h"
3434#include "TreeSynchronizer.h"
 35#include "cc/CCFontAtlas.h"
3536#include "cc/CCLayerAnimationController.h"
3637#include "cc/CCLayerIterator.h"
3738#include "cc/CCLayerTreeHostCommon.h"

@@bool CCLayerTreeHost::initialize()
99100 if (!m_proxy->initializeContext())
100101 return false;
101102
 103 // Only allocate the font atlas if we have reason to use the heads-up display.
 104 if (m_settings.showFPSCounter || m_settings.showPlatformLayerTree) {
 105 m_headsUpDisplayFontAtlas = CCFontAtlas::create();
 106 m_headsUpDisplayFontAtlas->initialize();
 107 }
 108
102109 m_compositorIdentifier = m_proxy->compositorIdentifier();
103110 return true;
104111}

Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h

4343
4444namespace WebCore {
4545
 46class CCFontAtlas;
4647class CCLayerTreeHostImpl;
4748class CCTextureUpdater;
4849class GraphicsContext3D;

@@public:
219220 bool requestPartialTextureUpdate();
220221 void deleteTextureAfterCommit(PassOwnPtr<ManagedTexture>);
221222
 223 CCFontAtlas* headsUpDisplayFontAtlas() { return m_headsUpDisplayFontAtlas.get(); }
 224
222225protected:
223226 CCLayerTreeHost(CCLayerTreeHostClient*, const CCSettings&);
224227 bool initialize();

@@private:
262265
263266 CCSettings m_settings;
264267
 268 // This is owned by the main layer tree host because it needs to be initialized on the main thread.
 269 OwnPtr<CCFontAtlas> m_headsUpDisplayFontAtlas;
 270
265271 IntSize m_viewportSize;
266272 bool m_visible;
267273 typedef HashMap<GraphicsContext3D*, RefPtr<RateLimiter> > RateLimiterMap;

Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp

@@void CCLayerTreeHostImpl::setVisible(bool visible)
497497 m_timeSourceClientAdapter->setActive(shouldTickInBackground);
498498}
499499
500 bool CCLayerTreeHostImpl::initializeLayerRenderer(PassRefPtr<GraphicsContext3D> context)
 500bool CCLayerTreeHostImpl::initializeLayerRenderer(PassRefPtr<GraphicsContext3D> context, CCFontAtlas* headsUpDisplayFontAtlas)
501501{
502502 OwnPtr<LayerRendererChromium> layerRenderer;
503  layerRenderer = LayerRendererChromium::create(this, context);
 503 layerRenderer = LayerRendererChromium::create(this, context, headsUpDisplayFontAtlas);
504504
505505 // Since we now have a new context/layerRenderer, we cannot continue to use the old
506506 // resources (i.e. renderSurfaces and texture IDs).

Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h

@@namespace WebCore {
4040
4141class CCActiveGestureAnimation;
4242class CCCompletionEvent;
 43class CCFontAtlas;
4344class CCPageScaleAnimation;
4445class CCLayerImpl;
4546class CCLayerTreeHostImplTimeSourceAdapter;

@@public:
109110 void finishAllRendering();
110111 int frameNumber() const { return m_frameNumber; }
111112
112  bool initializeLayerRenderer(PassRefPtr<GraphicsContext3D>);
 113 bool initializeLayerRenderer(PassRefPtr<GraphicsContext3D>, CCFontAtlas* headsUpDisplayFontAtlas);
113114 bool isContextLost();
114115 LayerRendererChromium* layerRenderer() { return m_layerRenderer.get(); }
115116 const LayerRendererCapabilities& layerRendererCapabilities() const;

Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.cpp

@@bool CCSingleThreadProxy::initializeLayerRenderer()
135135 ASSERT(m_contextBeforeInitialization);
136136 {
137137 DebugScopedSetImplThread impl;
138  bool ok = m_layerTreeHostImpl->initializeLayerRenderer(m_contextBeforeInitialization.release());
 138 bool ok = m_layerTreeHostImpl->initializeLayerRenderer(m_contextBeforeInitialization.release(), m_layerTreeHost->headsUpDisplayFontAtlas());
139139 if (ok) {
140140 m_layerRendererInitialized = true;
141141 m_layerRendererCapabilitiesForMainThread = m_layerTreeHostImpl->layerRendererCapabilities();

@@bool CCSingleThreadProxy::recreateContext()
159159 {
160160 DebugScopedSetImplThread impl;
161161 m_layerTreeHost->deleteContentsTexturesOnImplThread(m_layerTreeHostImpl->contentsTextureAllocator());
162  initialized = m_layerTreeHostImpl->initializeLayerRenderer(context);
 162 initialized = m_layerTreeHostImpl->initializeLayerRenderer(context, m_layerTreeHost->headsUpDisplayFontAtlas());
163163 if (initialized) {
164164 m_layerRendererCapabilitiesForMainThread = m_layerTreeHostImpl->layerRendererCapabilities();
165165 }

Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.cpp

@@void CCThreadProxy::initializeLayerRendererOnImplThread(CCCompletionEvent* compl
716716 TRACE_EVENT("CCThreadProxy::initializeLayerRendererOnImplThread", this, 0);
717717 ASSERT(isImplThread());
718718 ASSERT(m_contextBeforeInitializationOnImplThread);
719  *initializeSucceeded = m_layerTreeHostImpl->initializeLayerRenderer(m_contextBeforeInitializationOnImplThread.release());
 719 *initializeSucceeded = m_layerTreeHostImpl->initializeLayerRenderer(m_contextBeforeInitializationOnImplThread.release(), m_layerTreeHost->headsUpDisplayFontAtlas());
720720 if (*initializeSucceeded) {
721721 *capabilities = m_layerTreeHostImpl->layerRendererCapabilities();
722722 if (capabilities->usingSwapCompleteCallback)

@@void CCThreadProxy::recreateContextOnImplThread(CCCompletionEvent* completion, G
753753 TRACE_EVENT0("cc", "CCThreadProxy::recreateContextOnImplThread");
754754 ASSERT(isImplThread());
755755 m_layerTreeHost->deleteContentsTexturesOnImplThread(m_layerTreeHostImpl->contentsTextureAllocator());
756  *recreateSucceeded = m_layerTreeHostImpl->initializeLayerRenderer(adoptRef(contextPtr));
 756 *recreateSucceeded = m_layerTreeHostImpl->initializeLayerRenderer(adoptRef(contextPtr), m_layerTreeHost->headsUpDisplayFontAtlas());
757757 if (*recreateSucceeded) {
758758 *capabilities = m_layerTreeHostImpl->layerRendererCapabilities();
759759 m_schedulerOnImplThread->didRecreateContext();

Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp

@@TEST_F(CCLayerTreeHostImplTest, nonFastScrollableRegionBasic)
247247
248248TEST_F(CCLayerTreeHostImplTest, nonFastScrollableRegionWithOffset)
249249{
250  m_hostImpl->initializeLayerRenderer(createContext());
 250 m_hostImpl->initializeLayerRenderer(createContext(), 0);
251251
252252 OwnPtr<CCLayerImpl> root = CCLayerImpl::create(0);
253253 root->setScrollable(true);

@@private:
433433
434434TEST_F(CCLayerTreeHostImplTest, didDrawNotCalledOnHiddenLayer)
435435{
436  m_hostImpl->initializeLayerRenderer(createContext());
 436 m_hostImpl->initializeLayerRenderer(createContext(), 0);
437437
438438 // Ensure visibleLayerRect for root layer is empty
439439 m_hostImpl->setViewportSize(IntSize(0, 0));

@@TEST_F(CCLayerTreeHostImplTest, didDrawNotCalledOnHiddenLayer)
471471
472472TEST_F(CCLayerTreeHostImplTest, didDrawCalledOnAllLayers)
473473{
474  m_hostImpl->initializeLayerRenderer(createContext());
 474 m_hostImpl->initializeLayerRenderer(createContext(), 0);
475475 m_hostImpl->setViewportSize(IntSize(10, 10));
476476
477477 m_hostImpl->setRootLayer(DidDrawCheckLayer::create(0));

@@private:
523523
524524TEST_F(CCLayerTreeHostImplTest, prepareToDrawFailsWhenAnimationUsesCheckerboard)
525525{
526  m_hostImpl->initializeLayerRenderer(createContext());
 526 m_hostImpl->initializeLayerRenderer(createContext(), 0);
527527 m_hostImpl->setViewportSize(IntSize(10, 10));
528528
529529 // When the texture is not missing, we draw as usual.

@@private:
644644// https://bugs.webkit.org/show_bug.cgi?id=75783
645645TEST_F(CCLayerTreeHostImplTest, blendingOffWhenDrawingOpaqueLayers)
646646{
647  m_hostImpl->initializeLayerRenderer(createContext());
 647 m_hostImpl->initializeLayerRenderer(createContext(), 0);
648648 m_hostImpl->setViewportSize(IntSize(10, 10));
649649
650650 {

@@TEST_F(CCLayerTreeHostImplTest, blendingOffWhenDrawingOpaqueLayers)
846846
847847TEST_F(CCLayerTreeHostImplTest, viewportCovered)
848848{
849  m_hostImpl->initializeLayerRenderer(createContext());
 849 m_hostImpl->initializeLayerRenderer(createContext(), 0);
850850 m_hostImpl->setBackgroundColor(Color::gray);
851851
852852 IntSize viewportSize(100, 100);

@@TEST_F(CCLayerTreeHostImplTest, reshapeNotCalledUntilDraw)
953953{
954954 ReshapeTrackerContext* reshapeTracker = new ReshapeTrackerContext();
955955 RefPtr<GraphicsContext3D> context = GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(reshapeTracker), GraphicsContext3D::RenderDirectlyToHostWindow);
956  m_hostImpl->initializeLayerRenderer(context);
 956 m_hostImpl->initializeLayerRenderer(context, 0);
957957 m_hostImpl->setViewportSize(IntSize(10, 10));
958958
959959 CCLayerImpl* root = new FakeDrawableCCLayerImpl(1);

@@TEST_F(CCLayerTreeHostImplTest, partialSwapReceivesDamageRect)
10021002 CCSettings settings;
10031003 settings.partialSwapEnabled = true;
10041004 OwnPtr<CCLayerTreeHostImpl> layerTreeHostImpl = CCLayerTreeHostImpl::create(settings, this);
1005  layerTreeHostImpl->initializeLayerRenderer(context);
 1005 layerTreeHostImpl->initializeLayerRenderer(context, 0);
10061006 layerTreeHostImpl->setViewportSize(IntSize(500, 500));
10071007
10081008 CCLayerImpl* root = new FakeDrawableCCLayerImpl(1);

@@private:
10851085
10861086TEST_F(CCLayerTreeHostImplTest, contextLostAndRestoredNotificationSentToAllLayers)
10871087{
1088  m_hostImpl->initializeLayerRenderer(createContext());
 1088 m_hostImpl->initializeLayerRenderer(createContext(), 0);
10891089 m_hostImpl->setViewportSize(IntSize(10, 10));
10901090
10911091 m_hostImpl->setRootLayer(ContextLostNotificationCheckLayer::create(0));

@@TEST_F(CCLayerTreeHostImplTest, contextLostAndRestoredNotificationSentToAllLayer
11011101 EXPECT_FALSE(layer1->didLoseContextCalled());
11021102 EXPECT_FALSE(layer2->didLoseContextCalled());
11031103
1104  m_hostImpl->initializeLayerRenderer(createContext());
 1104 m_hostImpl->initializeLayerRenderer(createContext(), 0);
11051105
11061106 EXPECT_TRUE(root->didLoseContextCalled());
11071107 EXPECT_TRUE(layer1->didLoseContextCalled());

@@public:
11161116TEST_F(CCLayerTreeHostImplTest, finishAllRenderingAfterContextLost)
11171117{
11181118 // The context initialization will fail, but we should still be able to call finishAllRendering() without any ill effects.
1119  m_hostImpl->initializeLayerRenderer(GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(new FakeWebGraphicsContext3DMakeCurrentFails), GraphicsContext3D::RenderDirectlyToHostWindow));
 1119 m_hostImpl->initializeLayerRenderer(GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(new FakeWebGraphicsContext3DMakeCurrentFails), GraphicsContext3D::RenderDirectlyToHostWindow), 0);
11201120 m_hostImpl->finishAllRendering();
11211121}
11221122

@@private:
11321132
11331133TEST_F(CCLayerTreeHostImplTest, scrollbarLayerLostContext)
11341134{
1135  m_hostImpl->initializeLayerRenderer(createContext());
 1135 m_hostImpl->initializeLayerRenderer(createContext(), 0);
11361136 m_hostImpl->setViewportSize(IntSize(10, 10));
11371137
11381138 m_hostImpl->setRootLayer(ScrollbarLayerFakePaint::create(0));

@@TEST_F(CCLayerTreeHostImplTest, scrollbarLayerLostContext)
11491149 // Scrollbar layer should always generate quads, even after lost context
11501150 EXPECT_GT(renderPass->quadList().size(), 0u);
11511151
1152  m_hostImpl->initializeLayerRenderer(createContext());
 1152 m_hostImpl->initializeLayerRenderer(createContext(), 0);
11531153 }
11541154}
11551155

Source/WebKit/chromium/tests/LayerRendererChromiumTest.cpp

@@protected:
112112
113113 virtual void SetUp()
114114 {
115  m_layerRendererChromium.initialize();
 115 m_layerRendererChromium.initialize(0);
116116 }
117117
118118 void swapBuffers()