[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

jamesr at google.com jamesr at google.com
Wed Dec 22 11:30:54 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit fc50eb4e442d72a4894bd3e820b594b64cce80fd
Author: jamesr at google.com <jamesr at google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Tue Jul 27 21:37:41 2010 +0000

    2010-07-27  James Robinson  <jamesr at 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::):
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@64161 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 439a99f..e8b19f8 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,36 @@
+2010-07-27  James Robinson  <jamesr at 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::):
+
 2010-07-27  Simon Fraser  <simon.fraser at apple.com>
 
         Reviewed by Darin Adler.
diff --git a/WebCore/platform/graphics/chromium/GLES2Canvas.cpp b/WebCore/platform/graphics/chromium/GLES2Canvas.cpp
index 5b15e62..ec188c8 100644
--- a/WebCore/platform/graphics/chromium/GLES2Canvas.cpp
+++ b/WebCore/platform/graphics/chromium/GLES2Canvas.cpp
@@ -73,7 +73,7 @@ struct GLES2Canvas::State {
     AffineTransform m_ctm;
 };
 
-GLES2Canvas::GLES2Canvas(GLES2Context* context, int width, int height)
+GLES2Canvas::GLES2Canvas(GLES2Context* context, const IntSize& size)
     : m_gles2Context(context)
     , m_quadVertices(0)
     , m_quadIndices(0)
@@ -87,17 +87,15 @@ GLES2Canvas::GLES2Canvas(GLES2Context* context, int width, int height)
     , m_texSamplerLocation(-1)
     , m_texAlphaLocation(-1)
     , m_texPositionLocation(-1)
-    , m_width(width)
-    , m_height(height)
     , m_state(0)
 {
     m_flipMatrix.translate(-1.0f, 1.0f);
-    m_flipMatrix.scale(2.0f / width, -2.0f / height);
+    m_flipMatrix.scale(2.0f / size.width(), -2.0f / size.height());
 
     m_gles2Context->makeCurrent();
-    m_gles2Context->resizeOffscreenContent(IntSize(width, height));
+    m_gles2Context->resizeOffscreenContent(size);
     m_gles2Context->swapBuffers();
-    glViewport(0, 0, width, height);
+    glViewport(0, 0, size.width(), size.height());
 
     m_stateStack.append(State());
     m_state = &m_stateStack.last();
diff --git a/WebCore/platform/graphics/chromium/GLES2Canvas.h b/WebCore/platform/graphics/chromium/GLES2Canvas.h
index 802b200..e3a7a3b 100644
--- a/WebCore/platform/graphics/chromium/GLES2Canvas.h
+++ b/WebCore/platform/graphics/chromium/GLES2Canvas.h
@@ -53,7 +53,7 @@ typedef HashMap<NativeImagePtr, RefPtr<GLES2Texture> > TextureHashMap;
 
 class GLES2Canvas : public Noncopyable {
 public:
-    GLES2Canvas(GLES2Context* context, int width, int height);
+    GLES2Canvas(GLES2Context*, const IntSize&);
     ~GLES2Canvas();
 
     void fillRect(const FloatRect&, const Color&, ColorSpace);
@@ -103,8 +103,6 @@ private:
     int m_texSamplerLocation;
     int m_texAlphaLocation;
     int m_texPositionLocation;
-    int m_width;
-    int m_height;
     AffineTransform m_flipMatrix;
     TextureHashMap m_textures;
     CompositeOperator m_lastCompositeOp; // This is the one last set, not necessarily the one in the state stack.
diff --git a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
index 15bd9b4..392d505 100644
--- a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
+++ b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
@@ -44,7 +44,15 @@
 #include "SkShader.h"
 #include "SkDashPathEffect.h"
 
+#if USE(GLES2_RENDERING)
+#include "GLES2Canvas.h"
+#include "GLES2Context.h"
+#include "GLES2Texture.h"
+#include <GLES2/gl2.h>
+#endif
+
 #include <wtf/MathExtras.h>
+#include <wtf/OwnArrayPtr.h>
 #include <wtf/Vector.h>
 
 namespace WebCore 
@@ -199,6 +207,11 @@ PlatformContextSkia::PlatformContextSkia(skia::PlatformCanvas* canvas)
 #if OS(WINDOWS)
     , m_drawingToImageBuffer(false)
 #endif
+#if USE(GLES2_RENDERING)
+    , m_useGPU(false)
+    , m_gpuCanvas(0)
+    , m_backingStoreState(None)
+#endif
 {
     m_stateStack.append(State());
     m_state = &m_stateStack.last();
@@ -661,3 +674,117 @@ void PlatformContextSkia::applyAntiAliasedClipPaths(WTF::Vector<SkPath>& paths)
 
     m_canvas->restore();
 }
+
+#if USE(GLES2_RENDERING)
+void PlatformContextSkia::setGLES2Context(WebCore::GLES2Context* context, const WebCore::IntSize& size)
+{
+    m_useGPU = true;
+    m_gpuCanvas = new WebCore::GLES2Canvas(context, size);
+}
+
+void PlatformContextSkia::preSoftwareDraw() const
+{
+    if (!m_useGPU)
+        return;
+
+    if (m_backingStoreState == Hardware) {
+        // Depending on the blend mode we need to do one of a few things:
+
+        // * For associative blend modes, we can draw into an initially empty
+        // canvas and then composite the results on top of the hardware drawn
+        // results before the next hardware draw or swapBuffers().
+
+        // * For non-associative blend modes we have to do a readback and then
+        // software draw.  When we re-upload in this mode we have to blow
+        // away whatever is in the hardware backing store (do a copy instead
+        // of a compositing operation).
+
+        if (m_state->m_xferMode == SkXfermode::kSrcOver_Mode) {
+            // Last drawn on hardware; clear out the canvas.
+            m_canvas->save();
+            SkRect bounds = {0, 0, m_canvas->getDevice()->width(), m_canvas->getDevice()->height()};
+            m_canvas->clipRect(bounds, SkRegion::kReplace_Op);
+            m_canvas->drawARGB(0, 0, 0, 0, SkXfermode::kClear_Mode);
+            m_canvas->restore();
+            // Start compositing into the empty canvas.
+            m_backingStoreState = Mixed;
+        } else {
+            readbackHardwareToSoftware();
+            // When we switch back to hardware copy the results, don't composite.
+            m_backingStoreState = Software;
+        }
+    } else if (m_backingStoreState == Mixed) {
+        if (m_state->m_xferMode != SkXfermode::kSrcOver_Mode) {
+            // Have to composite our currently software drawn data...
+            uploadSoftwareToHardware(WebCore::CompositeSourceOver);
+            // then do a readback so we can hardware draw stuff.
+            readbackHardwareToSoftware();
+            m_backingStoreState = Software;
+        }
+    }
+}
+
+void PlatformContextSkia::preHardwareDraw() const
+{
+    if (!m_useGPU)
+        return;
+
+    if (m_backingStoreState == Software) {
+        // Last drawn in software; upload everything we've drawn.
+        uploadSoftwareToHardware(WebCore::CompositeCopy);
+    } else if (m_backingStoreState == Mixed) {
+        // Stuff in software/hardware, composite the software stuff on top of
+        // the hardware stuff.
+        uploadSoftwareToHardware(WebCore::CompositeSourceOver);
+    }
+    m_backingStoreState = Hardware;
+}
+
+void PlatformContextSkia::syncSoftwareCanvas() const
+{
+    if (!m_useGPU)
+        return;
+
+    if (m_backingStoreState == Hardware)
+        readbackHardwareToSoftware();
+    else if (m_backingStoreState == Mixed) {
+        // Have to composite our currently software drawn data..
+        uploadSoftwareToHardware(WebCore::CompositeSourceOver);
+        // then do a readback.
+        readbackHardwareToSoftware();
+        m_backingStoreState = Software;
+    }
+    m_backingStoreState = Software;
+}
+
+void PlatformContextSkia::uploadSoftwareToHardware(WebCore::CompositeOperator op) const
+{
+    const SkBitmap& bitmap = m_canvas->getDevice()->accessBitmap(false);
+    SkAutoLockPixels lock(bitmap);
+    m_gpuCanvas->gles2Context()->makeCurrent();
+    // FIXME: Keep a texture around for this rather than constantly creating/destroying one.
+    RefPtr<WebCore::GLES2Texture> texture = WebCore::GLES2Texture::create(WebCore::GLES2Texture::BGRA8, bitmap.width(), bitmap.height());
+    texture->load(bitmap.getPixels());
+    WebCore::IntRect rect(0, 0, bitmap.width(), bitmap.height());
+    gpuCanvas()->drawTexturedRect(texture.get(), rect, rect, WebCore::DeviceColorSpace, op);
+}
+
+void PlatformContextSkia::readbackHardwareToSoftware() const
+{
+    const SkBitmap& bitmap = m_canvas->getDevice()->accessBitmap(true);
+    SkAutoLockPixels lock(bitmap);
+    m_gpuCanvas->gles2Context()->makeCurrent();
+    int width = bitmap.width(), height = bitmap.height();
+    OwnArrayPtr<uint32_t> buf(new uint32_t[width]);
+    // Flips the image vertically.
+    for (int y = 0; y < height; ++y) {
+        uint32_t* pixels = bitmap.getAddr32(0, y);
+        glReadPixels(0, height - 1 - y, width, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+        for (int i = 0; i < width; ++i) {
+            uint32_t pixel = pixels[i];
+            // Swizzles from RGBA -> BGRA.
+            pixels[i] = pixel & 0xFF00FF00 | ((pixel & 0x00FF0000) >> 16) | ((pixel & 0x000000FF) << 16);
+        }
+    }
+}
+#endif
diff --git a/WebCore/platform/graphics/skia/PlatformContextSkia.h b/WebCore/platform/graphics/skia/PlatformContextSkia.h
index 88a8ec7..1b4e79c 100644
--- a/WebCore/platform/graphics/skia/PlatformContextSkia.h
+++ b/WebCore/platform/graphics/skia/PlatformContextSkia.h
@@ -41,6 +41,14 @@
 #include "SkPaint.h"
 #include "SkPath.h"
 
+#if USE(GLES2_RENDERING)
+namespace WebCore {
+enum CompositeOperator;
+class GLES2Canvas;
+class GLES2Context;
+}
+#endif
+
 #include <wtf/Vector.h>
 
 // This class holds the platform-specific state for GraphicsContext. We put
@@ -174,6 +182,24 @@ public:
     void setImageResamplingHint(const WebCore::IntSize& srcSize, const WebCore::FloatSize& dstSize);
     void clearImageResamplingHint();
     bool hasImageResamplingHint() const;
+#if USE(GLES2_RENDERING)
+    bool useGPU() { return m_useGPU; }
+    void setGLES2Context(WebCore::GLES2Context*, const WebCore::IntSize&);
+    WebCore::GLES2Canvas* gpuCanvas() const { return m_gpuCanvas.get(); }
+#endif
+
+#if USE(GLES2_RENDERING)
+    // Call these before making a call that manipulates the underlying
+    // skia::PlatformCanvas or WebCore::GLES2Canvas
+    void preSoftwareDraw() const;
+    void preHardwareDraw() const;
+    // Call to force the skia::PlatformCanvas to contain all rendering results.
+    void syncSoftwareCanvas() const;
+#else
+    void preSoftwareDraw() const {}
+    void preHardwareDraw() const {}
+    void syncSoftwareCanvas() const {}
+#endif
 
 private:
 #if OS(LINUX) || OS(WINDOWS)
@@ -183,6 +209,11 @@ private:
 #endif
     void applyAntiAliasedClipPaths(WTF::Vector<SkPath>& paths);
 
+#if USE(GLES2_RENDERING)
+    void uploadSoftwareToHardware(WebCore::CompositeOperator) const;
+    void readbackHardwareToSoftware() const;
+#endif
+
     // Defines drawing style.
     struct State;
 
@@ -206,6 +237,11 @@ private:
 #if OS(WINDOWS)
     bool m_drawingToImageBuffer;
 #endif
+#if USE(GLES2_RENDERING)
+    bool m_useGPU;
+    OwnPtr<WebCore::GLES2Canvas> m_gpuCanvas;
+    mutable enum { None, Software, Mixed, Hardware } m_backingStoreState;
+#endif
 };
 
-#endif  // PlatformContextSkia_h
+#endif // PlatformContextSkia_h

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list