Changeset 64161 in webkit


Ignore:
Timestamp:
Jul 27, 2010 2:37:41 PM (14 years ago)
Author:
jamesr@google.com
Message:

2010-07-27 James Robinson <jamesr@chromium.org>

Reviewed by Darin Fisher.

[chromium] Let PlatformContextSkia draw to a GLES2Canvas in addition to an SkCanvas
https://bugs.webkit.org/show_bug.cgi?id=43070

This adds a GLES2Canvas as drawing surface to PlatformContextSkia and lets callers
issue draw commands to either. The PlatformContextSkia keeps track of where
rendering results are being accumulated and can blend the hardware and software
backing stores into each other when necessary.

Still just plumbing, no functionality change.

  • platform/graphics/chromium/GLES2Canvas.cpp: (WebCore::GLES2Canvas::GLES2Canvas):
  • platform/graphics/chromium/GLES2Canvas.h:
  • platform/graphics/skia/PlatformContextSkia.cpp: (PlatformContextSkia::PlatformContextSkia): (PlatformContextSkia::setGLES2Context): (PlatformContextSkia::preSoftwareDraw): (PlatformContextSkia::preHardwareDraw): (PlatformContextSkia::forceToSoftware): (PlatformContextSkia::uploadSoftwareToHardware): (PlatformContextSkia::readbackHardwareToSoftware):
  • platform/graphics/skia/PlatformContextSkia.h: (PlatformContextSkia::useGPU): (PlatformContextSkia::gpuCanvas): (PlatformContextSkia::preSoftwareDraw): (PlatformContextSkia::preHardwareDraw): (PlatformContextSkia::forceToSoftware): (PlatformContextSkia::):
Location:
trunk/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r64158 r64161  
     12010-07-27  James Robinson  <jamesr@chromium.org>
     2
     3        Reviewed by Darin Fisher.
     4
     5        [chromium] Let PlatformContextSkia draw to a GLES2Canvas in addition to an SkCanvas
     6        https://bugs.webkit.org/show_bug.cgi?id=43070
     7
     8        This adds a GLES2Canvas as drawing surface to PlatformContextSkia and lets callers
     9        issue draw commands to either.  The PlatformContextSkia keeps track of where
     10        rendering results are being accumulated and can blend the hardware and software
     11        backing stores into each other when necessary.
     12
     13        Still just plumbing, no functionality change.
     14
     15        * platform/graphics/chromium/GLES2Canvas.cpp:
     16        (WebCore::GLES2Canvas::GLES2Canvas):
     17        * platform/graphics/chromium/GLES2Canvas.h:
     18        * platform/graphics/skia/PlatformContextSkia.cpp:
     19        (PlatformContextSkia::PlatformContextSkia):
     20        (PlatformContextSkia::setGLES2Context):
     21        (PlatformContextSkia::preSoftwareDraw):
     22        (PlatformContextSkia::preHardwareDraw):
     23        (PlatformContextSkia::forceToSoftware):
     24        (PlatformContextSkia::uploadSoftwareToHardware):
     25        (PlatformContextSkia::readbackHardwareToSoftware):
     26        * platform/graphics/skia/PlatformContextSkia.h:
     27        (PlatformContextSkia::useGPU):
     28        (PlatformContextSkia::gpuCanvas):
     29        (PlatformContextSkia::preSoftwareDraw):
     30        (PlatformContextSkia::preHardwareDraw):
     31        (PlatformContextSkia::forceToSoftware):
     32        (PlatformContextSkia::):
     33
    1342010-07-27  Simon Fraser  <simon.fraser@apple.com>
    235
  • trunk/WebCore/platform/graphics/chromium/GLES2Canvas.cpp

    r64046 r64161  
    7474};
    7575
    76 GLES2Canvas::GLES2Canvas(GLES2Context* context, int width, int height)
     76GLES2Canvas::GLES2Canvas(GLES2Context* context, const IntSize& size)
    7777    : m_gles2Context(context)
    7878    , m_quadVertices(0)
     
    8888    , m_texAlphaLocation(-1)
    8989    , m_texPositionLocation(-1)
    90     , m_width(width)
    91     , m_height(height)
    9290    , m_state(0)
    9391{
    9492    m_flipMatrix.translate(-1.0f, 1.0f);
    95     m_flipMatrix.scale(2.0f / width, -2.0f / height);
     93    m_flipMatrix.scale(2.0f / size.width(), -2.0f / size.height());
    9694
    9795    m_gles2Context->makeCurrent();
    98     m_gles2Context->resizeOffscreenContent(IntSize(width, height));
     96    m_gles2Context->resizeOffscreenContent(size);
    9997    m_gles2Context->swapBuffers();
    100     glViewport(0, 0, width, height);
     98    glViewport(0, 0, size.width(), size.height());
    10199
    102100    m_stateStack.append(State());
  • trunk/WebCore/platform/graphics/chromium/GLES2Canvas.h

    r64046 r64161  
    5454class GLES2Canvas : public Noncopyable {
    5555public:
    56     GLES2Canvas(GLES2Context* context, int width, int height);
     56    GLES2Canvas(GLES2Context*, const IntSize&);
    5757    ~GLES2Canvas();
    5858
     
    104104    int m_texAlphaLocation;
    105105    int m_texPositionLocation;
    106     int m_width;
    107     int m_height;
    108106    AffineTransform m_flipMatrix;
    109107    TextureHashMap m_textures;
  • trunk/WebCore/platform/graphics/skia/PlatformContextSkia.cpp

    r61037 r64161  
    4545#include "SkDashPathEffect.h"
    4646
     47#if USE(GLES2_RENDERING)
     48#include "GLES2Canvas.h"
     49#include "GLES2Context.h"
     50#include "GLES2Texture.h"
     51#include <GLES2/gl2.h>
     52#endif
     53
    4754#include <wtf/MathExtras.h>
     55#include <wtf/OwnArrayPtr.h>
    4856#include <wtf/Vector.h>
    4957
     
    199207#if OS(WINDOWS)
    200208    , m_drawingToImageBuffer(false)
     209#endif
     210#if USE(GLES2_RENDERING)
     211    , m_useGPU(false)
     212    , m_gpuCanvas(0)
     213    , m_backingStoreState(None)
    201214#endif
    202215{
     
    662675    m_canvas->restore();
    663676}
     677
     678#if USE(GLES2_RENDERING)
     679void PlatformContextSkia::setGLES2Context(WebCore::GLES2Context* context, const WebCore::IntSize& size)
     680{
     681    m_useGPU = true;
     682    m_gpuCanvas = new WebCore::GLES2Canvas(context, size);
     683}
     684
     685void PlatformContextSkia::preSoftwareDraw() const
     686{
     687    if (!m_useGPU)
     688        return;
     689
     690    if (m_backingStoreState == Hardware) {
     691        // Depending on the blend mode we need to do one of a few things:
     692
     693        // * For associative blend modes, we can draw into an initially empty
     694        // canvas and then composite the results on top of the hardware drawn
     695        // results before the next hardware draw or swapBuffers().
     696
     697        // * For non-associative blend modes we have to do a readback and then
     698        // software draw.  When we re-upload in this mode we have to blow
     699        // away whatever is in the hardware backing store (do a copy instead
     700        // of a compositing operation).
     701
     702        if (m_state->m_xferMode == SkXfermode::kSrcOver_Mode) {
     703            // Last drawn on hardware; clear out the canvas.
     704            m_canvas->save();
     705            SkRect bounds = {0, 0, m_canvas->getDevice()->width(), m_canvas->getDevice()->height()};
     706            m_canvas->clipRect(bounds, SkRegion::kReplace_Op);
     707            m_canvas->drawARGB(0, 0, 0, 0, SkXfermode::kClear_Mode);
     708            m_canvas->restore();
     709            // Start compositing into the empty canvas.
     710            m_backingStoreState = Mixed;
     711        } else {
     712            readbackHardwareToSoftware();
     713            // When we switch back to hardware copy the results, don't composite.
     714            m_backingStoreState = Software;
     715        }
     716    } else if (m_backingStoreState == Mixed) {
     717        if (m_state->m_xferMode != SkXfermode::kSrcOver_Mode) {
     718            // Have to composite our currently software drawn data...
     719            uploadSoftwareToHardware(WebCore::CompositeSourceOver);
     720            // then do a readback so we can hardware draw stuff.
     721            readbackHardwareToSoftware();
     722            m_backingStoreState = Software;
     723        }
     724    }
     725}
     726
     727void PlatformContextSkia::preHardwareDraw() const
     728{
     729    if (!m_useGPU)
     730        return;
     731
     732    if (m_backingStoreState == Software) {
     733        // Last drawn in software; upload everything we've drawn.
     734        uploadSoftwareToHardware(WebCore::CompositeCopy);
     735    } else if (m_backingStoreState == Mixed) {
     736        // Stuff in software/hardware, composite the software stuff on top of
     737        // the hardware stuff.
     738        uploadSoftwareToHardware(WebCore::CompositeSourceOver);
     739    }
     740    m_backingStoreState = Hardware;
     741}
     742
     743void PlatformContextSkia::syncSoftwareCanvas() const
     744{
     745    if (!m_useGPU)
     746        return;
     747
     748    if (m_backingStoreState == Hardware)
     749        readbackHardwareToSoftware();
     750    else if (m_backingStoreState == Mixed) {
     751        // Have to composite our currently software drawn data..
     752        uploadSoftwareToHardware(WebCore::CompositeSourceOver);
     753        // then do a readback.
     754        readbackHardwareToSoftware();
     755        m_backingStoreState = Software;
     756    }
     757    m_backingStoreState = Software;
     758}
     759
     760void PlatformContextSkia::uploadSoftwareToHardware(WebCore::CompositeOperator op) const
     761{
     762    const SkBitmap& bitmap = m_canvas->getDevice()->accessBitmap(false);
     763    SkAutoLockPixels lock(bitmap);
     764    m_gpuCanvas->gles2Context()->makeCurrent();
     765    // FIXME: Keep a texture around for this rather than constantly creating/destroying one.
     766    RefPtr<WebCore::GLES2Texture> texture = WebCore::GLES2Texture::create(WebCore::GLES2Texture::BGRA8, bitmap.width(), bitmap.height());
     767    texture->load(bitmap.getPixels());
     768    WebCore::IntRect rect(0, 0, bitmap.width(), bitmap.height());
     769    gpuCanvas()->drawTexturedRect(texture.get(), rect, rect, WebCore::DeviceColorSpace, op);
     770}
     771
     772void PlatformContextSkia::readbackHardwareToSoftware() const
     773{
     774    const SkBitmap& bitmap = m_canvas->getDevice()->accessBitmap(true);
     775    SkAutoLockPixels lock(bitmap);
     776    m_gpuCanvas->gles2Context()->makeCurrent();
     777    int width = bitmap.width(), height = bitmap.height();
     778    OwnArrayPtr<uint32_t> buf(new uint32_t[width]);
     779    // Flips the image vertically.
     780    for (int y = 0; y < height; ++y) {
     781        uint32_t* pixels = bitmap.getAddr32(0, y);
     782        glReadPixels(0, height - 1 - y, width, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
     783        for (int i = 0; i < width; ++i) {
     784            uint32_t pixel = pixels[i];
     785            // Swizzles from RGBA -> BGRA.
     786            pixels[i] = pixel & 0xFF00FF00 | ((pixel & 0x00FF0000) >> 16) | ((pixel & 0x000000FF) << 16);
     787        }
     788    }
     789}
     790#endif
  • trunk/WebCore/platform/graphics/skia/PlatformContextSkia.h

    r60658 r64161  
    4242#include "SkPath.h"
    4343
     44#if USE(GLES2_RENDERING)
     45namespace WebCore {
     46enum CompositeOperator;
     47class GLES2Canvas;
     48class GLES2Context;
     49}
     50#endif
     51
    4452#include <wtf/Vector.h>
    4553
     
    175183    void clearImageResamplingHint();
    176184    bool hasImageResamplingHint() const;
     185#if USE(GLES2_RENDERING)
     186    bool useGPU() { return m_useGPU; }
     187    void setGLES2Context(WebCore::GLES2Context*, const WebCore::IntSize&);
     188    WebCore::GLES2Canvas* gpuCanvas() const { return m_gpuCanvas.get(); }
     189#endif
     190
     191#if USE(GLES2_RENDERING)
     192    // Call these before making a call that manipulates the underlying
     193    // skia::PlatformCanvas or WebCore::GLES2Canvas
     194    void preSoftwareDraw() const;
     195    void preHardwareDraw() const;
     196    // Call to force the skia::PlatformCanvas to contain all rendering results.
     197    void syncSoftwareCanvas() const;
     198#else
     199    void preSoftwareDraw() const {}
     200    void preHardwareDraw() const {}
     201    void syncSoftwareCanvas() const {}
     202#endif
    177203
    178204private:
     
    183209#endif
    184210    void applyAntiAliasedClipPaths(WTF::Vector<SkPath>& paths);
     211
     212#if USE(GLES2_RENDERING)
     213    void uploadSoftwareToHardware(WebCore::CompositeOperator) const;
     214    void readbackHardwareToSoftware() const;
     215#endif
    185216
    186217    // Defines drawing style.
     
    207238    bool m_drawingToImageBuffer;
    208239#endif
     240#if USE(GLES2_RENDERING)
     241    bool m_useGPU;
     242    OwnPtr<WebCore::GLES2Canvas> m_gpuCanvas;
     243    mutable enum { None, Software, Mixed, Hardware } m_backingStoreState;
     244#endif
    209245};
    210246
    211 #endif  // PlatformContextSkia_h
     247#endif // PlatformContextSkia_h
Note: See TracChangeset for help on using the changeset viewer.