summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/graphics/skia
diff options
context:
space:
mode:
authorIain Merrick <husky@google.com>2010-09-13 16:35:48 +0100
committerIain Merrick <husky@google.com>2010-09-16 12:10:42 +0100
commit5abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306 (patch)
treeddce1aa5e3b6967a69691892e500897558ff8ab6 /WebCore/platform/graphics/skia
parent12bec63ec71e46baba27f0bd9bd9d8067683690a (diff)
downloadexternal_webkit-5abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306.zip
external_webkit-5abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306.tar.gz
external_webkit-5abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306.tar.bz2
Merge WebKit at r67178 : Initial merge by git.
Change-Id: I57e01163b6866cb029cdadf405a0394a3918bc18
Diffstat (limited to 'WebCore/platform/graphics/skia')
-rw-r--r--WebCore/platform/graphics/skia/FontCustomPlatformData.cpp213
-rw-r--r--WebCore/platform/graphics/skia/FontCustomPlatformData.h81
-rw-r--r--WebCore/platform/graphics/skia/GraphicsContextSkia.cpp29
-rw-r--r--WebCore/platform/graphics/skia/ImageBufferSkia.cpp22
-rw-r--r--WebCore/platform/graphics/skia/ImageSkia.cpp5
-rwxr-xr-x[-rw-r--r--]WebCore/platform/graphics/skia/PlatformContextSkia.cpp139
-rw-r--r--WebCore/platform/graphics/skia/PlatformContextSkia.h28
7 files changed, 429 insertions, 88 deletions
diff --git a/WebCore/platform/graphics/skia/FontCustomPlatformData.cpp b/WebCore/platform/graphics/skia/FontCustomPlatformData.cpp
new file mode 100644
index 0000000..b6d6e65
--- /dev/null
+++ b/WebCore/platform/graphics/skia/FontCustomPlatformData.cpp
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 2007 Apple Computer, Inc.
+ * Copyright (c) 2007, 2008, 2009, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "FontCustomPlatformData.h"
+
+#if OS(WINDOWS)
+#include "Base64.h"
+#include "ChromiumBridge.h"
+#include "OpenTypeUtilities.h"
+#elif OS(LINUX)
+#include "SkStream.h"
+#endif
+
+#include "FontPlatformData.h"
+#include "NotImplemented.h"
+#include "OpenTypeSanitizer.h"
+#include "SharedBuffer.h"
+
+#if OS(WINDOWS)
+#include <objbase.h>
+#elif OS(LINUX)
+#include <cstring>
+#endif
+
+namespace WebCore {
+
+FontCustomPlatformData::~FontCustomPlatformData()
+{
+#if OS(WINDOWS)
+ if (m_fontReference)
+ RemoveFontMemResourceEx(m_fontReference);
+#elif OS(LINUX)
+ if (m_fontReference)
+ m_fontReference->unref();
+#endif
+}
+
+FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontRenderingMode mode)
+{
+#if OS(WINDOWS)
+ ASSERT(m_fontReference);
+
+ LOGFONT logFont;
+ // m_name comes from createUniqueFontName, which, in turn, gets
+ // it from base64-encoded uuid (128-bit). So, m_name
+ // can never be longer than LF_FACESIZE (32).
+ if (m_name.length() + 1 >= LF_FACESIZE) {
+ ASSERT_NOT_REACHED();
+ return FontPlatformData();
+ }
+ memcpy(logFont.lfFaceName, m_name.charactersWithNullTermination(),
+ sizeof(logFont.lfFaceName[0]) * (1 + m_name.length()));
+
+ // FIXME: almost identical to FillLogFont in FontCacheWin.cpp.
+ // Need to refactor.
+ logFont.lfHeight = -size;
+ logFont.lfWidth = 0;
+ logFont.lfEscapement = 0;
+ logFont.lfOrientation = 0;
+ logFont.lfUnderline = false;
+ logFont.lfStrikeOut = false;
+ logFont.lfCharSet = DEFAULT_CHARSET;
+ logFont.lfOutPrecision = OUT_TT_ONLY_PRECIS;
+ logFont.lfQuality = ChromiumBridge::layoutTestMode() ?
+ NONANTIALIASED_QUALITY :
+ DEFAULT_QUALITY; // Honor user's desktop settings.
+ logFont.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
+ logFont.lfItalic = italic;
+ logFont.lfWeight = bold ? 700 : 400;
+
+ HFONT hfont = CreateFontIndirect(&logFont);
+ return FontPlatformData(hfont, size);
+#elif OS(LINUX)
+ ASSERT(m_fontReference);
+ return FontPlatformData(m_fontReference, "", size, bold && !m_fontReference->isBold(), italic && !m_fontReference->isItalic());
+#else
+ notImplemented();
+ return FontPlatformData();
+#endif
+}
+
+#if OS(WINDOWS)
+// Creates a unique and unpredictable font name, in order to avoid collisions and to
+// not allow access from CSS.
+static String createUniqueFontName()
+{
+ Vector<char> fontUuid(sizeof(GUID));
+ CoCreateGuid(reinterpret_cast<GUID*>(fontUuid.data()));
+
+ Vector<char> fontNameVector;
+ base64Encode(fontUuid, fontNameVector);
+ ASSERT(fontNameVector.size() < LF_FACESIZE);
+ return String(fontNameVector.data(), fontNameVector.size());
+}
+#endif
+
+#if OS(LINUX)
+class RemoteFontStream : public SkStream {
+public:
+ explicit RemoteFontStream(PassRefPtr<SharedBuffer> buffer)
+ : m_buffer(buffer)
+ , m_offset(0)
+ {
+ }
+
+ virtual ~RemoteFontStream()
+ {
+ }
+
+ virtual bool rewind()
+ {
+ m_offset = 0;
+ return true;
+ }
+
+ virtual size_t read(void* buffer, size_t size)
+ {
+ if (!buffer && !size) {
+ // This is request for the length of the stream.
+ return m_buffer->size();
+ }
+ if (!buffer) {
+ // This is a request to skip bytes. This operation is not supported.
+ return 0;
+ }
+ // This is a request to read bytes.
+ if (!m_buffer->data() || !m_buffer->size())
+ return 0;
+ size_t left = m_buffer->size() - m_offset;
+ size_t toRead = (left > size) ? size : left;
+ std::memcpy(buffer, m_buffer->data() + m_offset, toRead);
+ m_offset += toRead;
+ return toRead;
+ }
+
+private:
+ RefPtr<SharedBuffer> m_buffer;
+ size_t m_offset;
+};
+#endif
+
+FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)
+{
+ ASSERT_ARG(buffer, buffer);
+
+#if ENABLE(OPENTYPE_SANITIZER)
+ OpenTypeSanitizer sanitizer(buffer);
+ RefPtr<SharedBuffer> transcodeBuffer = sanitizer.sanitize();
+ if (!transcodeBuffer)
+ return 0; // validation failed.
+ buffer = transcodeBuffer.get();
+#endif
+
+#if OS(WINDOWS)
+ // Introduce the font to GDI. AddFontMemResourceEx should be used with care, because it will pollute the process's
+ // font namespace (Windows has no API for creating an HFONT from data without exposing the font to the
+ // entire process first).
+ String fontName = createUniqueFontName();
+ HANDLE fontReference = renameAndActivateFont(buffer, fontName);
+ if (!fontReference)
+ return 0;
+ return new FontCustomPlatformData(fontReference, fontName);
+#elif OS(LINUX)
+ RemoteFontStream* stream = new RemoteFontStream(buffer);
+ SkTypeface* typeface = SkTypeface::CreateFromStream(stream);
+ if (!typeface)
+ return 0;
+ return new FontCustomPlatformData(typeface);
+#else
+ notImplemented();
+ return 0;
+#endif
+}
+
+bool FontCustomPlatformData::supportsFormat(const String& format)
+{
+ return equalIgnoringCase(format, "truetype") || equalIgnoringCase(format, "opentype")
+#if ENABLE(OPENTYPE_SANITIZER)
+ || equalIgnoringCase(format, "woff")
+#endif
+ ;
+}
+
+}
diff --git a/WebCore/platform/graphics/skia/FontCustomPlatformData.h b/WebCore/platform/graphics/skia/FontCustomPlatformData.h
new file mode 100644
index 0000000..d451c9c
--- /dev/null
+++ b/WebCore/platform/graphics/skia/FontCustomPlatformData.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2007 Apple Computer, Inc.
+ * Copyright (c) 2007, 2008, 2009, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FontCustomPlatformData_h
+#define FontCustomPlatformData_h
+
+#include "FontRenderingMode.h"
+#include <wtf/Forward.h>
+#include <wtf/Noncopyable.h>
+
+#if OS(WINDOWS)
+#include "PlatformString.h"
+#include <windows.h>
+#elif OS(LINUX)
+#include "SkTypeface.h"
+#endif
+
+namespace WebCore {
+
+class FontPlatformData;
+class SharedBuffer;
+
+struct FontCustomPlatformData : Noncopyable {
+#if OS(WINDOWS)
+ FontCustomPlatformData(HANDLE fontReference, const String& name)
+ : m_fontReference(fontReference)
+ , m_name(name)
+ {}
+#elif OS(LINUX)
+ explicit FontCustomPlatformData(SkTypeface* typeface)
+ : m_fontReference(typeface)
+ {}
+#endif
+
+ ~FontCustomPlatformData();
+
+ FontPlatformData fontPlatformData(int size, bool bold, bool italic,
+ FontRenderingMode = NormalRenderingMode);
+
+ static bool supportsFormat(const String&);
+
+#if OS(WINDOWS)
+ HANDLE m_fontReference;
+ String m_name;
+#elif OS(LINUX)
+ SkTypeface* m_fontReference;
+#endif
+};
+
+FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer*);
+}
+
+#endif // FontCustomPlatformData_h
diff --git a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp b/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
index 1c80d49..d618c19 100644
--- a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
+++ b/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
@@ -1,10 +1,10 @@
/*
* Copyright (c) 2006, Google Inc. All rights reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
- *
+ *
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
@@ -14,7 +14,7 @@
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -65,7 +65,7 @@ namespace {
inline int fastMod(int value, int max)
{
int sign = SkExtractSign(value);
-
+
value = SkApplySign(value, sign);
if (value >= max)
value %= max;
@@ -391,7 +391,7 @@ void GraphicsContext::canvasClip(const Path& path)
if (!isPathSkiaSafe(getCTM(), p))
return;
- platformContext()->canvas()->clipPath(p);
+ platformContext()->canvasClipPath(p);
}
void GraphicsContext::clipOut(const IntRect& rect)
@@ -499,7 +499,7 @@ void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint* poin
if (numPoints <= 1)
return;
-
+
// FIXME: IMPLEMENT!!
}
@@ -767,7 +767,7 @@ void GraphicsContext::fillRect(const FloatRect& rect)
ClipRectToCanvas(*platformContext()->canvas(), r, &r);
}
- if (platformContext()->useGPU() && !m_common->state.fillPattern && !m_common->state.fillGradient && !platformContext()->getDrawLooper()) {
+ if (platformContext()->useGPU() && platformContext()->canAccelerate()) {
platformContext()->prepareForHardwareDraw();
platformContext()->gpuCanvas()->fillRect(rect);
return;
@@ -789,7 +789,7 @@ void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorS
if (paintingDisabled())
return;
- if (platformContext()->useGPU() && !m_common->state.fillPattern && !m_common->state.fillGradient) {
+ if (platformContext()->useGPU() && platformContext()->canAccelerate()) {
platformContext()->prepareForHardwareDraw();
platformContext()->gpuCanvas()->fillRect(rect, color, colorSpace);
return;
@@ -1240,14 +1240,19 @@ void GraphicsContext::translate(float w, float h)
WebCoreFloatToSkScalar(h));
}
-void GraphicsContext::setGraphicsContext3D(GraphicsContext3D* context3D, const IntSize& size)
+void GraphicsContext::syncSoftwareCanvas()
{
- platformContext()->setGraphicsContext3D(context3D, size);
+ platformContext()->syncSoftwareCanvas();
}
-void GraphicsContext::syncSoftwareCanvas()
+void GraphicsContext::setSharedGraphicsContext3D(SharedGraphicsContext3D* context, DrawingBuffer* framebuffer, const IntSize& size)
{
- platformContext()->syncSoftwareCanvas();
+ platformContext()->setSharedGraphicsContext3D(context, framebuffer, size);
+}
+
+void GraphicsContext::markDirtyRect(const IntRect& rect)
+{
+ platformContext()->markDirtyRect(rect);
}
} // namespace WebCore
diff --git a/WebCore/platform/graphics/skia/ImageBufferSkia.cpp b/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
index 9403406..2be7dc5 100644
--- a/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
+++ b/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
@@ -36,10 +36,12 @@
#include "Base64.h"
#include "BitmapImage.h"
#include "BitmapImageSingleFrameSkia.h"
+#include "DrawingBuffer.h"
+#include "GLES2Canvas.h"
#include "GraphicsContext.h"
#include "ImageData.h"
-#include "PlatformContextSkia.h"
#include "PNGImageEncoder.h"
+#include "PlatformContextSkia.h"
#include "SkColorPriv.h"
#include "SkiaUtils.h"
@@ -67,9 +69,7 @@ ImageBuffer::ImageBuffer(const IntSize& size, ImageColorSpace imageColorSpace, b
m_data.m_platformContext.setCanvas(&m_data.m_canvas);
m_context.set(new GraphicsContext(&m_data.m_platformContext));
-#if OS(WINDOWS)
m_context->platformContext()->setDrawingToImageBuffer(true);
-#endif
// Make the background transparent. It would be nice if this wasn't
// required, but the canvas is currently filled with the magic transparency
@@ -100,14 +100,26 @@ PassRefPtr<Image> ImageBuffer::copyImage() const
void ImageBuffer::clip(GraphicsContext* context, const FloatRect& rect) const
{
-#if OS(LINUX) || OS(WINDOWS)
context->platformContext()->beginLayerClippedToImage(rect, this);
-#endif
}
void ImageBuffer::draw(GraphicsContext* context, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect,
CompositeOperator op, bool useLowQualityScale)
{
+ if (m_data.m_platformContext.useGPU() && context->platformContext()->useGPU()) {
+ if (context->platformContext()->canAccelerate()) {
+ DrawingBuffer* sourceDrawingBuffer = m_data.m_platformContext.gpuCanvas()->drawingBuffer();
+ unsigned sourceTexture = sourceDrawingBuffer->getRenderingResultsAsTexture();
+ FloatRect destRectFlipped(destRect);
+ destRectFlipped.setY(destRect.y() + destRect.height());
+ destRectFlipped.setHeight(-destRect.height());
+ context->platformContext()->prepareForHardwareDraw();
+ context->platformContext()->gpuCanvas()->drawTexturedRect(sourceTexture, m_size, srcRect, destRectFlipped, styleColorSpace, op);
+ return;
+ }
+ m_data.m_platformContext.syncSoftwareCanvas();
+ }
+
RefPtr<Image> image = BitmapImageSingleFrameSkia::create(*m_data.m_platformContext.bitmap(), context == m_context);
context->drawImage(image.get(), styleColorSpace, destRect, srcRect, op, useLowQualityScale);
}
diff --git a/WebCore/platform/graphics/skia/ImageSkia.cpp b/WebCore/platform/graphics/skia/ImageSkia.cpp
index aed289f..9625b34 100644
--- a/WebCore/platform/graphics/skia/ImageSkia.cpp
+++ b/WebCore/platform/graphics/skia/ImageSkia.cpp
@@ -47,6 +47,7 @@
#include "SkRect.h"
#include "SkShader.h"
#include "SkiaUtils.h"
+#include "Texture.h"
#include "skia/ext/image_operations.h"
#include "skia/ext/platform_canvas.h"
@@ -468,7 +469,7 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dstRect,
if (normSrcRect.isEmpty() || normDstRect.isEmpty())
return; // Nothing to draw.
- if (ctxt->platformContext()->useGPU()) {
+ if (ctxt->platformContext()->useGPU() && ctxt->platformContext()->canAccelerate()) {
drawBitmapGLES2(ctxt, bm, normSrcRect, normDstRect, colorSpace, compositeOp);
return;
}
@@ -496,7 +497,7 @@ void BitmapImageSingleFrameSkia::draw(GraphicsContext* ctxt,
if (normSrcRect.isEmpty() || normDstRect.isEmpty())
return; // Nothing to draw.
- if (ctxt->platformContext()->useGPU()) {
+ if (ctxt->platformContext()->useGPU() && ctxt->platformContext()->canAccelerate()) {
drawBitmapGLES2(ctxt, &m_nativeImage, srcRect, dstRect, styleColorSpace, compositeOp);
return;
}
diff --git a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
index 3b1d015..88fbcdd 100644..100755
--- a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
+++ b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
@@ -1,10 +1,10 @@
/*
* Copyright (c) 2008, Google Inc. All rights reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
- *
+ *
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
@@ -14,7 +14,7 @@
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -33,12 +33,13 @@
#include "PlatformContextSkia.h"
#include "AffineTransform.h"
-#include "CanvasLayerChromium.h"
+#include "DrawingBuffer.h"
#include "GLES2Canvas.h"
#include "GraphicsContext.h"
#include "GraphicsContext3D.h"
#include "ImageBuffer.h"
#include "NativeImageSkia.h"
+#include "SharedGraphicsContext3D.h"
#include "SkiaUtils.h"
#include "Texture.h"
#include "TilingData.h"
@@ -96,18 +97,19 @@ struct PlatformContextSkia::State {
// color to produce a new output color.
SkColor applyAlpha(SkColor) const;
-#if OS(LINUX) || OS(WINDOWS)
// If non-empty, the current State is clipped to this image.
SkBitmap m_imageBufferClip;
// If m_imageBufferClip is non-empty, this is the region the image is clipped to.
FloatRect m_clip;
-#endif
// This is a list of clipping paths which are currently active, in the
// order in which they were pushed.
WTF::Vector<SkPath> m_antiAliasClipPaths;
InterpolationQuality m_interpolationQuality;
+ // If we currently have a canvas (non-antialiased path) clip applied.
+ bool m_canvasClipApplied;
+
PlatformContextSkia::State cloneInheritedProperties();
private:
// Not supported.
@@ -133,6 +135,7 @@ PlatformContextSkia::State::State()
, m_dash(0)
, m_textDrawingMode(cTextFill)
, m_interpolationQuality(InterpolationHigh)
+ , m_canvasClipApplied(false)
{
}
@@ -153,12 +156,11 @@ PlatformContextSkia::State::State(const State& other)
, m_lineJoin(other.m_lineJoin)
, m_dash(other.m_dash)
, m_textDrawingMode(other.m_textDrawingMode)
-#if OS(LINUX) || OS(WINDOWS)
, m_imageBufferClip(other.m_imageBufferClip)
, m_clip(other.m_clip)
-#endif
, m_antiAliasClipPaths(other.m_antiAliasClipPaths)
, m_interpolationQuality(other.m_interpolationQuality)
+ , m_canvasClipApplied(other.m_canvasClipApplied)
{
// Up the ref count of these. saveRef does nothing if 'this' is NULL.
m_looper->safeRef();
@@ -181,7 +183,7 @@ PlatformContextSkia::State PlatformContextSkia::State::cloneInheritedProperties(
PlatformContextSkia::State state(*this);
// Everything is inherited except for the clip paths.
- state.m_antiAliasClipPaths.clear();
+ state.m_antiAliasClipPaths.clear();
return state;
}
@@ -203,9 +205,7 @@ SkColor PlatformContextSkia::State::applyAlpha(SkColor c) const
// Danger: canvas can be NULL.
PlatformContextSkia::PlatformContextSkia(skia::PlatformCanvas* canvas)
: m_canvas(canvas)
-#if OS(WINDOWS)
, m_drawingToImageBuffer(false)
-#endif
, m_useGPU(false)
, m_gpuCanvas(0)
, m_backingStoreState(None)
@@ -216,12 +216,8 @@ PlatformContextSkia::PlatformContextSkia(skia::PlatformCanvas* canvas)
PlatformContextSkia::~PlatformContextSkia()
{
-#if USE(ACCELERATED_COMPOSITING)
- if (m_gpuCanvas) {
- CanvasLayerChromium* layer = static_cast<CanvasLayerChromium*>(m_gpuCanvas->context()->platformLayer());
- layer->setPrepareTextureCallback(0);
- }
-#endif
+ if (m_gpuCanvas)
+ m_gpuCanvas->drawingBuffer()->setWillPublishCallback(0);
}
void PlatformContextSkia::setCanvas(skia::PlatformCanvas* canvas)
@@ -229,7 +225,6 @@ void PlatformContextSkia::setCanvas(skia::PlatformCanvas* canvas)
m_canvas = canvas;
}
-#if OS(WINDOWS)
void PlatformContextSkia::setDrawingToImageBuffer(bool value)
{
m_drawingToImageBuffer = value;
@@ -239,7 +234,6 @@ bool PlatformContextSkia::isDrawingToImageBuffer() const
{
return m_drawingToImageBuffer;
}
-#endif
void PlatformContextSkia::save()
{
@@ -248,17 +242,14 @@ void PlatformContextSkia::save()
m_stateStack.append(m_state->cloneInheritedProperties());
m_state = &m_stateStack.last();
-#if OS(LINUX) || OS(WINDOWS)
// The clip image only needs to be applied once. Reset the image so that we
// don't attempt to clip multiple times.
m_state->m_imageBufferClip.reset();
-#endif
// Save our native canvas.
canvas()->save();
}
-#if OS(LINUX) || OS(WINDOWS)
void PlatformContextSkia::beginLayerClippedToImage(const FloatRect& rect,
const ImageBuffer* imageBuffer)
{
@@ -287,7 +278,6 @@ void PlatformContextSkia::beginLayerClippedToImage(const FloatRect& rect,
m_state->m_imageBufferClip = *bitmap;
}
}
-#endif
void PlatformContextSkia::clipPathAntiAliased(const SkPath& clipPath)
{
@@ -306,12 +296,10 @@ void PlatformContextSkia::clipPathAntiAliased(const SkPath& clipPath)
void PlatformContextSkia::restore()
{
-#if OS(LINUX) || OS(WINDOWS)
if (!m_state->m_imageBufferClip.empty()) {
applyClipFromImage(m_state->m_clip, m_state->m_imageBufferClip);
canvas()->restore();
}
-#endif
if (!m_state->m_antiAliasClipPaths.isEmpty())
applyAntiAliasedClipPaths(m_state->m_antiAliasClipPaths);
@@ -337,7 +325,7 @@ void PlatformContextSkia::drawRect(SkRect rect)
// We do a fill of four rects to simulate the stroke of a border.
SkColor oldFillColor = m_state->m_fillColor;
- // setFillColor() will set the shader to NULL, so save a ref to it now.
+ // setFillColor() will set the shader to NULL, so save a ref to it now.
SkShader* oldFillShader = m_state->m_fillShader;
oldFillShader->safeRef();
setFillColor(m_state->m_strokeColor);
@@ -462,7 +450,7 @@ void PlatformContextSkia::setXfermodeMode(SkXfermode::Mode pdm)
void PlatformContextSkia::setFillColor(SkColor color)
{
m_state->m_fillColor = color;
- setFillShader(NULL);
+ setFillShader(0);
}
SkDrawLooper* PlatformContextSkia::getDrawLooper() const
@@ -483,7 +471,7 @@ void PlatformContextSkia::setStrokeStyle(StrokeStyle strokeStyle)
void PlatformContextSkia::setStrokeColor(SkColor strokeColor)
{
m_state->m_strokeColor = strokeColor;
- setStrokeShader(NULL);
+ setStrokeShader(0);
}
float PlatformContextSkia::getStrokeThickness() const
@@ -559,6 +547,12 @@ SkPath PlatformContextSkia::currentPathInLocalCoordinates() const
return localPath;
}
+void PlatformContextSkia::canvasClipPath(const SkPath& path)
+{
+ m_state->m_canvasClipApplied = true;
+ m_canvas->clipPath(path);
+}
+
void PlatformContextSkia::setFillRule(SkPath::FillType fr)
{
m_path.setFillType(fr);
@@ -630,7 +624,6 @@ bool PlatformContextSkia::hasImageResamplingHint() const
return !m_imageResamplingHintSrcSize.isEmpty() && !m_imageResamplingHintDstSize.isEmpty();
}
-#if OS(LINUX) || OS(WINDOWS)
void PlatformContextSkia::applyClipFromImage(const FloatRect& rect, const SkBitmap& imageBuffer)
{
// NOTE: this assumes the image mask contains opaque black for the portions that are to be shown, as such we
@@ -639,7 +632,6 @@ void PlatformContextSkia::applyClipFromImage(const FloatRect& rect, const SkBitm
paint.setXfermodeMode(SkXfermode::kDstIn_Mode);
m_canvas->drawBitmap(imageBuffer, SkFloatToScalar(rect.x()), SkFloatToScalar(rect.y()), &paint);
}
-#endif
void PlatformContextSkia::applyAntiAliasedClipPaths(WTF::Vector<SkPath>& paths)
{
@@ -678,33 +670,47 @@ void PlatformContextSkia::applyAntiAliasedClipPaths(WTF::Vector<SkPath>& paths)
m_canvas->restore();
}
-#if USE(ACCELERATED_COMPOSITING)
-class PrepareTextureCallbackImpl : public CanvasLayerChromium::PrepareTextureCallback {
+bool PlatformContextSkia::canAccelerate() const
+{
+ return !m_state->m_fillShader // Can't accelerate with a fill gradient or pattern.
+ && !m_state->m_looper // Can't accelerate with a shadow.
+ && !m_state->m_canvasClipApplied; // Can't accelerate with a clip to path applied.
+}
+
+class WillPublishCallbackImpl : public DrawingBuffer::WillPublishCallback {
public:
- static PassOwnPtr<PrepareTextureCallbackImpl> create(PlatformContextSkia* pcs)
+ static PassOwnPtr<WillPublishCallback> create(PlatformContextSkia* pcs)
{
- return new PrepareTextureCallbackImpl(pcs);
+ return adoptPtr(new WillPublishCallbackImpl(pcs));
}
- virtual void willPrepareTexture()
+ virtual void willPublish()
{
m_pcs->prepareForHardwareDraw();
}
+
private:
- explicit PrepareTextureCallbackImpl(PlatformContextSkia* pcs) : m_pcs(pcs) {}
+ explicit WillPublishCallbackImpl(PlatformContextSkia* pcs)
+ : m_pcs(pcs)
+ {
+ }
+
PlatformContextSkia* m_pcs;
};
-#endif
-void PlatformContextSkia::setGraphicsContext3D(GraphicsContext3D* context, const WebCore::IntSize& size)
+void PlatformContextSkia::setSharedGraphicsContext3D(SharedGraphicsContext3D* context, DrawingBuffer* drawingBuffer, const WebCore::IntSize& size)
{
- m_useGPU = true;
- m_gpuCanvas = new GLES2Canvas(context, size);
- m_uploadTexture.clear();
-#if USE(ACCELERATED_COMPOSITING)
- CanvasLayerChromium* layer = static_cast<CanvasLayerChromium*>(context->platformLayer());
- layer->setPrepareTextureCallback(PrepareTextureCallbackImpl::create(this));
-#endif
+ if (context && drawingBuffer) {
+ m_useGPU = true;
+ m_gpuCanvas = new GLES2Canvas(context, drawingBuffer, size);
+ m_uploadTexture.clear();
+ drawingBuffer->setWillPublishCallback(WillPublishCallbackImpl::create(this));
+ } else {
+ syncSoftwareCanvas();
+ m_uploadTexture.clear();
+ m_gpuCanvas.clear();
+ m_useGPU = false;
+ }
}
void PlatformContextSkia::prepareForSoftwareDraw() const
@@ -725,9 +731,7 @@ void PlatformContextSkia::prepareForSoftwareDraw() const
// of a compositing operation).
if (m_state->m_xferMode == SkXfermode::kSrcOver_Mode) {
- // Last drawn on hardware; clear out the canvas.
- m_canvas->getDevice()->eraseColor(0);
- // Start compositing into the empty canvas.
+ // Note that we have rendering results in both the hardware and software backing stores.
m_backingStoreState = Mixed;
} else {
readbackHardwareToSoftware();
@@ -780,17 +784,42 @@ void PlatformContextSkia::syncSoftwareCanvas() const
m_backingStoreState = Software;
}
+void PlatformContextSkia::markDirtyRect(const IntRect& rect)
+{
+ if (!m_useGPU)
+ return;
+
+ switch (m_backingStoreState) {
+ case Software:
+ case Mixed:
+ m_softwareDirtyRect.unite(rect);
+ return;
+ case Hardware:
+ return;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+}
+
void PlatformContextSkia::uploadSoftwareToHardware(CompositeOperator op) const
{
const SkBitmap& bitmap = m_canvas->getDevice()->accessBitmap(false);
SkAutoLockPixels lock(bitmap);
- GraphicsContext3D* context = m_gpuCanvas->context();
+ SharedGraphicsContext3D* context = m_gpuCanvas->context();
if (!m_uploadTexture || m_uploadTexture->tiles().totalSizeX() < bitmap.width() || m_uploadTexture->tiles().totalSizeY() < bitmap.height())
- m_uploadTexture = Texture::create(context, Texture::BGRA8, bitmap.width(), bitmap.height());
- m_uploadTexture->load(bitmap.getPixels());
- IntRect rect(0, 0, bitmap.width(), bitmap.height());
+ m_uploadTexture = context->createTexture(Texture::BGRA8, bitmap.width(), bitmap.height());
+
+ m_uploadTexture->updateSubRect(bitmap.getPixels(), m_softwareDirtyRect);
AffineTransform identity;
- gpuCanvas()->drawTexturedRect(m_uploadTexture.get(), rect, rect, identity, 1.0, DeviceColorSpace, op);
+ gpuCanvas()->drawTexturedRect(m_uploadTexture.get(), m_softwareDirtyRect, m_softwareDirtyRect, identity, 1.0, DeviceColorSpace, op);
+ // Clear out the region of the software canvas we just uploaded.
+ m_canvas->save();
+ m_canvas->resetMatrix();
+ SkRect bounds = m_softwareDirtyRect;
+ m_canvas->clipRect(bounds, SkRegion::kReplace_Op);
+ m_canvas->drawARGB(0, 0, 0, 0, SkXfermode::kClear_Mode);
+ m_canvas->restore();
+ m_softwareDirtyRect.setWidth(0); // Clear dirty rect.
}
void PlatformContextSkia::readbackHardwareToSoftware() const
@@ -799,7 +828,8 @@ void PlatformContextSkia::readbackHardwareToSoftware() const
SkAutoLockPixels lock(bitmap);
int width = bitmap.width(), height = bitmap.height();
OwnArrayPtr<uint32_t> buf(new uint32_t[width]);
- GraphicsContext3D* context = m_gpuCanvas->context();
+ SharedGraphicsContext3D* context = m_gpuCanvas->context();
+ m_gpuCanvas->bindFramebuffer();
// Flips the image vertically.
for (int y = 0; y < height; ++y) {
uint32_t* pixels = bitmap.getAddr32(0, y);
@@ -814,6 +844,7 @@ void PlatformContextSkia::readbackHardwareToSoftware() const
}
}
}
+ m_softwareDirtyRect.unite(IntRect(0, 0, width, height)); // Mark everything as dirty.
}
} // namespace WebCore
diff --git a/WebCore/platform/graphics/skia/PlatformContextSkia.h b/WebCore/platform/graphics/skia/PlatformContextSkia.h
index 82edc16..4ba85d1 100644
--- a/WebCore/platform/graphics/skia/PlatformContextSkia.h
+++ b/WebCore/platform/graphics/skia/PlatformContextSkia.h
@@ -1,10 +1,10 @@
/*
* Copyright (c) 2008, Google Inc. All rights reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
- *
+ *
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
@@ -14,7 +14,7 @@
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -35,7 +35,6 @@
#include "Noncopyable.h"
#include "SkDashPathEffect.h"
-#include "SkDeque.h"
#include "SkDrawLooper.h"
#include "SkPaint.h"
#include "SkPath.h"
@@ -46,9 +45,10 @@
namespace WebCore {
enum CompositeOperator;
+class DrawingBuffer;
class GLES2Canvas;
-class Texture;
class GraphicsContext3D;
+class Texture;
// This class holds the platform-specific state for GraphicsContext. We put
// most of our Skia wrappers on this class. In theory, a lot of this stuff could
@@ -78,7 +78,6 @@ public:
// to the constructor.
void setCanvas(skia::PlatformCanvas*);
-#if OS(WINDOWS)
// If false we're rendering to a GraphicsContext for a web page, if false
// we're not (as is the case when rendering to a canvas object).
// If this is true the contents have not been marked up with the magic
@@ -86,7 +85,6 @@ public:
// correctly updated.
void setDrawingToImageBuffer(bool);
bool isDrawingToImageBuffer() const;
-#endif
void save();
void restore();
@@ -95,9 +93,7 @@ public:
// |rect|. This layer is implicitly restored when the next restore is
// invoked.
// NOTE: |imageBuffer| may be deleted before the |restore| is invoked.
-#if OS(LINUX) || OS(WINDOWS)
void beginLayerClippedToImage(const FloatRect&, const ImageBuffer*);
-#endif
void clipPathAntiAliased(const SkPath&);
// Sets up the common flags on a paint for antialiasing, effects, etc.
@@ -143,6 +139,8 @@ public:
void addPath(const SkPath&);
SkPath currentPathInLocalCoordinates() const;
+ void canvasClipPath(const SkPath&);
+
// Returns the fill color. The returned color has it's alpha adjusted
// by the current alpha.
SkColor effectiveFillColor() const;
@@ -180,8 +178,10 @@ public:
void setImageResamplingHint(const IntSize& srcSize, const FloatSize& dstSize);
void clearImageResamplingHint();
bool hasImageResamplingHint() const;
+
+ bool canAccelerate() const;
bool useGPU() { return m_useGPU; }
- void setGraphicsContext3D(GraphicsContext3D*, const IntSize&);
+ void setSharedGraphicsContext3D(SharedGraphicsContext3D*, DrawingBuffer*, const IntSize&);
GLES2Canvas* gpuCanvas() const { return m_gpuCanvas.get(); }
// Call these before making a call that manipulates the underlying
@@ -190,13 +190,12 @@ public:
void prepareForHardwareDraw() const;
// Call to force the skia::PlatformCanvas to contain all rendering results.
void syncSoftwareCanvas() const;
+ void markDirtyRect(const IntRect& rect);
private:
-#if OS(LINUX) || OS(WINDOWS)
// Used when restoring and the state has an image clip. Only shows the pixels in
// m_canvas that are also in imageBuffer.
void applyClipFromImage(const FloatRect&, const SkBitmap&);
-#endif
void applyAntiAliasedClipPaths(WTF::Vector<SkPath>& paths);
void uploadSoftwareToHardware(CompositeOperator) const;
@@ -218,17 +217,16 @@ private:
// Current path in global coordinates.
SkPath m_path;
- // Stores image sizes for a hint to compute image resampling modes.
+ // Stores image sizes for a hint to compute image resampling modes.
// Values are used in ImageSkia.cpp
IntSize m_imageResamplingHintSrcSize;
FloatSize m_imageResamplingHintDstSize;
-#if OS(WINDOWS)
bool m_drawingToImageBuffer;
-#endif
bool m_useGPU;
OwnPtr<GLES2Canvas> m_gpuCanvas;
mutable enum { None, Software, Mixed, Hardware } m_backingStoreState;
mutable RefPtr<Texture> m_uploadTexture;
+ mutable IntRect m_softwareDirtyRect;
};
}