Skip to content

Commit

Permalink
cc: Switch HudLayer to use skia's font rendering
Browse files Browse the repository at this point in the history
This change switches the font rendering on the HudLayer to skia's font
rendering. The old FontAtlas plumbing is still left in case of a necessary
rollback. This change also includes some refactorings and UI changes of
PlatformLayerTree and MemoryStats.

Screenshot: https://docs.google.com/file/d/0B8Y78t3tjy1XdFNIWlh5SF95aFU/edit?usp=sharing

BUG=172284


Review URL: https://chromiumcodereview.appspot.com/12210056

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@181525 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
egraether@chromium.org committed Feb 8, 2013
1 parent 70ddea6 commit fbf3a62
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 78 deletions.
2 changes: 1 addition & 1 deletion cc/frame_rate_counter.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class FrameRateCounter {
// FIXME: Determine this threshold based on monitor refresh rate, crbug.com/138642.
static const double kDroppedFrameTime;

RingBuffer<base::TimeTicks, 130> m_ringBuffer;
RingBuffer<base::TimeTicks, 136> m_ringBuffer;

bool m_hasImplThread;
int m_droppedFrameCount;
Expand Down
4 changes: 2 additions & 2 deletions cc/heads_up_display_layer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ HeadsUpDisplayLayer::HeadsUpDisplayLayer()
: Layer()
, m_hasFontAtlas(false)
{
setBounds(gfx::Size(256, 128));
setBounds(gfx::Size(256, 256));
}

HeadsUpDisplayLayer::~HeadsUpDisplayLayer()
Expand All @@ -40,7 +40,7 @@ void HeadsUpDisplayLayer::update(ResourceUpdateQueue&, const OcclusionTracker*,
int height = std::min(maxTextureSize, layerTreeHost()->layoutViewportSize().height());
bounds = gfx::Size(width, height);
} else {
bounds = gfx::Size(256, 128);
bounds = gfx::Size(256, 256);
matrix.Translate(layerTreeHost()->layoutViewportSize().width() - 256, 0);
}

Expand Down
149 changes: 78 additions & 71 deletions cc/heads_up_display_layer_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "cc/heads_up_display_layer_impl.h"

#include "base/string_split.h"
#include "base/stringprintf.h"
#include "cc/debug_colors.h"
#include "cc/debug_rect_history.h"
Expand All @@ -21,7 +22,9 @@
#include "third_party/khronos/GLES2/gl2.h"
#include "third_party/khronos/GLES2/gl2ext.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkFontHost.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "third_party/skia/include/core/SkTypeface.h"
#include "third_party/skia/include/effects/SkColorMatrixFilter.h"
#include "ui/gfx/point.h"
#include "ui/gfx/size.h"
Expand Down Expand Up @@ -70,6 +73,7 @@ HeadsUpDisplayLayerImpl::HeadsUpDisplayLayerImpl(LayerTreeImpl* treeImpl, int id
: LayerImpl(treeImpl, id)
, m_fpsGraph(60.0, 80.0)
, m_paintTimeGraph(16.0, 48.0)
, m_typeface(skia::AdoptRef(SkFontHost::CreateTypeface(NULL, "monospace", SkTypeface::kBold)))
{
}

Expand Down Expand Up @@ -192,18 +196,13 @@ void HeadsUpDisplayLayerImpl::drawHudContents(SkCanvas* canvas)
{
const LayerTreeDebugState& debugState = layerTreeImpl()->debug_state();

FrameRateCounter* fpsCounter = layerTreeImpl()->frame_rate_counter();
MemoryHistory* memoryHistory = layerTreeImpl()->memory_history();
PaintTimeCounter* paintTimeCounter = layerTreeImpl()->paint_time_counter();

if (debugState.showPlatformLayerTree) {
SkPaint paint = createPaint();
drawGraphBackground(canvas, &paint, SkRect::MakeXYWH(0, 0, bounds().width(), bounds().height()));
}

int top = 2;
if (debugState.showPlatformLayerTree)
drawPlaformLayerTree(canvas);

if (debugState.continuousPainting || debugState.showFPSCounter) {
FrameRateCounter* fpsCounter = layerTreeImpl()->frame_rate_counter();
PaintTimeCounter* paintTimeCounter = layerTreeImpl()->paint_time_counter();

// Update numbers not every frame so text is readable
base::TimeTicks now = base::TimeTicks::Now();
if (base::TimeDelta(now - m_timeOfLastGraphUpdate).InSecondsF() > 0.25) {
Expand All @@ -221,48 +220,36 @@ void HeadsUpDisplayLayerImpl::drawHudContents(SkCanvas* canvas)
m_timeOfLastGraphUpdate = now;
}

int top = 2;
if (debugState.continuousPainting)
top = drawPaintTimeDisplay(canvas, paintTimeCounter, top);
// Don't show the FPS display when continuous painting is enabled, because it would show misleading numbers.
else if (debugState.showFPSCounter) {
else if (debugState.showFPSCounter)
top = drawFPSDisplay(canvas, fpsCounter, top);
}
if (debugState.continuousPainting ||
debugState.showFPSCounter) {
top = drawMemoryDisplay(canvas, memoryHistory, top);
}
}

if (debugState.showPlatformLayerTree && m_fontAtlas) {
std::string layerTree = layerTreeImpl()->layer_tree_as_text();
SkPaint paint = createPaint();
m_fontAtlas->setColor(DebugColors::PlatformLayerTreeTextColor());
m_fontAtlas->drawText(canvas, &paint, layerTree, gfx::Point(2, top), bounds());
drawMemoryDisplay(canvas, layerTreeImpl()->memory_history(), top);
}

if (debugState.showHudRects())
drawDebugRects(canvas, layerTreeImpl()->debug_rect_history());
}

void HeadsUpDisplayLayerImpl::drawTextLeftAligned(SkCanvas* canvas, SkPaint* paint, const SkRect& bounds, const std::string& text)
void HeadsUpDisplayLayerImpl::drawText(SkCanvas* canvas, SkPaint* paint, const std::string& text, const SkPaint::Align& align, const int& size, const int& x, const int& y)
{
if (!m_fontAtlas)
return;
const bool antiAlias = paint->isAntiAlias();
paint->setAntiAlias(true);

paint->setTextSize(size);
paint->setTextAlign(align);
paint->setTypeface(m_typeface.get());
canvas->drawText(text.c_str(), text.length(), x, y, *paint);

m_fontAtlas->drawText(canvas, paint, text, gfx::Point(bounds.left(), bounds.top()), gfx::Size(bounds.width(), bounds.height()));
paint->setAntiAlias(antiAlias);
}

void HeadsUpDisplayLayerImpl::drawTextRightAligned(SkCanvas* canvas, SkPaint* paint, const SkRect& bounds, const std::string& text)
void HeadsUpDisplayLayerImpl::drawText(SkCanvas* canvas, SkPaint* paint, const std::string& text, const SkPaint::Align& align, const int& size, const SkPoint& pos)
{
if (!m_fontAtlas)
return;

int textWidth = m_fontAtlas->textSize(text).width();

gfx::Point textPosition(bounds.right() - textWidth, bounds.top());
gfx::Size textArea(bounds.width(), bounds.height());

m_fontAtlas->drawText(canvas, paint, text, textPosition, textArea);
drawText(canvas, paint, text, align, size, pos.x(), pos.y());
}

void HeadsUpDisplayLayerImpl::drawGraphBackground(SkCanvas* canvas, SkPaint* paint, const SkRect& bounds)
Expand All @@ -284,12 +271,28 @@ void HeadsUpDisplayLayerImpl::drawGraphLines(SkCanvas* canvas, SkPaint* paint, c
canvas->drawLine(bounds.left(), bounds.top() + indicatorTop, bounds.right(), bounds.top() + indicatorTop, *paint);
}

void HeadsUpDisplayLayerImpl::drawPlaformLayerTree(SkCanvas* canvas)
{
const int fontHeight = 14;
SkPaint paint = createPaint();
drawGraphBackground(canvas, &paint, SkRect::MakeXYWH(0, 0, bounds().width(), bounds().height()));

std::string layerTree = layerTreeImpl()->layer_tree_as_text();
std::vector<std::string> lines;
base::SplitString(layerTree, '\n', &lines);

paint.setColor(DebugColors::PlatformLayerTreeTextColor());
for (size_t i = 0; i < lines.size() && static_cast<int>(2 + i * fontHeight) < bounds().height(); ++i) {
drawText(canvas, &paint, lines[i], SkPaint::kLeft_Align, fontHeight, 2, 2 + (i + 1) * fontHeight);
}
}

int HeadsUpDisplayLayerImpl::drawFPSDisplay(SkCanvas* canvas, FrameRateCounter* fpsCounter, const int& top)
{
const int padding = 4;
const int gap = 6;

const int fontHeight = m_fontAtlas.get() ? m_fontAtlas->fontHeight() : 0;
const int fontHeight = 15;

const int graphWidth = fpsCounter->timeStampHistorySize() - 2;
const int graphHeight = 40;
Expand All @@ -308,11 +311,12 @@ int HeadsUpDisplayLayerImpl::drawFPSDisplay(SkCanvas* canvas, FrameRateCounter*
SkRect graphBounds = SkRect::MakeXYWH(left + padding, textBounds.bottom() + 2 * padding, graphWidth, graphHeight);
SkRect histogramBounds = SkRect::MakeXYWH(graphBounds.right() + gap, graphBounds.top(), histogramWidth, graphHeight);

if (m_fontAtlas.get())
m_fontAtlas->setColor(DebugColors::FPSDisplayTextAndGraphColor());
const std::string valueText = base::StringPrintf("FPS:%5.1f", m_fpsGraph.value);
const std::string minMaxText = base::StringPrintf("%.0f-%.0f", m_fpsGraph.min, m_fpsGraph.max);

drawTextLeftAligned(canvas, &paint, textBounds, base::StringPrintf("FPS:%5.1f", m_fpsGraph.value));
drawTextRightAligned(canvas, &paint, textBounds, base::StringPrintf("%.0f-%.0f", m_fpsGraph.min, m_fpsGraph.max));
paint.setColor(DebugColors::FPSDisplayTextAndGraphColor());
drawText(canvas, &paint, valueText, SkPaint::kLeft_Align, fontHeight, textBounds.left(), textBounds.bottom());
drawText(canvas, &paint, minMaxText, SkPaint::kRight_Align, fontHeight, textBounds.right(), textBounds.bottom());

const double upperBound = Graph::updateUpperBound(&m_fpsGraph);
drawGraphLines(canvas, &paint, graphBounds, m_fpsGraph);
Expand Down Expand Up @@ -383,55 +387,56 @@ int HeadsUpDisplayLayerImpl::drawFPSDisplay(SkCanvas* canvas, FrameRateCounter*

int HeadsUpDisplayLayerImpl::drawMemoryDisplay(SkCanvas* canvas, MemoryHistory* memoryHistory, const int& initial_top)
{
MemoryHistory::Entry curEntry = memoryHistory->GetEntry(
memoryHistory->HistorySize() - 1);

// Don't draw the display if there is no data in it.
if (curEntry.bytes_total() == 0)
return initial_top;

// Move up by 2 to create no gap between us and previous counter.
int top = initial_top - 2;
const int top = initial_top - 2;
const int padding = 4;
const int fontHeight = m_fontAtlas.get() ? m_fontAtlas->fontHeight() : 0;
const int fontHeight = 11;

const int width = 181;
const int height = 2 * fontHeight + 3 * padding;
const int width = 187;
const int height = 3 * fontHeight + 4 * padding;

const int left = bounds().width() - width - 2;
const double megabyte = static_cast<double>(1024*1024);

SkPaint paint = createPaint();
drawGraphBackground(canvas, &paint, SkRect::MakeXYWH(left, top, width, height));

SkRect textRun1 = SkRect::MakeXYWH(left + padding, top + padding, width, fontHeight);
SkRect textRun2 = SkRect::MakeXYWH(left + padding, top + 2*padding + fontHeight, width, fontHeight);

if (m_fontAtlas.get())
m_fontAtlas->setColor(DebugColors::FPSDisplayTextAndGraphColor());

std::string text;
MemoryHistory::Entry curEntry = memoryHistory->GetEntry(
memoryHistory->HistorySize() - 1);
SkPoint titlePos = SkPoint::Make(left + padding, top + fontHeight);
SkPoint stat1Pos = SkPoint::Make(left + width - padding - 1, top + padding + 2 * fontHeight);
SkPoint stat2Pos = SkPoint::Make(left + width - padding - 1, top + 2 * padding + 3 * fontHeight);

double curMB = curEntry.bytes_total() / megabyte;
paint.setColor(SkColorSetRGB(220, 220, 220));
drawText(canvas, &paint, "GPU memory", SkPaint::kLeft_Align, fontHeight, titlePos);

text = base::StringPrintf(
"%6.1f MB GPU memory used",
std::string text = base::StringPrintf(
"%6.1f MB used",
(curEntry.bytes_unreleasable + curEntry.bytes_allocated) / megabyte);
drawTextLeftAligned(canvas, &paint, textRun1, text);
drawText(canvas, &paint, text, SkPaint::kRight_Align, fontHeight, stat1Pos);

if (curEntry.bytes_over) {
text = base::StringPrintf(
"%6.1f MB over",
(curEntry.bytes_over) / megabyte);
paint.setColor(SK_ColorRED);
text = base::StringPrintf("%6.1f MB over",
curEntry.bytes_over / megabyte);
} else {
text = base::StringPrintf(
"%6.1f MB maximum",
(curEntry.total_budget_in_bytes) / megabyte);
text = base::StringPrintf("%6.1f MB max ",
curEntry.total_budget_in_bytes / megabyte);
}
drawTextLeftAligned(canvas, &paint, textRun2, text);
drawText(canvas, &paint, text, SkPaint::kRight_Align, fontHeight, stat2Pos);

return top + height + 2;
}

int HeadsUpDisplayLayerImpl::drawPaintTimeDisplay(SkCanvas* canvas, PaintTimeCounter* paintTimeCounter, const int& top)
{
const int padding = 4;
const int fontHeight = m_fontAtlas.get() ? m_fontAtlas->fontHeight() : 0;
const int fontHeight = 15;

const int graphWidth = paintTimeCounter->HistorySize() * 2 - 1;
const int graphHeight = 40;
Expand All @@ -448,11 +453,13 @@ int HeadsUpDisplayLayerImpl::drawPaintTimeDisplay(SkCanvas* canvas, PaintTimeCou
SkRect textBounds2 = SkRect::MakeXYWH(left + padding, textBounds.bottom() + padding, graphWidth, fontHeight);
SkRect graphBounds = SkRect::MakeXYWH(left + padding, textBounds2.bottom() + 2 * padding, graphWidth, graphHeight);

if (m_fontAtlas.get())
m_fontAtlas->setColor(DebugColors::PaintTimeDisplayTextAndGraphColor());
drawTextLeftAligned(canvas, &paint, textBounds, "Page paint time (ms)");
drawTextLeftAligned(canvas, &paint, textBounds2, base::StringPrintf("%5.1f", m_paintTimeGraph.value));
drawTextRightAligned(canvas, &paint, textBounds2, base::StringPrintf("%.1f-%.1f", m_paintTimeGraph.min, m_paintTimeGraph.max));
const std::string valueText = base::StringPrintf("%.1f", m_paintTimeGraph.value);
const std::string minMaxText = base::StringPrintf("%.1f-%.1f", m_paintTimeGraph.min, m_paintTimeGraph.max);

paint.setColor(DebugColors::PaintTimeDisplayTextAndGraphColor());
drawText(canvas, &paint, "Page paint time (ms)", SkPaint::kLeft_Align, fontHeight, textBounds.left(), textBounds.bottom());
drawText(canvas, &paint, valueText, SkPaint::kLeft_Align, fontHeight, textBounds2.left(), textBounds2.bottom());
drawText(canvas, &paint, minMaxText, SkPaint::kRight_Align, fontHeight, textBounds2.right(), textBounds2.bottom());

const double upperBound = Graph::updateUpperBound(&m_paintTimeGraph);
drawGraphLines(canvas, &paint, graphBounds, m_paintTimeGraph);
Expand Down
9 changes: 6 additions & 3 deletions cc/heads_up_display_layer_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

class SkCanvas;
class SkPaint;
class SkTypeface;
struct SkRect;

namespace cc {
Expand Down Expand Up @@ -69,12 +70,12 @@ class CC_EXPORT HeadsUpDisplayLayerImpl : public LayerImpl {

void drawHudContents(SkCanvas*);

void drawTextLeftAligned(SkCanvas*, SkPaint*, const SkRect& bounds, const std::string& text);
void drawTextRightAligned(SkCanvas*, SkPaint*, const SkRect& bounds, const std::string& text);

void drawText(SkCanvas*, SkPaint*, const std::string&, const SkPaint::Align&, const int& size, const int& x, const int& y);
void drawText(SkCanvas*, SkPaint*, const std::string&, const SkPaint::Align&, const int& size, const SkPoint& pos);
void drawGraphBackground(SkCanvas*, SkPaint*, const SkRect& bounds);
void drawGraphLines(SkCanvas*, SkPaint*, const SkRect& bounds, const Graph&);

void drawPlaformLayerTree(SkCanvas*);
int drawFPSDisplay(SkCanvas*, FrameRateCounter*, const int& top);
int drawMemoryDisplay(SkCanvas*, MemoryHistory*, const int& top);
int drawPaintTimeDisplay(SkCanvas*, PaintTimeCounter*, const int& top);
Expand All @@ -85,6 +86,8 @@ class CC_EXPORT HeadsUpDisplayLayerImpl : public LayerImpl {
scoped_ptr<ScopedResource> m_hudTexture;
scoped_ptr<SkCanvas> m_hudCanvas;

skia::RefPtr<SkTypeface> m_typeface;

Graph m_fpsGraph;
Graph m_paintTimeGraph;

Expand Down
2 changes: 1 addition & 1 deletion cc/paint_time_counter.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class PaintTimeCounter {
private:
PaintTimeCounter();

RingBuffer<base::TimeDelta, 80> ring_buffer_;
RingBuffer<base::TimeDelta, 90> ring_buffer_;
base::TimeDelta last_total_paint_time_;

DISALLOW_COPY_AND_ASSIGN(PaintTimeCounter);
Expand Down

0 comments on commit fbf3a62

Please sign in to comment.