diff options
author | Iain Merrick <husky@google.com> | 2010-09-13 16:35:48 +0100 |
---|---|---|
committer | Iain Merrick <husky@google.com> | 2010-09-16 12:10:42 +0100 |
commit | 5abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306 (patch) | |
tree | ddce1aa5e3b6967a69691892e500897558ff8ab6 /WebCore/platform/graphics/skia | |
parent | 12bec63ec71e46baba27f0bd9bd9d8067683690a (diff) | |
download | external_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.cpp | 213 | ||||
-rw-r--r-- | WebCore/platform/graphics/skia/FontCustomPlatformData.h | 81 | ||||
-rw-r--r-- | WebCore/platform/graphics/skia/GraphicsContextSkia.cpp | 29 | ||||
-rw-r--r-- | WebCore/platform/graphics/skia/ImageBufferSkia.cpp | 22 | ||||
-rw-r--r-- | WebCore/platform/graphics/skia/ImageSkia.cpp | 5 | ||||
-rwxr-xr-x[-rw-r--r--] | WebCore/platform/graphics/skia/PlatformContextSkia.cpp | 139 | ||||
-rw-r--r-- | WebCore/platform/graphics/skia/PlatformContextSkia.h | 28 |
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; }; } |