Changeset 67123 in webkit


Ignore:
Timestamp:
Sep 9, 2010 4:15:29 PM (14 years ago)
Author:
jamesr@google.com
Message:

2010-09-09 Vincent Scheib <scheib@chromium.org>

Reviewed by James Robinson.

[Chromium] Minimize uploads in canvas 2d mixed mode rendering
https://bugs.webkit.org/show_bug.cgi?id=45476

No new tests - change is for performance, logic fixes only apparent when running hardware acceleration.

  • Enumeration values fixed, "CavasWillDraw" -> "CanvasDidDraw".
  • markDirtyRect() plumbed through GraphicsContext to PlatformContextSkia.
  • Texture::updateSubRect() added to allow uploading only a dirty rect.
  • Logic fix in ImageBuffer::draw(), caused canvas to canvas copies to be incorrect.
  • html/canvas/CanvasRenderingContext2D.cpp: (WebCore::CanvasRenderingContext2D::setAllAttributesToDefault): (WebCore::CanvasRenderingContext2D::strokeRect): (WebCore::CanvasRenderingContext2D::drawImage): (WebCore::CanvasRenderingContext2D::didDraw):
    • Logic fix for drawingContext()->markDirtyRect() call.

(WebCore::CanvasRenderingContext2D::putImageData):
(WebCore::CanvasRenderingContext2D::drawTextInternal):

  • Logic fix for calls to "didDraw()", use peer method first.
  • html/canvas/CanvasRenderingContext2D.h:
  • platform/graphics/GraphicsContext.cpp: (WebCore::GraphicsContext::drawImageBuffer): (WebCore::GraphicsContext::markDirtyRect):
  • platform/graphics/GraphicsContext.h:
  • platform/graphics/gpu/Texture.cpp: (WebCore::Texture::create): (WebCore::Texture::load): (WebCore::Texture::updateSubRect):
  • platform/graphics/gpu/Texture.h:
  • platform/graphics/gpu/TilingData.h: (WebCore::TilingData::borderTexels):
  • platform/graphics/skia/GraphicsContextSkia.cpp: (WebCore::GraphicsContext::clipConvexPolygon): (WebCore::GraphicsContext::markDirtyRect):
  • platform/graphics/skia/ImageBufferSkia.cpp: (WebCore::ImageBuffer::draw):
  • platform/graphics/skia/PlatformContextSkia.cpp: (WebCore::PlatformContextSkia::State::cloneInheritedProperties): (WebCore::PlatformContextSkia::drawRect): (WebCore::PlatformContextSkia::setFillColor): (WebCore::PlatformContextSkia::setStrokeColor): (WebCore::PlatformContextSkia::markDirtyRect): (WebCore::PlatformContextSkia::uploadSoftwareToHardware):
  • platform/graphics/skia/PlatformContextSkia.h:
Location:
trunk/WebCore
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r67122 r67123  
     12010-09-09  Vincent Scheib  <scheib@chromium.org>
     2
     3        Reviewed by James Robinson.
     4
     5        [Chromium] Minimize uploads in canvas 2d mixed mode rendering
     6        https://bugs.webkit.org/show_bug.cgi?id=45476
     7
     8        No new tests - change is for performance, logic fixes only apparent when running hardware acceleration.
     9
     10        - Enumeration values fixed, "CavasWillDraw" -> "CanvasDidDraw".
     11        - markDirtyRect() plumbed through GraphicsContext to PlatformContextSkia.
     12        - Texture::updateSubRect() added to allow uploading only a dirty rect.
     13        - Logic fix in ImageBuffer::draw(), caused canvas to canvas copies to be incorrect.
     14
     15        * html/canvas/CanvasRenderingContext2D.cpp:
     16        (WebCore::CanvasRenderingContext2D::setAllAttributesToDefault):
     17        (WebCore::CanvasRenderingContext2D::strokeRect):
     18        (WebCore::CanvasRenderingContext2D::drawImage):
     19        (WebCore::CanvasRenderingContext2D::didDraw):
     20          - Logic fix for drawingContext()->markDirtyRect() call.
     21        (WebCore::CanvasRenderingContext2D::putImageData):
     22        (WebCore::CanvasRenderingContext2D::drawTextInternal):
     23          - Logic fix for calls to "didDraw()", use peer method first.
     24        * html/canvas/CanvasRenderingContext2D.h:
     25        * platform/graphics/GraphicsContext.cpp:
     26        (WebCore::GraphicsContext::drawImageBuffer):
     27        (WebCore::GraphicsContext::markDirtyRect):
     28        * platform/graphics/GraphicsContext.h:
     29        * platform/graphics/gpu/Texture.cpp:
     30        (WebCore::Texture::create):
     31        (WebCore::Texture::load):
     32        (WebCore::Texture::updateSubRect):
     33        * platform/graphics/gpu/Texture.h:
     34        * platform/graphics/gpu/TilingData.h:
     35        (WebCore::TilingData::borderTexels):
     36        * platform/graphics/skia/GraphicsContextSkia.cpp:
     37        (WebCore::GraphicsContext::clipConvexPolygon):
     38        (WebCore::GraphicsContext::markDirtyRect):
     39        * platform/graphics/skia/ImageBufferSkia.cpp:
     40        (WebCore::ImageBuffer::draw):
     41        * platform/graphics/skia/PlatformContextSkia.cpp:
     42        (WebCore::PlatformContextSkia::State::cloneInheritedProperties):
     43        (WebCore::PlatformContextSkia::drawRect):
     44        (WebCore::PlatformContextSkia::setFillColor):
     45        (WebCore::PlatformContextSkia::setStrokeColor):
     46        (WebCore::PlatformContextSkia::markDirtyRect):
     47        (WebCore::PlatformContextSkia::uploadSoftwareToHardware):
     48        * platform/graphics/skia/PlatformContextSkia.h:
     49
    1502010-09-08  Darin Adler  <darin@apple.com>
    251
  • trunk/WebCore/html/canvas/CanvasRenderingContext2D.cpp

    r66988 r67123  
    2626 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    2727 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
     28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2929 */
    3030
     
    220220}
    221221
    222 void CanvasRenderingContext2D::setAllAttributesToDefault() 
     222void CanvasRenderingContext2D::setAllAttributesToDefault()
    223223{
    224224    state().m_globalAlpha = 1;
     
    944944    if (!validateRectForCanvas(x, y, width, height))
    945945        return;
    946  
     946
    947947    if (!(lineWidth >= 0))
    948948        return;
     
    12771277    if (!state().m_invertibleCTM)
    12781278        return;
    1279  
     1279
    12801280    FloatRect sourceRect = c->roundToDevicePixels(srcRect);
    12811281    FloatRect destRect = c->roundToDevicePixels(dstRect);
     
    15111511
    15121512    FloatRect dirtyRect = r;
    1513     if (options & CanvasWillDrawApplyTransform) {
     1513    if (options & CanvasDidDrawApplyTransform) {
    15141514        AffineTransform ctm = state().m_transform;
    15151515        dirtyRect = ctm.mapRect(r);
    15161516    }
    15171517
    1518     if (options & CanvasWillDrawApplyShadow && alphaChannel(state().m_shadowColor)) {
     1518    if (options & CanvasDidDrawApplyShadow && alphaChannel(state().m_shadowColor)) {
    15191519        // The shadow gets applied after transformation
    15201520        FloatRect shadowRect(dirtyRect);
     
    15241524    }
    15251525
    1526     if (options & CanvasWillDrawApplyClip) {
     1526    if (options & CanvasDidDrawApplyClip) {
    15271527        // FIXME: apply the current clip to the rectangle. Unfortunately we can't get the clip
    15281528        // back out of the GraphicsContext, so to take clip into account for incremental painting,
     
    15301530    }
    15311531
     1532#if ENABLE(ACCELERATED_2D_CANVAS)
     1533    if (isAccelerated())
     1534        drawingContext()->markDirtyRect(enclosingIntRect(dirtyRect));
     1535#endif
    15321536#if ENABLE(ACCELERATED_2D_CANVAS) && USE(ACCELERATED_COMPOSITING)
    15331537    // If we are drawing to hardware and we have a composited layer, just call rendererContentChanged().
     
    16591663
    16601664    buffer->putUnmultipliedImageData(data, sourceRect, destPoint);
    1661     didDraw(sourceRect, 0); // ignore transform, shadow and clip
     1665    didDraw(sourceRect, CanvasDidDrawApplyNone); // ignore transform, shadow and clip
    16621666}
    16631667
     
    18791883
    18801884    if (fill)
    1881         canvas()->didDraw(textRect);
     1885        didDraw(textRect);
    18821886    else {
    18831887        // When stroking text, pointy miters can extend outside of textRect, so we
    18841888        // punt and dirty the whole canvas.
    1885         canvas()->didDraw(FloatRect(0, 0, canvas()->width(), canvas()->height()));
     1889        didDraw(FloatRect(0, 0, canvas()->width(), canvas()->height()));
    18861890    }
    18871891
  • trunk/WebCore/html/canvas/CanvasRenderingContext2D.h

    r66746 r67123  
    2121 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    2222 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
     23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2424 */
    2525
     
    265265    void applyShadow();
    266266
    267     enum CanvasWillDrawOption {
    268         CanvasWillDrawApplyTransform = 1,
    269         CanvasWillDrawApplyShadow = 1 << 1,
    270         CanvasWillDrawApplyClip = 1 << 2,
    271         CanvasWillDrawApplyAll = 0xffffffff
     267    enum CanvasDidDrawOption {
     268        CanvasDidDrawApplyNone = 0,
     269        CanvasDidDrawApplyTransform = 1,
     270        CanvasDidDrawApplyShadow = 1 << 1,
     271        CanvasDidDrawApplyClip = 1 << 2,
     272        CanvasDidDrawApplyAll = 0xffffffff
    272273    };
    273274
    274     void didDraw(const FloatRect&, unsigned options = CanvasWillDrawApplyAll);
     275    void didDraw(const FloatRect&, unsigned options = CanvasDidDrawApplyAll);
    275276
    276277    GraphicsContext* drawingContext() const;
  • trunk/WebCore/platform/graphics/GraphicsContext.cpp

    r66746 r67123  
    468468    if (paintingDisabled() || !image)
    469469        return;
    470        
     470
    471471    float tsw = src.width();
    472472    float tsh = src.height();
     
    490490
    491491    image->draw(this, styleColorSpace, dest, src, op, useLowQualityScale);
    492    
     492
    493493    if (useLowQualityScale)
    494494        restore();
     
    578578
    579579void GraphicsContext::syncSoftwareCanvas()
     580{
     581}
     582
     583void GraphicsContext::markDirtyRect(const IntRect&)
    580584{
    581585}
  • trunk/WebCore/platform/graphics/GraphicsContext.h

    r66746 r67123  
    2222 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    2323 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
     24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2525 */
    2626
     
    425425        void setSharedGraphicsContext3D(SharedGraphicsContext3D*, DrawingBuffer*, const IntSize&);
    426426        void syncSoftwareCanvas();
     427        void markDirtyRect(const IntRect&); // Hints that a portion of the backing store is dirty.
    427428
    428429    private:
  • trunk/WebCore/platform/graphics/gpu/Texture.cpp

    r66746 r67123  
    3333#include "Texture.h"
    3434
     35#include "FloatRect.h"
    3536#include "GraphicsContext3D.h"
    3637#include "IntRect.h"
    3738
     39#include <algorithm>
    3840#include <wtf/OwnArrayPtr.h>
     41
     42using namespace std;
    3943
    4044namespace WebCore {
     
    8387    int maxTextureSize = 0;
    8488    context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &maxTextureSize);
    85 
    8689    TilingData tiling(maxTextureSize, width, height, true);
    8790    int numTiles = tiling.numTiles();
     
    138141void Texture::load(void* pixels)
    139142{
     143    updateSubRect(pixels, IntRect(0, 0, m_tiles.totalSizeX(), m_tiles.totalSizeY()));
     144}
     145
     146void Texture::updateSubRect(void* pixels, const IntRect updateRect)
     147{
    140148    uint32_t* pixels32 = static_cast<uint32_t*>(pixels);
    141149    unsigned int glFormat = 0;
     
    147155        // FIXME:  This could use PBO's to save doing an extra copy here.
    148156    }
    149     OwnArrayPtr<uint32_t> tempBuff(new uint32_t[m_tiles.maxTextureSize() * m_tiles.maxTextureSize()]);
    150 
    151     for (int i = 0; i < m_tiles.numTiles(); i++) {
    152         IntRect tileBoundsWithBorder = m_tiles.tileBoundsWithBorder(i);
    153 
     157    int tempBuffSize = // Temporary buffer size is the smaller of the max texture size or the updateRect
     158        min(m_tiles.maxTextureSize(), m_tiles.borderTexels() + updateRect.width()) *
     159        min(m_tiles.maxTextureSize(), m_tiles.borderTexels() + updateRect.height());
     160    OwnArrayPtr<uint32_t> tempBuff(new uint32_t[tempBuffSize]);
     161
     162    for (int tile = 0; tile < m_tiles.numTiles(); tile++) {
     163        // Intersect with tile
     164        IntRect tileBoundsWithBorder = m_tiles.tileBoundsWithBorder(tile);
     165
     166        IntRect updateRectIntersected = updateRect;
     167        updateRectIntersected.intersect(tileBoundsWithBorder);
     168
     169        IntRect dstRect = updateRectIntersected;
     170        dstRect.move(-tileBoundsWithBorder.x(), -tileBoundsWithBorder.y());
     171
     172        if (updateRectIntersected.isEmpty())
     173            continue;
     174
     175        // Copy sub rectangle out of larger pixel data
    154176        uint32_t* uploadBuff = 0;
    155177        if (swizzle) {
    156178            uploadBuff = copySubRect<true>(
    157             pixels32, tileBoundsWithBorder.x(), tileBoundsWithBorder.y(),
    158             tempBuff.get(), tileBoundsWithBorder.width(), tileBoundsWithBorder.height(), m_tiles.totalSizeX());
     179            pixels32, updateRectIntersected.x(), updateRectIntersected.y(),
     180            tempBuff.get(), updateRectIntersected.width(), updateRectIntersected.height(), m_tiles.totalSizeX());
    159181        } else {
    160182            uploadBuff = copySubRect<false>(
    161             pixels32, tileBoundsWithBorder.x(), tileBoundsWithBorder.y(),
    162             tempBuff.get(), tileBoundsWithBorder.width(), tileBoundsWithBorder.height(), m_tiles.totalSizeX());
    163         }
    164 
    165         m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_tileTextureIds->at(i));
    166         m_context->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, 0, 0,
    167             tileBoundsWithBorder.width(),
    168             tileBoundsWithBorder.height(), glFormat, glType, uploadBuff);
     183            pixels32, updateRectIntersected.x(), updateRectIntersected.y(),
     184            tempBuff.get(), updateRectIntersected.width(), updateRectIntersected.height(), m_tiles.totalSizeX());
     185        }
     186
     187        m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_tileTextureIds->at(tile));
     188        m_context->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0 /* level */,
     189            dstRect.x(),
     190            dstRect.y(),
     191            updateRectIntersected.width(),
     192            updateRectIntersected.height(), glFormat, glType, uploadBuff);
    169193    }
    170194}
  • trunk/WebCore/platform/graphics/gpu/Texture.h

    r66248 r67123  
    4242class GraphicsContext3D;
    4343
     44class IntRect;
     45
    4446class Texture : public RefCounted<Texture> {
    4547public:
     
    4951    void bindTile(int tile);
    5052    void load(void* pixels);
     53    void updateSubRect(void* pixels, const IntRect);
    5154    Format format() const { return m_format; }
    5255    const TilingData& tiles() const { return m_tiles; }
  • trunk/WebCore/platform/graphics/gpu/TilingData.h

    r66248 r67123  
    4545    int totalSizeX() const { return m_totalSizeX; }
    4646    int totalSizeY() const { return m_totalSizeY; }
     47    int borderTexels() const { return m_borderTexels; }
    4748
    4849    int numTiles() const { return numTilesX() * numTilesY(); }
  • trunk/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp

    r67039 r67123  
    11/*
    22 * Copyright (c) 2006, Google Inc. All rights reserved.
    3  * 
     3 *
    44 * Redistribution and use in source and binary forms, with or without
    55 * modification, are permitted provided that the following conditions are
    66 * met:
    7  * 
     7 *
    88 *     * Redistributions of source code must retain the above copyright
    99 * notice, this list of conditions and the following disclaimer.
     
    1515 * contributors may be used to endorse or promote products derived from
    1616 * this software without specific prior written permission.
    17  * 
     17 *
    1818 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    1919 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     
    6666{
    6767    int sign = SkExtractSign(value);
    68    
     68
    6969    value = SkApplySign(value, sign);
    7070    if (value >= max)
     
    500500    if (numPoints <= 1)
    501501        return;
    502    
     502
    503503    // FIXME: IMPLEMENT!!
    504504}
     
    12511251}
    12521252
     1253void GraphicsContext::markDirtyRect(const IntRect& rect)
     1254{
     1255    platformContext()->markDirtyRect(rect);
     1256}
     1257
    12531258}  // namespace WebCore
  • trunk/WebCore/platform/graphics/skia/ImageBufferSkia.cpp

    r67003 r67123  
    118118            destRectFlipped.setY(destRect.y() + destRect.height());
    119119            destRectFlipped.setHeight(-destRect.height());
     120            context->platformContext()->prepareForHardwareDraw();
    120121            context->platformContext()->gpuCanvas()->drawTexturedRect(sourceTexture, m_size, srcRect, destRectFlipped, styleColorSpace, op);
    121122            return;
  • trunk/WebCore/platform/graphics/skia/PlatformContextSkia.cpp

    r67003 r67123  
    11/*
    22 * Copyright (c) 2008, Google Inc. All rights reserved.
    3  * 
     3 *
    44 * Redistribution and use in source and binary forms, with or without
    55 * modification, are permitted provided that the following conditions are
    66 * met:
    7  * 
     7 *
    88 *     * Redistributions of source code must retain the above copyright
    99 * notice, this list of conditions and the following disclaimer.
     
    1515 * contributors may be used to endorse or promote products derived from
    1616 * this software without specific prior written permission.
    17  * 
     17 *
    1818 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    1919 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     
    188188
    189189    // Everything is inherited except for the clip paths.
    190     state.m_antiAliasClipPaths.clear(); 
     190    state.m_antiAliasClipPaths.clear();
    191191
    192192    return state;
     
    340340        SkColor oldFillColor = m_state->m_fillColor;
    341341
    342         // setFillColor() will set the shader to NULL, so save a ref to it now. 
     342        // setFillColor() will set the shader to NULL, so save a ref to it now.
    343343        SkShader* oldFillShader = m_state->m_fillShader;
    344344        oldFillShader->safeRef();
     
    465465{
    466466    m_state->m_fillColor = color;
    467     setFillShader(NULL);
     467    setFillShader(0);
    468468}
    469469
     
    486486{
    487487    m_state->m_strokeColor = strokeColor;
    488     setStrokeShader(NULL);
     488    setStrokeShader(0);
    489489}
    490490
     
    803803}
    804804
     805void PlatformContextSkia::markDirtyRect(const IntRect& rect)
     806{
     807    if (!m_useGPU)
     808        return;
     809
     810    switch (m_backingStoreState) {
     811    case Software:
     812    case Mixed:
     813        m_softwareDirtyRect.unite(rect);
     814        return;
     815    case Hardware:
     816        return;
     817    default:
     818        ASSERT_NOT_REACHED();
     819    }
     820}
     821
    805822void PlatformContextSkia::uploadSoftwareToHardware(CompositeOperator op) const
    806823{
     
    810827    if (!m_uploadTexture || m_uploadTexture->tiles().totalSizeX() < bitmap.width() || m_uploadTexture->tiles().totalSizeY() < bitmap.height())
    811828        m_uploadTexture = context->createTexture(Texture::BGRA8, bitmap.width(), bitmap.height());
    812     m_uploadTexture->load(bitmap.getPixels());
    813     IntRect rect(0, 0, bitmap.width(), bitmap.height());
     829
     830    m_uploadTexture->updateSubRect(bitmap.getPixels(), m_softwareDirtyRect);
    814831    AffineTransform identity;
    815     gpuCanvas()->drawTexturedRect(m_uploadTexture.get(), rect, rect, identity, 1.0, DeviceColorSpace, op);
     832    gpuCanvas()->drawTexturedRect(m_uploadTexture.get(), m_softwareDirtyRect, m_softwareDirtyRect, identity, 1.0, DeviceColorSpace, op);
     833    m_softwareDirtyRect.setWidth(0); // Clear dirty rect.
    816834}
    817835
  • trunk/WebCore/platform/graphics/skia/PlatformContextSkia.h

    r67003 r67123  
    11/*
    22 * Copyright (c) 2008, Google Inc. All rights reserved.
    3  * 
     3 *
    44 * Redistribution and use in source and binary forms, with or without
    55 * modification, are permitted provided that the following conditions are
    66 * met:
    7  * 
     7 *
    88 *     * Redistributions of source code must retain the above copyright
    99 * notice, this list of conditions and the following disclaimer.
     
    1515 * contributors may be used to endorse or promote products derived from
    1616 * this software without specific prior written permission.
    17  * 
     17 *
    1818 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    1919 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     
    195195    // Call to force the skia::PlatformCanvas to contain all rendering results.
    196196    void syncSoftwareCanvas() const;
     197    void markDirtyRect(const IntRect& rect);
    197198
    198199private:
     
    223224    SkPath m_path;
    224225
    225     // Stores image sizes for a hint to compute image resampling modes. 
     226    // Stores image sizes for a hint to compute image resampling modes.
    226227    // Values are used in ImageSkia.cpp
    227228    IntSize m_imageResamplingHintSrcSize;
     
    234235    mutable enum { None, Software, Mixed, Hardware } m_backingStoreState;
    235236    mutable RefPtr<Texture> m_uploadTexture;
     237    mutable IntRect m_softwareDirtyRect;
    236238};
    237239
Note: See TracChangeset for help on using the changeset viewer.