181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch/*
281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * Copyright (C) 2011 Google Inc. All rights reserved.
381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch *
481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * Redistribution and use in source and binary forms, with or without
581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * modification, are permitted provided that the following conditions
681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * are met:
781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * 1.  Redistributions of source code must retain the above copyright
881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch *     notice, this list of conditions and the following disclaimer.
981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * 2.  Redistributions in binary form must reproduce the above copyright
1081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch *     notice, this list of conditions and the following disclaimer in the
1181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch *     documentation and/or other materials provided with the distribution.
1281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch *
1381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
1481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
1781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
2081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch */
2481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
2581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "config.h"
2681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
2781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#if USE(ACCELERATED_COMPOSITING)
2881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "CCHeadsUpDisplay.h"
2981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
3081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "CurrentTime.h"
3181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "Font.h"
3281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "FontDescription.h"
3381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "GraphicsContext3D.h"
3481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "LayerChromium.h"
3554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block#include "LayerRendererChromium.h"
3681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "LayerTexture.h"
3781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "TextRun.h"
3881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "TextStream.h"
3981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "TextureManager.h"
4081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include <wtf/text/CString.h>
4181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include <wtf/text/WTFString.h>
4281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
4381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochnamespace WebCore {
4481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
4581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochusing namespace std;
4681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
4781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen MurdochCCHeadsUpDisplay::CCHeadsUpDisplay(LayerRendererChromium* owner)
482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    : m_currentFrameNumber(1)
492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    , m_filteredFrameTime(0)
5081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    , m_layerRenderer(owner)
5181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    , m_showFPSCounter(false)
5281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    , m_showPlatformLayerTree(false)
5381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
5481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_presentTimeHistoryInSec[0] = currentTime();
5581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_presentTimeHistoryInSec[1] = m_presentTimeHistoryInSec[0];
562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    for (int i = 2; i < kPresentHistorySize; i++)
572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        m_presentTimeHistoryInSec[i] = 0;
582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    FontDescription mediumFontDesc;
602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    mediumFontDesc.setGenericFamily(FontDescription::MonospaceFamily);
612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    mediumFontDesc.setComputedSize(20);
622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    m_mediumFont = adoptPtr(new Font(mediumFontDesc, 0, 0));
642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    m_mediumFont->update(0);
652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    FontDescription smallFontDesc;
672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    smallFontDesc.setGenericFamily(FontDescription::MonospaceFamily);
682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    smallFontDesc.setComputedSize(10);
692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    m_smallFont = adoptPtr(new Font(smallFontDesc, 0, 0));
712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    m_smallFont->update(0);
7281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
7381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
7481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen MurdochCCHeadsUpDisplay::~CCHeadsUpDisplay()
7581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
7681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
7781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
7881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid CCHeadsUpDisplay::draw()
7981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
8081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    GraphicsContext3D* context = m_layerRenderer->context();
8181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (!m_hudTexture)
8281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_hudTexture = LayerTexture::create(context, m_layerRenderer->textureManager());
8381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
8481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // Use a fullscreen texture only if we need to...
8581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    IntSize hudSize;
8681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (m_showPlatformLayerTree) {
872bde8e466a4451c7319e3a072d118917957d6554Steve Block        hudSize.setWidth(min(2048, m_layerRenderer->viewportSize().width()));
882bde8e466a4451c7319e3a072d118917957d6554Steve Block        hudSize.setHeight(min(2048, m_layerRenderer->viewportSize().height()));
8981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    } else {
9081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        hudSize.setWidth(512);
9181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        hudSize.setHeight(128);
9281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
9381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
9481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_hudTexture->reserve(hudSize, GraphicsContext3D::RGBA);
9581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
9681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // Render pixels into the texture.
9781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    PlatformCanvas canvas;
9881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    canvas.resize(hudSize);
9981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    {
1002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        PlatformCanvas::Painter painter(&canvas, PlatformCanvas::Painter::GrayscaleText);
10181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        drawHudContents(painter.context(), hudSize);
10281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
10381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
10481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // Upload to GL.
10581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    {
10681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        PlatformCanvas::AutoLocker locker(&canvas);
10781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
10881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_hudTexture->bindTexture();
10981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        GLC(context.get(), context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, canvas.size().width(), canvas.size().height(), 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, locker.pixels()));
11081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
11181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
11281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // Draw the HUD onto the default render surface.
11354cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    const Program* program = m_layerRenderer->headsUpDisplayProgram();
11481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ASSERT(program && program->initialized());
11581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
11681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_hudTexture->bindTexture();
11781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_layerRenderer->useShader(program->program());
11881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0));
11981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
12081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    TransformationMatrix matrix;
12181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    matrix.translate3d(hudSize.width() * 0.5, hudSize.height() * 0.5, 0);
12281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    LayerChromium::drawTexturedQuad(context, m_layerRenderer->projectionMatrix(),
12381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                                    matrix, hudSize.width(), hudSize.height(),
12481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                                    1.0f, program->vertexShader().matrixLocation(),
12581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                                    program->fragmentShader().alphaLocation());
12681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
12781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
12881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid CCHeadsUpDisplay::drawHudContents(GraphicsContext* ctx, const IntSize& hudSize)
12981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
13081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (m_showPlatformLayerTree) {
13181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        ctx->setFillColor(Color(0, 0, 0, 192), ColorSpaceDeviceRGB);
13281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        ctx->fillRect(FloatRect(0, 0, hudSize.width(), hudSize.height()));
13381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
13481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
1352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    int fpsCounterHeight = m_mediumFont->fontMetrics().floatHeight() + 2;
1362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    int fpsCounterTop = 2;
1372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    int platformLayerTreeTop;
1382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (m_showFPSCounter)
1392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        platformLayerTreeTop = fpsCounterTop + fpsCounterHeight + 2;
1402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    else
1412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        platformLayerTreeTop = 0;
1422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (m_showFPSCounter)
1442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        drawFPSCounter(ctx, fpsCounterTop, fpsCounterHeight);
1452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (m_showPlatformLayerTree)
1472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        drawPlatformLayerTree(ctx, platformLayerTreeTop);
1482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}
1492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochvoid CCHeadsUpDisplay::drawFPSCounter(GraphicsContext* ctx, int top, int height)
1512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{
1522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // Note that since we haven't finished the current frame, the FPS counter
1532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // actually reports the last frame's time.
1542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    double secForLastFrame = m_presentTimeHistoryInSec[(m_currentFrameNumber + kPresentHistorySize - 1) % kPresentHistorySize] -
1552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                             m_presentTimeHistoryInSec[(m_currentFrameNumber + kPresentHistorySize - 2) % kPresentHistorySize];
1562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // Filter the frame times to avoid spikes.
1582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    const float alpha = 0.1;
1592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (!m_filteredFrameTime) {
1602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (m_currentFrameNumber == 2)
1612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            m_filteredFrameTime = secForLastFrame;
1622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    } else
1632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        m_filteredFrameTime = ((1.0 - alpha) * m_filteredFrameTime) + (alpha * secForLastFrame);
1642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // Create & measure FPS text.
1662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    String text(String::format("FPS: %5.1f", 1.0 / m_filteredFrameTime));
1672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    TextRun run(text);
1682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    float textWidth = m_mediumFont->width(run) + 2.0f;
1692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    float graphWidth = kPresentHistorySize;
1702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // Draw background.
1722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    ctx->setFillColor(Color(0, 0, 0, 255), ColorSpaceDeviceRGB);
1732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    ctx->fillRect(FloatRect(2, top, textWidth + graphWidth, height));
1742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // Draw FPS text.
1762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (m_filteredFrameTime) {
17781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        ctx->setFillColor(Color(255, 0, 0), ColorSpaceDeviceRGB);
1782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        ctx->drawText(*m_mediumFont, run, IntPoint(3, top + height - 6));
17981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
18081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
1812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // Draw FPS graph.
1822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    const double loFPS = 0.0;
1832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    const double hiFPS = 120.0;
1842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    ctx->setStrokeStyle(SolidStroke);
1852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    ctx->setStrokeColor(Color(255, 0, 0), ColorSpaceDeviceRGB);
1862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    int graphLeft = static_cast<int>(textWidth + 3);
1872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    IntPoint prev(-1, 0);
1882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    int x = 0;
1892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    double h = static_cast<double>(height - 2);
1902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    for (int i = m_currentFrameNumber % kPresentHistorySize; i != (m_currentFrameNumber - 1) % kPresentHistorySize; i = (i + 1) % kPresentHistorySize) {
1912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        int j = (i + 1) % kPresentHistorySize;
1922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        double fps = 1.0 / (m_presentTimeHistoryInSec[j] - m_presentTimeHistoryInSec[i]);
1932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        double p = 1 - ((fps - loFPS) / (hiFPS - loFPS));
1942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (p < 0)
1952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            p = 0;
1962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (p > 1)
1972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            p = 1;
1982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        IntPoint cur(graphLeft + x, 1 + top + p*h);
1992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (prev.x() != -1)
2002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            ctx->drawLine(prev, cur);
2012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        prev = cur;
2022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        x += 1;
2032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
2042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}
2052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
2062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochvoid CCHeadsUpDisplay::drawPlatformLayerTree(GraphicsContext* ctx, int top)
2072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{
2082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    float smallFontHeight = m_smallFont->fontMetrics().floatHeight();
2092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    int y = top + smallFontHeight - 4;
2102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    ctx->setFillColor(Color(255, 0, 0), ColorSpaceDeviceRGB);
2112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    Vector<String> lines;
2122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    m_layerRenderer->layerTreeAsText().split('\n', lines);
2132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    for (size_t i = 0; i < lines.size(); ++i) {
2142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        ctx->drawText(*m_smallFont, TextRun(lines[i]), IntPoint(2, y));
2152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        y += smallFontHeight;
21681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
21781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
21881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
21981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid CCHeadsUpDisplay::onPresent()
22081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
2212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    m_presentTimeHistoryInSec[m_currentFrameNumber % kPresentHistorySize] = currentTime();
22281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_currentFrameNumber += 1;
22381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
22481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
22581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
22681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
22781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#endif // USE(ACCELERATED_COMPOSITING)
228