diff options
author | Kristian Monsen <kristianm@google.com> | 2010-07-30 10:46:49 +0100 |
---|---|---|
committer | Kristian Monsen <kristianm@google.com> | 2010-08-04 13:01:34 +0100 |
commit | 0617145a89917ae7735fe1c9538688ab9a577df5 (patch) | |
tree | 56206078694427c37ed7bdf27eb5221398b833c0 /WebCore/platform/graphics | |
parent | ef1adcdfc805d4d13103f6f15cc5b4d96828a60f (diff) | |
download | external_webkit-0617145a89917ae7735fe1c9538688ab9a577df5.zip external_webkit-0617145a89917ae7735fe1c9538688ab9a577df5.tar.gz external_webkit-0617145a89917ae7735fe1c9538688ab9a577df5.tar.bz2 |
Merge WebKit at r64264 : Initial merge by git.
Change-Id: Ic42bef02efef8217a0f84c47176a9c617c28d1f1
Diffstat (limited to 'WebCore/platform/graphics')
26 files changed, 1267 insertions, 82 deletions
diff --git a/WebCore/platform/graphics/BitmapImage.h b/WebCore/platform/graphics/BitmapImage.h index 2cf30d3..72f3092 100644 --- a/WebCore/platform/graphics/BitmapImage.h +++ b/WebCore/platform/graphics/BitmapImage.h @@ -175,7 +175,7 @@ protected: virtual void draw(GraphicsContext*, const FloatRect& dstRect, const FloatRect& srcRect, ColorSpace styleColorSpace, CompositeOperator); #if (OS(WINCE) && !PLATFORM(QT)) - virtual void drawPattern(GraphicsContext*, const FloatRect& srcRect, const TransformationMatrix& patternTransform, + virtual void drawPattern(GraphicsContext*, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator, const FloatRect& destRect); #endif diff --git a/WebCore/platform/graphics/Font.cpp b/WebCore/platform/graphics/Font.cpp index 61f5707..0e93d4f 100644 --- a/WebCore/platform/graphics/Font.cpp +++ b/WebCore/platform/graphics/Font.cpp @@ -68,7 +68,7 @@ Font::Font(const FontDescription& fd, short letterSpacing, short wordSpacing) , m_letterSpacing(letterSpacing) , m_wordSpacing(wordSpacing) , m_isPlatformFont(false) - , m_needsTranscoding(fontTranscoder().needsTranscoding(family().family().string())) + , m_needsTranscoding(fontTranscoder().needsTranscoding(fd)) { } @@ -77,10 +77,10 @@ Font::Font(const FontPlatformData& fontData, bool isPrinterFont, FontSmoothingMo , m_letterSpacing(0) , m_wordSpacing(0) , m_isPlatformFont(true) - , m_needsTranscoding(fontTranscoder().needsTranscoding(family().family().string())) { m_fontDescription.setUsePrinterFont(isPrinterFont); m_fontDescription.setFontSmoothing(fontSmoothingMode); + m_needsTranscoding = fontTranscoder().needsTranscoding(fontDescription()); m_fontList->setPlatformFont(fontData); } @@ -90,7 +90,7 @@ Font::Font(const Font& other) , m_letterSpacing(other.m_letterSpacing) , m_wordSpacing(other.m_wordSpacing) , m_isPlatformFont(other.m_isPlatformFont) - , m_needsTranscoding(fontTranscoder().needsTranscoding(family().family().string())) + , m_needsTranscoding(fontTranscoder().needsTranscoding(other.m_fontDescription)) { } diff --git a/WebCore/platform/graphics/FontDescription.h b/WebCore/platform/graphics/FontDescription.h index fc63db9..86a4349 100644 --- a/WebCore/platform/graphics/FontDescription.h +++ b/WebCore/platform/graphics/FontDescription.h @@ -65,6 +65,7 @@ public: , m_keywordSize(0) , m_fontSmoothing(AutoSmoothing) , m_textRendering(AutoTextRendering) + , m_isSpecifiedFont(false) { } @@ -92,6 +93,7 @@ public: TextRenderingMode textRenderingMode() const { return static_cast<TextRenderingMode>(m_textRendering); } FontTraitsMask traitsMask() const; + bool isSpecifiedFont() const { return m_isSpecifiedFont; } void setFamily(const FontFamily& family) { m_familyList = family; } void setComputedSize(float s) { m_computedSize = s; } @@ -106,6 +108,7 @@ public: void setKeywordSize(unsigned s) { m_keywordSize = s; } void setFontSmoothing(FontSmoothingMode smoothing) { m_fontSmoothing = smoothing; } void setTextRenderingMode(TextRenderingMode rendering) { m_textRendering = rendering; } + void setIsSpecifiedFont(bool isSpecifiedFont) { m_isSpecifiedFont = isSpecifiedFont; } private: FontFamily m_familyList; // The list of font families to be used. @@ -130,6 +133,7 @@ private: unsigned m_fontSmoothing : 2; // FontSmoothingMode unsigned m_textRendering : 2; // TextRenderingMode + bool m_isSpecifiedFont : 1; // True if a web page specifies a non-generic font family as the first font family. }; inline bool FontDescription::operator==(const FontDescription& other) const @@ -146,7 +150,8 @@ inline bool FontDescription::operator==(const FontDescription& other) const && m_renderingMode == other.m_renderingMode && m_keywordSize == other.m_keywordSize && m_fontSmoothing == other.m_fontSmoothing - && m_textRendering == other.m_textRendering; + && m_textRendering == other.m_textRendering + && m_isSpecifiedFont == other.m_isSpecifiedFont; } } diff --git a/WebCore/platform/graphics/GraphicsContext.h b/WebCore/platform/graphics/GraphicsContext.h index 457368b..d5df153 100644 --- a/WebCore/platform/graphics/GraphicsContext.h +++ b/WebCore/platform/graphics/GraphicsContext.h @@ -274,7 +274,7 @@ namespace WebCore { void clipOutRoundedRect(const IntRect&, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight); void clipPath(WindRule); void clipToImageBuffer(const FloatRect&, const ImageBuffer*); - void clipConvexPolygon(size_t numPoints, const FloatPoint*); + void clipConvexPolygon(size_t numPoints, const FloatPoint*, bool antialias = true); int textDrawingMode(); void setTextDrawingMode(int); @@ -342,16 +342,16 @@ namespace WebCore { #if OS(WINCE) && !PLATFORM(QT) void setBitmap(PassRefPtr<SharedBitmap>); - const TransformationMatrix& affineTransform() const; - TransformationMatrix& affineTransform(); + const AffineTransform& affineTransform() const; + AffineTransform& affineTransform(); void resetAffineTransform(); void fillRect(const FloatRect&, const Gradient*); void drawText(const SimpleFontData* fontData, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point); void drawFrameControl(const IntRect& rect, unsigned type, unsigned state); void drawFocusRect(const IntRect& rect); void paintTextField(const IntRect& rect, unsigned state); - void drawBitmap(SharedBitmap*, const IntRect& dstRect, const IntRect& srcRect, CompositeOperator compositeOp); - void drawBitmapPattern(SharedBitmap*, const FloatRect& tileRectIn, const AffineTransform& patternTransform, const FloatPoint& phase, CompositeOperator op, const FloatRect& destRect, const IntSize& origSourceSize); + void drawBitmap(SharedBitmap*, const IntRect& dstRect, const IntRect& srcRect, ColorSpace styleColorSpace, CompositeOperator compositeOp); + void drawBitmapPattern(SharedBitmap*, const FloatRect& tileRectIn, const AffineTransform& patternTransform, const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect, const IntSize& origSourceSize); void drawIcon(HICON icon, const IntRect& dstRect, UINT flags); HDC getWindowsContext(const IntRect&, bool supportAlphaBlend = false, bool mayCreateBitmap = true); // The passed in rect is used to create a bitmap for compositing inside transparency layers. void releaseWindowsContext(HDC, const IntRect&, bool supportAlphaBlend = false, bool mayCreateBitmap = true); // The passed in HDC should be the one handed back by getWindowsContext. diff --git a/WebCore/platform/graphics/Path.h b/WebCore/platform/graphics/Path.h index f2ae2df..86b77f8 100644 --- a/WebCore/platform/graphics/Path.h +++ b/WebCore/platform/graphics/Path.h @@ -59,6 +59,7 @@ typedef BRegion PlatformPath; namespace WebCore { class PlatformPath; } +typedef WebCore::PlatformPath PlatformPath; #else typedef void PlatformPath; #endif diff --git a/WebCore/platform/graphics/cairo/FontPlatformDataCairo.cpp b/WebCore/platform/graphics/cairo/FontPlatformDataCairo.cpp index 974c195..1f94f5a 100644 --- a/WebCore/platform/graphics/cairo/FontPlatformDataCairo.cpp +++ b/WebCore/platform/graphics/cairo/FontPlatformDataCairo.cpp @@ -32,7 +32,9 @@ #include <cairo-ft.h> #include <cairo.h> #include <fontconfig/fcfreetype.h> +#if !PLATFORM(EFL) || ENABLE(GLIB_SUPPORT) #include <gdk/gdk.h> +#endif namespace WebCore { @@ -109,8 +111,10 @@ FontPlatformData::FontPlatformData(const FontDescription& fontDescription, const cairo_matrix_init_scale(&fontMatrix, fontDescription.computedPixelSize(), fontDescription.computedPixelSize()); cairo_matrix_init_identity(&ctm); +#if !PLATFORM(EFL) || ENABLE(GLIB_SUPPORT) if (GdkScreen* screen = gdk_screen_get_default()) options = gdk_screen_get_font_options(screen); +#endif // gdk_screen_get_font_options() returns NULL if no default options are // set, so we always have to check. @@ -149,8 +153,10 @@ FontPlatformData::FontPlatformData(cairo_font_face_t* fontFace, float size, bool static const cairo_font_options_t* defaultOptions = cairo_font_options_create(); const cairo_font_options_t* options = NULL; +#if !PLATFORM(EFL) || ENABLE(GLIB_SUPPORT) if (GdkScreen* screen = gdk_screen_get_default()) options = gdk_screen_get_font_options(screen); +#endif // gdk_screen_get_font_options() returns NULL if no default options are // set, so we always have to check. diff --git a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp index 6ed8905..96cd4ee 100644 --- a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp +++ b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp @@ -504,7 +504,7 @@ void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points cairo_restore(cr); } -void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint* points) +void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint* points, bool antialiased) { if (paintingDisabled()) return; diff --git a/WebCore/platform/graphics/cg/GraphicsContextCG.cpp b/WebCore/platform/graphics/cg/GraphicsContextCG.cpp index a65874c..2de4d14 100644 --- a/WebCore/platform/graphics/cg/GraphicsContextCG.cpp +++ b/WebCore/platform/graphics/cg/GraphicsContextCG.cpp @@ -469,16 +469,24 @@ void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points CGContextSetShouldAntialias(context, shouldAntialias()); } -void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint* points) +void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint* points, bool antialias) { if (paintingDisabled()) return; if (numPoints <= 1) return; + + CGContextRef context = platformContext(); + + if (antialias != shouldAntialias()) + CGContextSetShouldAntialias(context, antialias); - addConvexPolygonToContext(platformContext(), numPoints, points); + addConvexPolygonToContext(context, numPoints, points); clipPath(RULE_NONZERO); + + if (antialias != shouldAntialias()) + CGContextSetShouldAntialias(context, shouldAntialias()); } void GraphicsContext::applyStrokePattern() diff --git a/WebCore/platform/graphics/cg/ImageBufferCG.cpp b/WebCore/platform/graphics/cg/ImageBufferCG.cpp index fe7f83a..feb8cec 100644 --- a/WebCore/platform/graphics/cg/ImageBufferCG.cpp +++ b/WebCore/platform/graphics/cg/ImageBufferCG.cpp @@ -80,7 +80,7 @@ ImageBuffer::ImageBuffer(const IntSize& size, ImageColorSpace imageColorSpace, b case GrayScale: colorSpace.adoptCF(CGColorSpaceCreateDeviceGray()); break; -#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) +#if ((PLATFORM(MAC) || PLATFORM(CHROMIUM)) && !defined(BUILDING_ON_TIGER)) case LinearRGB: colorSpace.adoptCF(CGColorSpaceCreateWithName(kCGColorSpaceGenericRGBLinear)); break; diff --git a/WebCore/platform/graphics/chromium/GLES2Canvas.cpp b/WebCore/platform/graphics/chromium/GLES2Canvas.cpp new file mode 100644 index 0000000..ec188c8 --- /dev/null +++ b/WebCore/platform/graphics/chromium/GLES2Canvas.cpp @@ -0,0 +1,523 @@ +/* + * Copyright (c) 2010, 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" + +#if USE(GLES2_RENDERING) + +#include "GLES2Canvas.h" + +#include "FloatRect.h" +#include "GLES2Context.h" +#include "GLES2Texture.h" + +#include <GLES2/gl2.h> + +#define _USE_MATH_DEFINES +#include <math.h> + +#include <wtf/OwnArrayPtr.h> + +namespace WebCore { + +static inline void affineTo3x3(const AffineTransform& transform, GLfloat mat[9]) +{ + mat[0] = transform.a(); + mat[1] = transform.b(); + mat[2] = 0.0f; + mat[3] = transform.c(); + mat[4] = transform.d(); + mat[5] = 0.0f; + mat[6] = transform.e(); + mat[7] = transform.f(); + mat[8] = 1.0f; +} + +struct GLES2Canvas::State { + State() + : m_fillColor(0, 0, 0, 255) + , m_alpha(1.0f) + , m_compositeOp(CompositeSourceOver) + { + } + Color m_fillColor; + float m_alpha; + CompositeOperator m_compositeOp; + AffineTransform m_ctm; +}; + +GLES2Canvas::GLES2Canvas(GLES2Context* context, const IntSize& size) + : m_gles2Context(context) + , m_quadVertices(0) + , m_quadIndices(0) + , m_simpleProgram(0) + , m_texProgram(0) + , m_simpleMatrixLocation(-1) + , m_simpleColorLocation(-1) + , m_simplePositionLocation(-1) + , m_texMatrixLocation(-1) + , m_texTexMatrixLocation(-1) + , m_texSamplerLocation(-1) + , m_texAlphaLocation(-1) + , m_texPositionLocation(-1) + , m_state(0) +{ + m_flipMatrix.translate(-1.0f, 1.0f); + m_flipMatrix.scale(2.0f / size.width(), -2.0f / size.height()); + + m_gles2Context->makeCurrent(); + m_gles2Context->resizeOffscreenContent(size); + m_gles2Context->swapBuffers(); + glViewport(0, 0, size.width(), size.height()); + + m_stateStack.append(State()); + m_state = &m_stateStack.last(); +} + +GLES2Canvas::~GLES2Canvas() +{ + m_gles2Context->makeCurrent(); + if (m_simpleProgram) + glDeleteProgram(m_simpleProgram); + if (m_texProgram) + glDeleteProgram(m_texProgram); + if (m_quadVertices) + glDeleteBuffers(1, &m_quadVertices); + if (m_quadIndices) + glDeleteBuffers(1, &m_quadVertices); +} + +void GLES2Canvas::clearRect(const FloatRect& rect) +{ + m_gles2Context->makeCurrent(); + + glScissor(rect.x(), rect.y(), rect.width(), rect.height()); + glEnable(GL_SCISSOR_TEST); + glClear(GL_COLOR_BUFFER_BIT); + glDisable(GL_SCISSOR_TEST); +} + +void GLES2Canvas::fillRect(const FloatRect& rect, const Color& color, ColorSpace colorSpace) +{ + m_gles2Context->makeCurrent(); + + glBindBuffer(GL_ARRAY_BUFFER, getQuadVertices()); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, getQuadIndices()); + + float rgba[4]; + color.getRGBA(rgba[0], rgba[1], rgba[2], rgba[3]); + glUniform4f(m_simpleColorLocation, rgba[0] * rgba[3], rgba[1] * rgba[3], rgba[2] * rgba[3], rgba[3]); + + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0); +} + +void GLES2Canvas::fillRect(const FloatRect& rect) +{ + m_gles2Context->makeCurrent(); + + applyCompositeOperator(m_state->m_compositeOp); + + glBindBuffer(GL_ARRAY_BUFFER, getQuadVertices()); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, getQuadIndices()); + + glUseProgram(getSimpleProgram()); + + float rgba[4]; + m_state->m_fillColor.getRGBA(rgba[0], rgba[1], rgba[2], rgba[3]); + glUniform4f(m_simpleColorLocation, rgba[0] * rgba[3], rgba[1] * rgba[3], rgba[2] * rgba[3], rgba[3]); + + AffineTransform matrix(m_flipMatrix); + matrix.multLeft(m_state->m_ctm); + matrix.translate(rect.x(), rect.y()); + matrix.scale(rect.width(), rect.height()); + GLfloat mat[9]; + affineTo3x3(matrix, mat); + glUniformMatrix3fv(m_simpleMatrixLocation, 1, GL_FALSE, mat); + + glVertexAttribPointer(m_simplePositionLocation, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)(0)); + + glEnableVertexAttribArray(m_simplePositionLocation); + + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0); +} + +void GLES2Canvas::setFillColor(const Color& color, ColorSpace colorSpace) +{ + m_state->m_fillColor = color; +} + +void GLES2Canvas::setAlpha(float alpha) +{ + m_state->m_alpha = alpha; +} + +void GLES2Canvas::translate(float x, float y) +{ + m_state->m_ctm.translate(x, y); +} + +void GLES2Canvas::rotate(float angleInRadians) +{ + m_state->m_ctm.rotate(angleInRadians * (180.0f / M_PI)); +} + +void GLES2Canvas::scale(const FloatSize& size) +{ + m_state->m_ctm.scale(size.width(), size.height()); +} + +void GLES2Canvas::concatCTM(const AffineTransform& affine) +{ + m_state->m_ctm.multLeft(affine); +} + +void GLES2Canvas::save() +{ + m_stateStack.append(State(m_stateStack.last())); + m_state = &m_stateStack.last(); +} + +void GLES2Canvas::restore() +{ + ASSERT(!m_stateStack.isEmpty()); + m_stateStack.removeLast(); + m_state = &m_stateStack.last(); +} + +void GLES2Canvas::drawTexturedRect(GLES2Texture* texture, const FloatRect& srcRect, const FloatRect& dstRect, ColorSpace colorSpace, CompositeOperator compositeOp) +{ + drawTexturedRect(texture, srcRect, dstRect, m_state->m_ctm, m_state->m_alpha, colorSpace, compositeOp); +} + +void GLES2Canvas::drawTexturedRect(GLES2Texture* texture, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform& transform, float alpha, ColorSpace colorSpace, CompositeOperator compositeOp) +{ + m_gles2Context->makeCurrent(); + + applyCompositeOperator(compositeOp); + + glBindBuffer(GL_ARRAY_BUFFER, getQuadVertices()); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, getQuadIndices()); + checkGLError("glBindBuffer"); + + glUseProgram(getTexProgram()); + checkGLError("glUseProgram"); + + glActiveTexture(GL_TEXTURE0); + texture->bind(); + + glUniform1i(m_texSamplerLocation, 0); + checkGLError("glUniform1i"); + + glUniform1f(m_texAlphaLocation, alpha); + checkGLError("glUniform1f for alpha"); + + AffineTransform matrix(m_flipMatrix); + matrix.multLeft(transform); + matrix.translate(dstRect.x(), dstRect.y()); + matrix.scale(dstRect.width(), dstRect.height()); + GLfloat mat[9]; + affineTo3x3(matrix, mat); + glUniformMatrix3fv(m_texMatrixLocation, 1, GL_FALSE, mat); + checkGLError("glUniformMatrix3fv"); + + AffineTransform texMatrix; + texMatrix.scale(1.0f / texture->width(), 1.0f / texture->height()); + texMatrix.translate(srcRect.x(), srcRect.y()); + texMatrix.scale(srcRect.width(), srcRect.height()); + GLfloat texMat[9]; + affineTo3x3(texMatrix, texMat); + glUniformMatrix3fv(m_texTexMatrixLocation, 1, GL_FALSE, texMat); + checkGLError("glUniformMatrix3fv"); + + glVertexAttribPointer(m_texPositionLocation, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)(0)); + + glEnableVertexAttribArray(m_texPositionLocation); + + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0); + checkGLError("glDrawElements"); +} + +void GLES2Canvas::setCompositeOperation(CompositeOperator op) +{ + m_state->m_compositeOp = op; +} + +void GLES2Canvas::applyCompositeOperator(CompositeOperator op) +{ + if (op == m_lastCompositeOp) + return; + + switch (op) { + case CompositeClear: + glEnable(GL_BLEND); + glBlendFunc(GL_ZERO, GL_ZERO); + break; + case CompositeCopy: + glDisable(GL_BLEND); + break; + case CompositeSourceOver: + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + break; + case CompositeSourceIn: + glEnable(GL_BLEND); + glBlendFunc(GL_DST_ALPHA, GL_ZERO); + break; + case CompositeSourceOut: + glEnable(GL_BLEND); + glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ZERO); + break; + case CompositeSourceAtop: + glEnable(GL_BLEND); + glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + break; + case CompositeDestinationOver: + glEnable(GL_BLEND); + glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE); + break; + case CompositeDestinationIn: + glEnable(GL_BLEND); + glBlendFunc(GL_ZERO, GL_SRC_ALPHA); + break; + case CompositeDestinationOut: + glEnable(GL_BLEND); + glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA); + break; + case CompositeDestinationAtop: + glEnable(GL_BLEND); + glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA); + break; + case CompositeXOR: + glEnable(GL_BLEND); + glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + break; + case CompositePlusDarker: + case CompositeHighlight: + // unsupported + glDisable(GL_BLEND); + break; + case CompositePlusLighter: + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE); + break; + } + m_lastCompositeOp = op; +} + +unsigned GLES2Canvas::getQuadVertices() +{ + if (!m_quadVertices) { + GLfloat vertices[] = { 0.0f, 0.0f, 1.0f, + 1.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + 0.0f, 1.0f, 1.0f }; + glGenBuffers(1, &m_quadVertices); + glBindBuffer(GL_ARRAY_BUFFER, m_quadVertices); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + } + return m_quadVertices; +} + + +unsigned GLES2Canvas::getQuadIndices() +{ + if (!m_quadIndices) { + GLushort indices[] = { 0, 1, 2, 0, 2, 3}; + + glGenBuffers(1, &m_quadIndices); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_quadIndices); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); + } + return m_quadIndices; +} + +static GLuint loadShader(GLenum type, const char* shaderSource) +{ + GLuint shader = glCreateShader(type); + if (!shader) + return 0; + + glShaderSource(shader, 1, &shaderSource, 0); + glCompileShader(shader); + GLint compileStatus; + glGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus); + if (!compileStatus) { + int length; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length); + OwnArrayPtr<char> log(new char[length]); + glGetShaderInfoLog(shader, length, 0, log.get()); + LOG_ERROR(log.get()); + glDeleteShader(shader); + return 0; + } + return shader; +} + +unsigned GLES2Canvas::getSimpleProgram() +{ + if (!m_simpleProgram) { + GLuint vertexShader = loadShader(GL_VERTEX_SHADER, + "uniform mat3 matrix;\n" + "uniform vec4 color;\n" + "attribute vec3 position;\n" + "void main() {\n" + " gl_Position = vec4(matrix * position, 1.0);\n" + "}\n"); + if (!vertexShader) + return 0; + GLuint fragmentShader = loadShader(GL_FRAGMENT_SHADER, + "precision mediump float;\n" + "uniform mat3 matrix;\n" + "uniform vec4 color;\n" + "void main() {\n" + " gl_FragColor = color;\n" + "}\n"); + if (!fragmentShader) + return 0; + m_simpleProgram = glCreateProgram(); + if (!m_simpleProgram) + return 0; + glAttachShader(m_simpleProgram, vertexShader); + glAttachShader(m_simpleProgram, fragmentShader); + glLinkProgram(m_simpleProgram); + GLint linkStatus; + glGetProgramiv(m_simpleProgram, GL_LINK_STATUS, &linkStatus); + if (!linkStatus) { + glDeleteProgram(m_simpleProgram); + m_simpleProgram = 0; + } + glDeleteShader(vertexShader); + glDeleteShader(fragmentShader); + m_simplePositionLocation = glGetAttribLocation(m_simpleProgram, "position"); + m_simpleMatrixLocation = glGetUniformLocation(m_simpleProgram, "matrix"); + m_simpleColorLocation = glGetUniformLocation(m_simpleProgram, "color"); + } + return m_simpleProgram; +} + +unsigned GLES2Canvas::getTexProgram() +{ + if (!m_texProgram) { + GLuint vertexShader = loadShader(GL_VERTEX_SHADER, + "uniform mat3 matrix;\n" + "uniform mat3 texMatrix;\n" + "attribute vec3 position;\n" + "varying vec3 texCoord;\n" + "void main() {\n" + " texCoord = texMatrix * position;\n" + " gl_Position = vec4(matrix * position, 1.0);\n" + "}\n"); + if (!vertexShader) + return 0; + GLuint fragmentShader = loadShader(GL_FRAGMENT_SHADER, + "precision mediump float;\n" + "uniform sampler2D sampler;\n" + "uniform float alpha;\n" + "varying vec3 texCoord;\n" + "void main() {\n" + " gl_FragColor = texture2D(sampler, texCoord.xy)* vec4(alpha);\n" + "}\n"); + if (!fragmentShader) + return 0; + m_texProgram = glCreateProgram(); + if (!m_texProgram) + return 0; + glAttachShader(m_texProgram, vertexShader); + glAttachShader(m_texProgram, fragmentShader); + glLinkProgram(m_texProgram); + GLint linkStatus; + glGetProgramiv(m_texProgram, GL_LINK_STATUS, &linkStatus); + if (!linkStatus) { + glDeleteProgram(m_texProgram); + m_texProgram = 0; + } + glDeleteShader(vertexShader); + glDeleteShader(fragmentShader); + m_texMatrixLocation = glGetUniformLocation(m_texProgram, "matrix"); + m_texSamplerLocation = glGetUniformLocation(m_texProgram, "sampler"); + m_texTexMatrixLocation = glGetUniformLocation(m_texProgram, "texMatrix"); + m_texPositionLocation = glGetAttribLocation(m_texProgram, "position"); + m_texAlphaLocation = glGetUniformLocation(m_texProgram, "alpha"); + } + return m_texProgram; +} + +GLES2Texture* GLES2Canvas::createTexture(NativeImagePtr ptr, GLES2Texture::Format format, int width, int height) +{ + PassRefPtr<GLES2Texture> texture = m_textures.get(ptr); + if (texture) + return texture.get(); + + texture = GLES2Texture::create(format, width, height); + GLES2Texture* t = texture.get(); + m_textures.set(ptr, texture); + return t; +} + +GLES2Texture* GLES2Canvas::getTexture(NativeImagePtr ptr) +{ + PassRefPtr<GLES2Texture> texture = m_textures.get(ptr); + return texture ? texture.get() : 0; +} + +void GLES2Canvas::checkGLError(const char* header) +{ +#ifndef NDEBUG + GLenum err; + while ((err = glGetError()) != GL_NO_ERROR) { + const char* errorStr = "*** UNKNOWN ERROR ***"; + switch (err) { + case GL_INVALID_ENUM: + errorStr = "GL_INVALID_ENUM"; + break; + case GL_INVALID_VALUE: + errorStr = "GL_INVALID_VALUE"; + break; + case GL_INVALID_OPERATION: + errorStr = "GL_INVALID_OPERATION"; + break; + case GL_INVALID_FRAMEBUFFER_OPERATION: + errorStr = "GL_INVALID_FRAMEBUFFER_OPERATION"; + break; + case GL_OUT_OF_MEMORY: + errorStr = "GL_OUT_OF_MEMORY"; + break; + } + if (header) + LOG_ERROR("%s: %s", header, errorStr); + else + LOG_ERROR("%s", errorStr); + } +#endif +} + +} + +#endif diff --git a/WebCore/platform/graphics/chromium/GLES2Canvas.h b/WebCore/platform/graphics/chromium/GLES2Canvas.h new file mode 100644 index 0000000..e3a7a3b --- /dev/null +++ b/WebCore/platform/graphics/chromium/GLES2Canvas.h @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2010, 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 GLES2Canvas_h +#define GLES2Canvas_h + +#if USE(GLES2_RENDERING) + +#include "AffineTransform.h" +#include "Color.h" +#include "ColorSpace.h" +#include "GLES2Texture.h" +#include "GraphicsTypes.h" +#include "ImageSource.h" + +#include <wtf/HashMap.h> +#include <wtf/Noncopyable.h> + +namespace WebCore { + +class FloatRect; +class Color; +class GLES2Context; + +typedef HashMap<NativeImagePtr, RefPtr<GLES2Texture> > TextureHashMap; + +class GLES2Canvas : public Noncopyable { +public: + GLES2Canvas(GLES2Context*, const IntSize&); + ~GLES2Canvas(); + + void fillRect(const FloatRect&, const Color&, ColorSpace); + void fillRect(const FloatRect&); + void clearRect(const FloatRect&); + void setFillColor(const Color&, ColorSpace); + void setAlpha(float alpha); + void setCompositeOperation(CompositeOperator); + void translate(float x, float y); + void rotate(float angleInRadians); + void scale(const FloatSize&); + void concatCTM(const AffineTransform&); + + void save(); + void restore(); + + // non-standard functions + // These are not standard GraphicsContext functions, and should be pushed + // down into a PlatformContextGLES2 at some point. + void drawTexturedRect(GLES2Texture*, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform&, float alpha, ColorSpace, CompositeOperator); + void drawTexturedRect(GLES2Texture*, const FloatRect& srcRect, const FloatRect& dstRect, ColorSpace, CompositeOperator); + GLES2Context* gles2Context() { return m_gles2Context; } + GLES2Texture* createTexture(NativeImagePtr, GLES2Texture::Format, int width, int height); + GLES2Texture* getTexture(NativeImagePtr); + +private: + void applyCompositeOperator(CompositeOperator); + void checkGLError(const char* header); + unsigned getQuadVertices(); + unsigned getQuadIndices(); + unsigned getSimpleProgram(); + unsigned getTexProgram(); + + GLES2Context* m_gles2Context; + struct State; + WTF::Vector<State> m_stateStack; + State* m_state; + unsigned m_quadVertices; + unsigned m_quadIndices; + unsigned m_simpleProgram; + unsigned m_texProgram; + int m_simpleMatrixLocation; + int m_simpleColorLocation; + int m_simplePositionLocation; + int m_texMatrixLocation; + int m_texTexMatrixLocation; + int m_texSamplerLocation; + int m_texAlphaLocation; + int m_texPositionLocation; + AffineTransform m_flipMatrix; + TextureHashMap m_textures; + CompositeOperator m_lastCompositeOp; // This is the one last set, not necessarily the one in the state stack. +}; + +} + +#endif + +#endif // GLES2Canvas_h diff --git a/WebCore/platform/graphics/chromium/GLES2Texture.cpp b/WebCore/platform/graphics/chromium/GLES2Texture.cpp new file mode 100644 index 0000000..26c8bf7 --- /dev/null +++ b/WebCore/platform/graphics/chromium/GLES2Texture.cpp @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2010, 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" + +#if USE(GLES2_RENDERING) + +#include "GLES2Texture.h" + +#include <GLES2/gl2.h> + +#include <wtf/OwnArrayPtr.h> + +namespace WebCore { + +GLES2Texture::GLES2Texture(unsigned int textureId, Format format, int width, int height) + : m_textureId(textureId) + , m_format(format) + , m_width(width) + , m_height(height) +{ +} + +GLES2Texture::~GLES2Texture() +{ + glDeleteTextures(1, &m_textureId); +} + +PassRefPtr<GLES2Texture> GLES2Texture::create(Format format, int width, int height) +{ + GLuint textureId; + glGenTextures(1, &textureId); + if (!textureId) + return 0; + + glBindTexture(GL_TEXTURE_2D, textureId); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + + int max; + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max); + if (width > max || height > max) + ASSERT(!"texture too big"); + + return adoptRef(new GLES2Texture(textureId, format, width, height)); +} + +static void convertFormat(GLES2Texture::Format format, unsigned int* glFormat, unsigned int* glType, bool* swizzle) +{ + *swizzle = false; + switch (format) { + case GLES2Texture::RGBA8: + *glFormat = GL_RGBA; + *glType = GL_UNSIGNED_BYTE; + break; + case GLES2Texture::BGRA8: +// FIXME: Once we have support for extensions, we should check for EXT_texture_format_BGRA8888, +// and use that if present. + *glFormat = GL_RGBA; + *glType = GL_UNSIGNED_BYTE; + *swizzle = true; + break; + default: + ASSERT(!"bad format"); + break; + } +} + +void GLES2Texture::load(void* pixels) +{ + unsigned int glFormat, glType; + bool swizzle; + convertFormat(m_format, &glFormat, &glType, &swizzle); + glBindTexture(GL_TEXTURE_2D, m_textureId); + if (swizzle) { + ASSERT(glFormat == GL_RGBA && glType == GL_UNSIGNED_BYTE); + // FIXME: This could use PBO's to save doing an extra copy here. + int size = m_width * m_height; + unsigned* pixels32 = static_cast<unsigned*>(pixels); + OwnArrayPtr<unsigned> buf(new unsigned[size]); + unsigned* bufptr = buf.get(); + for (int i = 0; i < size; ++i) { + unsigned pixel = pixels32[i]; + bufptr[i] = pixel & 0xFF00FF00 | ((pixel & 0x00FF0000) >> 16) | ((pixel & 0x000000FF) << 16); + } + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_width, m_height, glFormat, glType, buf.get()); + } else + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_width, m_height, glFormat, glType, pixels); +} + +void GLES2Texture::bind() +{ + glBindTexture(GL_TEXTURE_2D, m_textureId); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); +} + +} + +#endif diff --git a/WebCore/platform/graphics/chromium/GLES2Texture.h b/WebCore/platform/graphics/chromium/GLES2Texture.h new file mode 100644 index 0000000..346365a --- /dev/null +++ b/WebCore/platform/graphics/chromium/GLES2Texture.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2010, 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 GLES2Texture_h +#define GLES2Texture_h + +#if USE(GLES2_RENDERING) + +#include "RefCounted.h" +#include "RefPtr.h" + +namespace WebCore { + +class GLES2Texture : public RefCounted<GLES2Texture> { +public: + ~GLES2Texture(); + enum Format { RGBA8, BGRA8 }; + static PassRefPtr<GLES2Texture> create(Format, int width, int height); + void bind(); + void load(void* pixels); + Format format() const { return m_format; } + int width() const { return m_width; } + int height() const { return m_height; } +private: + GLES2Texture(unsigned int textureId, Format format, int width, int height); + unsigned int m_textureId; + Format m_format; + int m_width; + int m_height; +}; + +} + +#endif + +#endif // GLES2Texture_h diff --git a/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp b/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp index 7869c45..7184439 100644 --- a/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp +++ b/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp @@ -1255,6 +1255,7 @@ static HashSet<String> mimeTypeCache() || g_str_equal(name, "audio/x-m4a")) { cache.add(String("video/mp4")); cache.add(String("audio/aac")); + cache.add(String("audio/mp4")); cached = true; } @@ -1270,11 +1271,13 @@ static HashSet<String> mimeTypeCache() if (g_str_equal(name, "audio/x-wav")) { cache.add(String("audio/wav")); + cache.add(String("audio/x-wav")); cached = true; } if (g_str_equal(name, "audio/mpeg")) { cache.add(String(name)); + cache.add(String("audio/x-mpeg")); cached = true; // This is what we are handling: @@ -1289,8 +1292,10 @@ static HashSet<String> mimeTypeCache() cache.add(String("audio/mp1")); if (minLayer <= 2 && 2 <= maxLayer) cache.add(String("audio/mp2")); - if (minLayer <= 3 && 3 <= maxLayer) + if (minLayer <= 3 && 3 <= maxLayer) { + cache.add(String("audio/x-mp3")); cache.add(String("audio/mp3")); + } } } } diff --git a/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp b/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp index f9e1980..6561c11 100644 --- a/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp +++ b/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp @@ -152,7 +152,7 @@ void GraphicsContext::drawConvexPolygon(size_t pointsLength, const FloatPoint* p m_data->m_view->StrokePolygon(bPoints, pointsLength, true, getHaikuStrokeStyle()); } -void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint* points) +void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint* points, bool antialiased) { if (paintingDisabled()) return; diff --git a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp index a828070..e560e15 100644 --- a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp +++ b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp @@ -529,7 +529,7 @@ void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points p->restore(); } -void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint* points) +void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint* points, bool antialiased) { if (paintingDisabled()) return; @@ -793,9 +793,11 @@ void GraphicsContext::beginPath() void GraphicsContext::addPath(const Path& path) { - QPainterPath newPath = m_data->currentPath; - newPath.addPath(path.platformPath()); - m_data->currentPath = newPath; + if (!m_data->currentPath.elementCount()) { + m_data->currentPath = path.platformPath(); + return; + } + m_data->currentPath.addPath(path.platformPath()); } bool GraphicsContext::inTransparencyLayer() const diff --git a/WebCore/platform/graphics/qt/ImageBufferQt.cpp b/WebCore/platform/graphics/qt/ImageBufferQt.cpp index b4ca617..bc25003 100644 --- a/WebCore/platform/graphics/qt/ImageBufferQt.cpp +++ b/WebCore/platform/graphics/qt/ImageBufferQt.cpp @@ -175,32 +175,53 @@ PassRefPtr<ImageData> getImageData(const IntRect& rect, const ImageBufferData& i endy = size.height(); int numRows = endy - originy; - QImage image = imageData.m_pixmap.toImage(); - if (multiplied == Unmultiplied) - image = image.convertToFormat(QImage::Format_ARGB32); - else - image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); + // NOTE: For unmultiplied data, we undo the premultiplication below. + QImage image = imageData.m_pixmap.toImage().convertToFormat(QImage::Format_ARGB32_Premultiplied); ASSERT(!image.isNull()); - unsigned destBytesPerRow = 4 * rect.width(); - unsigned char* destRows = data + desty * destBytesPerRow + destx * 4; - for (int y = 0; y < numRows; ++y) { + const int bytesPerLine = image.bytesPerLine(); #if QT_VERSION >= 0x040700 - const quint32* scanLine = reinterpret_cast<const quint32*>(image.constScanLine(y + originy)); + const uchar* bits = image.constBits(); #else - quint32* scanLine = reinterpret_cast<quint32*>(image.scanLine(y + originy)); + const uchar* bits = image.bits(); #endif - for (int x = 0; x < numColumns; x++) { - QRgb value = scanLine[x + originx]; - int basex = x * 4; - - destRows[basex] = qRed(value); - destRows[basex + 1] = qGreen(value); - destRows[basex + 2] = qBlue(value); - destRows[basex + 3] = qAlpha(value); + + quint32* destRows = reinterpret_cast<quint32*>(&data[desty * rect.width() + destx]); + + if (multiplied == Unmultiplied) { + for (int y = 0; y < numRows; ++y) { + const quint32* scanLine = reinterpret_cast<const quint32*>(bits + (y + originy) * bytesPerLine); + for (int x = 0; x < numColumns; x++) { + QRgb pixel = scanLine[x + originx]; + int alpha = qAlpha(pixel); + // Un-premultiply and convert RGB to BGR. + if (alpha == 255) + destRows[x] = (0xFF000000 + | (qBlue(pixel) << 16) + | (qGreen(pixel) << 8) + | (qRed(pixel))); + else if (alpha > 0) + destRows[x] = ((alpha << 24) + | (((255 * qBlue(pixel)) / alpha)) << 16) + | (((255 * qGreen(pixel)) / alpha) << 8) + | ((255 * qRed(pixel)) / alpha); + else + destRows[x] = 0; + } + destRows += rect.width(); + } + } else { + for (int y = 0; y < numRows; ++y) { + const quint32* scanLine = reinterpret_cast<const quint32*>(bits + (y + originy) * bytesPerLine); + for (int x = 0; x < numColumns; x++) { + QRgb pixel = scanLine[x + originx]; + // Convert RGB to BGR. + destRows[x] = ((pixel << 16) & 0xff0000) | ((pixel >> 16) & 0xff) | (pixel & 0xff00ff00); + + } + destRows += rect.width(); } - destRows += destBytesPerRow; } return result; @@ -216,6 +237,22 @@ PassRefPtr<ImageData> ImageBuffer::getPremultipliedImageData(const IntRect& rect return getImageData<Premultiplied>(rect, m_data, m_size); } +static inline unsigned int premultiplyABGRtoARGB(unsigned int x) +{ + unsigned int a = x >> 24; + if (a == 255) + return (x << 16) | ((x >> 16) & 0xff) | (x & 0xff00ff00); + unsigned int t = (x & 0xff00ff) * a; + t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8; + t = ((t << 16) | (t >> 16)) & 0xff00ff; + + x = ((x >> 8) & 0xff) * a; + x = (x + ((x >> 8) & 0xff) + 0x80); + x &= 0xff00; + x |= t | (a << 24); + return x; +} + template <Multiply multiplied> void putImageData(ImageData*& source, const IntRect& sourceRect, const IntPoint& destPoint, ImageBufferData& data, const IntSize& size) { @@ -247,22 +284,33 @@ void putImageData(ImageData*& source, const IntRect& sourceRect, const IntPoint& unsigned srcBytesPerRow = 4 * source->width(); - QRect destRect(destx, desty, endx - destx, endy - desty); - - QImage::Format format = multiplied == Unmultiplied ? QImage::Format_ARGB32 : QImage::Format_ARGB32_Premultiplied; - QImage image(destRect.size(), format); - - unsigned char* srcRows = source->data()->data()->data() + originy * srcBytesPerRow + originx * 4; - for (int y = 0; y < numRows; ++y) { - quint32* scanLine = reinterpret_cast<quint32*>(image.scanLine(y)); - for (int x = 0; x < numColumns; x++) { - // ImageData stores the pixels in RGBA while QImage is ARGB - quint32 pixel = reinterpret_cast<quint32*>(srcRows + 4 * x)[0]; - pixel = ((pixel << 16) & 0xff0000) | ((pixel >> 16) & 0xff) | (pixel & 0xff00ff00); - scanLine[x] = pixel; + // NOTE: For unmultiplied input data, we do the premultiplication below. + QImage image(numColumns, numRows, QImage::Format_ARGB32_Premultiplied); + uchar* bits = image.bits(); + const int bytesPerLine = image.bytesPerLine(); + + const quint32* srcScanLine = reinterpret_cast<const quint32*>(source->data()->data()->data() + originy * srcBytesPerRow + originx * 4); + + if (multiplied == Unmultiplied) { + for (int y = 0; y < numRows; ++y) { + quint32* destScanLine = reinterpret_cast<quint32*>(bits + y * bytesPerLine); + for (int x = 0; x < numColumns; x++) { + // Premultiply and convert BGR to RGB. + quint32 pixel = srcScanLine[x]; + destScanLine[x] = premultiplyABGRtoARGB(pixel); + } + srcScanLine += source->width(); + } + } else { + for (int y = 0; y < numRows; ++y) { + quint32* destScanLine = reinterpret_cast<quint32*>(bits + y * bytesPerLine); + for (int x = 0; x < numColumns; x++) { + // Convert BGR to RGB. + quint32 pixel = srcScanLine[x]; + destScanLine[x] = ((pixel << 16) & 0xff0000) | ((pixel >> 16) & 0xff) | (pixel & 0xff00ff00); + } + srcScanLine += source->width(); } - - srcRows += srcBytesPerRow; } bool isPainting = data.m_painter->isActive(); @@ -278,7 +326,7 @@ void putImageData(ImageData*& source, const IntRect& sourceRect, const IntPoint& } data.m_painter->setCompositionMode(QPainter::CompositionMode_Source); - data.m_painter->drawImage(destRect, image); + data.m_painter->drawImage(destx, desty, image); if (!isPainting) data.m_painter->end(); diff --git a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp b/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp index 0c1898b..7994244 100644 --- a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp +++ b/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp @@ -54,6 +54,10 @@ #include <wtf/Assertions.h> #include <wtf/MathExtras.h> +#if USE(GLES2_RENDERING) +#include "GLES2Canvas.h" +#endif + using namespace std; namespace WebCore { @@ -243,6 +247,11 @@ void GraphicsContext::savePlatformState() if (paintingDisabled()) return; +#if USE(GLES2_RENDERING) + if (platformContext()->useGPU()) + platformContext()->gpuCanvas()->save(); +#endif + // Save our private State. platformContext()->save(); } @@ -252,6 +261,11 @@ void GraphicsContext::restorePlatformState() if (paintingDisabled()) return; +#if USE(GLES2_RENDERING) + if (platformContext()->useGPU()) + platformContext()->gpuCanvas()->restore(); +#endif + // Restore our private State. platformContext()->restore(); } @@ -290,6 +304,7 @@ void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness if (!isRectSkiaSafe(getCTM(), r)) return; + platformContext()->prepareForSoftwareDraw(); SkPath path; path.addOval(r, SkPath::kCW_Direction); // only perform the inset if we won't invert r @@ -307,6 +322,7 @@ void GraphicsContext::addPath(const Path& path) { if (paintingDisabled()) return; + platformContext()->prepareForSoftwareDraw(); platformContext()->addPath(*path.platformPath()); } @@ -314,6 +330,7 @@ void GraphicsContext::beginPath() { if (paintingDisabled()) return; + platformContext()->prepareForSoftwareDraw(); platformContext()->beginPath(); } @@ -329,6 +346,16 @@ void GraphicsContext::clearRect(const FloatRect& rect) if (paintingDisabled()) return; +#if USE(GLES2_RENDERING) + if (platformContext()->useGPU()) { + platformContext()->prepareForHardwareDraw(); + platformContext()->gpuCanvas()->clearRect(rect); + return; + } +#endif + + platformContext()->prepareForSoftwareDraw(); + SkRect r = rect; if (!isRectSkiaSafe(getCTM(), r)) ClipRectToCanvas(*platformContext()->canvas(), r, &r); @@ -348,6 +375,7 @@ void GraphicsContext::clip(const FloatRect& rect) if (!isRectSkiaSafe(getCTM(), r)) return; + platformContext()->prepareForSoftwareDraw(); platformContext()->canvas()->clipRect(r); } @@ -360,6 +388,7 @@ void GraphicsContext::clip(const Path& path) if (!isPathSkiaSafe(getCTM(), p)) return; + platformContext()->prepareForSoftwareDraw(); platformContext()->clipPathAntiAliased(p); } @@ -441,6 +470,12 @@ void GraphicsContext::concatCTM(const AffineTransform& affine) { if (paintingDisabled()) return; + +#if USE(GLES2_RENDERING) + if (platformContext()->useGPU()) + platformContext()->gpuCanvas()->concatCTM(affine); +#endif + platformContext()->canvas()->concat(affine); } @@ -454,6 +489,8 @@ void GraphicsContext::drawConvexPolygon(size_t numPoints, if (numPoints <= 1) return; + platformContext()->prepareForSoftwareDraw(); + SkPath path; path.incReserve(numPoints); @@ -478,7 +515,7 @@ void GraphicsContext::drawConvexPolygon(size_t numPoints, } } -void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint* points) +void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint* points, bool antialiased) { if (paintingDisabled()) return; @@ -499,6 +536,7 @@ void GraphicsContext::drawEllipse(const IntRect& elipseRect) if (!isRectSkiaSafe(getCTM(), rect)) return; + platformContext()->prepareForSoftwareDraw(); SkPaint paint; platformContext()->setupPaintForFilling(&paint); platformContext()->canvas()->drawOval(rect, paint); @@ -524,6 +562,7 @@ void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int /* width * if (!rectCount) return; + platformContext()->prepareForSoftwareDraw(); SkRegion focusRingRegion; const SkScalar focusRingOutset = WebCoreFloatToSkScalar(0.5); for (unsigned i = 0; i < rectCount; i++) { @@ -558,6 +597,8 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2) if (!isPointSkiaSafe(getCTM(), point1) || !isPointSkiaSafe(getCTM(), point2)) return; + platformContext()->prepareForSoftwareDraw(); + FloatPoint p1 = point1; FloatPoint p2 = point2; bool isVerticalLine = (p1.x() == p2.x()); @@ -604,6 +645,8 @@ void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint& pt, if (paintingDisabled()) return; + platformContext()->prepareForSoftwareDraw(); + // Create the pattern we'll use to draw the underline. static SkBitmap* misspellBitmap = 0; if (!misspellBitmap) { @@ -684,6 +727,8 @@ void GraphicsContext::drawLineForText(const IntPoint& pt, if (width <= 0) return; + platformContext()->prepareForSoftwareDraw(); + int thickness = SkMax32(static_cast<int>(strokeThickness()), 1); SkRect r; r.fLeft = SkIntToScalar(pt.x()); @@ -704,6 +749,8 @@ void GraphicsContext::drawRect(const IntRect& rect) if (paintingDisabled()) return; + platformContext()->prepareForSoftwareDraw(); + SkRect r = rect; if (!isRectSkiaSafe(getCTM(), r)) { // See the fillRect below. @@ -722,6 +769,8 @@ void GraphicsContext::fillPath() if (!isPathSkiaSafe(getCTM(), path)) return; + platformContext()->prepareForSoftwareDraw(); + const GraphicsContextState& state = m_common->state; path.setFillType(state.fillRule == RULE_EVENODD ? SkPath::kEvenOdd_FillType : SkPath::kWinding_FillType); @@ -745,6 +794,16 @@ void GraphicsContext::fillRect(const FloatRect& rect) ClipRectToCanvas(*platformContext()->canvas(), r, &r); } +#if USE(GLES2_RENDERING) + if (platformContext()->useGPU() && !m_common->state.fillPattern && !m_common->state.fillGradient) { + platformContext()->prepareForHardwareDraw(); + platformContext()->gpuCanvas()->fillRect(rect); + return; + } +#endif + + platformContext()->prepareForSoftwareDraw(); + SkPaint paint; platformContext()->setupPaintForFilling(&paint); platformContext()->canvas()->drawRect(r, paint); @@ -757,6 +816,16 @@ void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorS if (paintingDisabled()) return; +#if USE(GLES2_RENDERING) + if (platformContext()->useGPU() && !m_common->state.fillPattern && !m_common->state.fillGradient) { + platformContext()->prepareForHardwareDraw(); + platformContext()->gpuCanvas()->fillRect(rect, color, colorSpace); + return; + } +#endif + + platformContext()->prepareForSoftwareDraw(); + SkRect r = rect; if (!isRectSkiaSafe(getCTM(), r)) { // Special case when the rectangle overflows fixed point. This is a @@ -789,6 +858,8 @@ void GraphicsContext::fillRoundedRect(const IntRect& rect, if (paintingDisabled()) return; + platformContext()->prepareForSoftwareDraw(); + SkRect r = rect; if (!isRectSkiaSafe(getCTM(), r)) // See fillRect(). @@ -872,6 +943,12 @@ void GraphicsContext::scale(const FloatSize& size) { if (paintingDisabled()) return; + +#if USE(GLES2_RENDERING) + if (platformContext()->useGPU()) + platformContext()->gpuCanvas()->scale(size); +#endif + platformContext()->canvas()->scale(WebCoreFloatToSkScalar(size.width()), WebCoreFloatToSkScalar(size.height())); } @@ -880,6 +957,10 @@ void GraphicsContext::setAlpha(float alpha) { if (paintingDisabled()) return; +#if USE(GLES2_RENDERING) + if (platformContext()->useGPU()) + platformContext()->gpuCanvas()->setAlpha(alpha); +#endif platformContext()->setAlpha(alpha); } @@ -887,6 +968,10 @@ void GraphicsContext::setCompositeOperation(CompositeOperator op) { if (paintingDisabled()) return; +#if USE(GLES2_RENDERING) + if (platformContext()->useGPU()) + platformContext()->gpuCanvas()->setCompositeOperation(op); +#endif platformContext()->setXfermodeMode(WebCoreCompositeToSkiaComposite(op)); } @@ -973,6 +1058,11 @@ void GraphicsContext::setPlatformFillColor(const Color& color, ColorSpace colorS { if (paintingDisabled()) return; +#if USE(GLES2_RENDERING) + if (platformContext()->useGPU()) + platformContext()->gpuCanvas()->setFillColor(color, colorSpace); +#endif + platformContext()->setFillColor(color.rgb()); } @@ -1102,6 +1192,8 @@ void GraphicsContext::strokeArc(const IntRect& r, int startAngle, int angleSpan) if (paintingDisabled()) return; + platformContext()->prepareForSoftwareDraw(); + SkPaint paint; SkRect oval = r; if (strokeStyle() == NoStroke) { @@ -1133,6 +1225,8 @@ void GraphicsContext::strokePath() if (!isPathSkiaSafe(getCTM(), path)) return; + platformContext()->prepareForSoftwareDraw(); + SkPaint paint; platformContext()->setupPaintForStroking(&paint, 0, 0); platformContext()->canvas()->drawPath(path, paint); @@ -1146,6 +1240,8 @@ void GraphicsContext::strokeRect(const FloatRect& rect, float lineWidth) if (!isRectSkiaSafe(getCTM(), rect)) return; + platformContext()->prepareForSoftwareDraw(); + SkPaint paint; platformContext()->setupPaintForStroking(&paint, 0, 0); paint.setStrokeWidth(WebCoreFloatToSkScalar(lineWidth)); @@ -1157,6 +1253,11 @@ void GraphicsContext::rotate(float angleInRadians) if (paintingDisabled()) return; +#if USE(GLES2_RENDERING) + if (platformContext()->useGPU()) + platformContext()->gpuCanvas()->rotate(angleInRadians); +#endif + platformContext()->canvas()->rotate(WebCoreFloatToSkScalar( angleInRadians * (180.0f / 3.14159265f))); } @@ -1166,6 +1267,11 @@ void GraphicsContext::translate(float w, float h) if (paintingDisabled()) return; +#if USE(GLES2_RENDERING) + if (platformContext()->useGPU()) + platformContext()->gpuCanvas()->translate(w, h); +#endif + platformContext()->canvas()->translate(WebCoreFloatToSkScalar(w), WebCoreFloatToSkScalar(h)); } diff --git a/WebCore/platform/graphics/skia/ImageBufferSkia.cpp b/WebCore/platform/graphics/skia/ImageBufferSkia.cpp index f8192fe..26c44f2 100644 --- a/WebCore/platform/graphics/skia/ImageBufferSkia.cpp +++ b/WebCore/platform/graphics/skia/ImageBufferSkia.cpp @@ -74,10 +74,7 @@ ImageBuffer::ImageBuffer(const IntSize& size, ImageColorSpace imageColorSpace, b // Make the background transparent. It would be nice if this wasn't // required, but the canvas is currently filled with the magic transparency // color. Can we have another way to manage this? - // - // Avoid drawing on a zero-sized canvas. Skia can't handle it. - if (!size.isZero()) - m_data.m_canvas.drawARGB(0, 0, 0, 0, SkXfermode::kClear_Mode); + m_data.m_canvas.drawARGB(0, 0, 0, 0, SkXfermode::kClear_Mode); success = true; } @@ -131,6 +128,13 @@ PassRefPtr<ImageData> getImageData(const IntRect& rect, const SkBitmap& bitmap, const IntSize& size) { RefPtr<ImageData> result = ImageData::create(rect.width(), rect.height()); + + if (bitmap.config() == SkBitmap::kNo_Config) { + // This is an empty SkBitmap that could not be configured. + ASSERT(size.width() == 0 || size.height() == 0); + return result; + } + unsigned char* data = result->data()->data()->data(); if (rect.x() < 0 || rect.y() < 0 || diff --git a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp index 15bd9b4..65c6e95 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::prepareForSoftwareDraw() 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::prepareForHardwareDraw() 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..2099dd0 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 prepareForSoftwareDraw() const; + void prepareForHardwareDraw() const; + // Call to force the skia::PlatformCanvas to contain all rendering results. + void syncSoftwareCanvas() const; +#else + void prepareForSoftwareDraw() const {} + void prepareForHardwareDraw() 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 diff --git a/WebCore/platform/graphics/wince/GraphicsContextWince.cpp b/WebCore/platform/graphics/wince/GraphicsContextWince.cpp index 5292b82..e4466c8 100644 --- a/WebCore/platform/graphics/wince/GraphicsContextWince.cpp +++ b/WebCore/platform/graphics/wince/GraphicsContextWince.cpp @@ -948,7 +948,7 @@ void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points } } -void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint* points) +void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint* points, bool antialiased) { if (paintingDisabled()) return; @@ -1160,12 +1160,12 @@ void GraphicsContext::concatCTM(const AffineTransform& transform) m_data->concatCTM(transform); } -TransformationMatrix& GraphicsContext::affineTransform() +AffineTransform& GraphicsContext::affineTransform() { return m_data->m_transform; } -const TransformationMatrix& GraphicsContext::affineTransform() const +const AffineTransform& GraphicsContext::affineTransform() const { return m_data->m_transform; } @@ -1268,8 +1268,8 @@ void GraphicsContext::fillRoundedRect(const IntRect& fillRect, const IntSize& to IntRect dstRect = fillRect; - dstRect.move(shadowSize); - dstRect.inflate(shadowBlur); + dstRect.move(stableRound(shadowSize.width()), stableRound(shadowSize.height())); + dstRect.inflate(stableRound(shadowBlur)); dstRect = m_data->mapRect(dstRect); FloatSize newTopLeft(m_data->mapSize(topLeft)); @@ -1513,7 +1513,7 @@ void GraphicsContext::fillRect(const FloatRect& r, const Gradient* gradient) int width = rect.width(); int height = rect.height(); FloatSize d = gradient->p1() - gradient->p0(); - bool vertical = abs(d.height()) > abs(d.width()); + bool vertical = fabs(d.height()) > fabs(d.width()); for (size_t i = 0; i < numStops; ++i) { const Gradient::ColorStop& stop = stops[i]; int iTv = i ? 2 * i - 1 : 0; @@ -1868,7 +1868,7 @@ void GraphicsContext::paintTextField(const IntRect& rect, unsigned state) FillRect(dc, &rectWin, reinterpret_cast<HBRUSH>(((state & DFCS_INACTIVE) ? COLOR_BTNFACE : COLOR_WINDOW) + 1)); } -void GraphicsContext::drawBitmap(SharedBitmap* bmp, const IntRect& dstRectIn, const IntRect& srcRect, CompositeOperator compositeOp) +void GraphicsContext::drawBitmap(SharedBitmap* bmp, const IntRect& dstRectIn, const IntRect& srcRect, ColorSpace styleColorSpace, CompositeOperator compositeOp) { if (!m_data->m_opacity) return; @@ -1891,7 +1891,7 @@ void GraphicsContext::drawBitmap(SharedBitmap* bmp, const IntRect& dstRectIn, co } void GraphicsContext::drawBitmapPattern(SharedBitmap* bmp, const FloatRect& tileRectIn, const AffineTransform& patternTransform, - const FloatPoint& phase, CompositeOperator op, const FloatRect& destRectIn, const IntSize& origSourceSize) + const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRectIn, const IntSize& origSourceSize) { if (!m_data->m_opacity) return; @@ -1912,7 +1912,7 @@ void GraphicsContext::drawBitmapPattern(SharedBitmap* bmp, const FloatRect& tile AffineTransform transform = m_data->m_transform; transform.translate(moved.width(), moved.height()); - bmp->drawPattern(dc, transform, tileRectIn, patternTransform, phase, op, destRectIn, origSourceSize); + bmp->drawPattern(dc, transform, tileRectIn, patternTransform, phase, styleColorSpace, op, destRectIn, origSourceSize); if (!bmp->hasAlpha()) transparentDC.fillAlphaChannel(); diff --git a/WebCore/platform/graphics/wince/ImageBufferWince.cpp b/WebCore/platform/graphics/wince/ImageBufferWince.cpp index 4b739c8..1a25f4f 100644 --- a/WebCore/platform/graphics/wince/ImageBufferWince.cpp +++ b/WebCore/platform/graphics/wince/ImageBufferWince.cpp @@ -26,8 +26,10 @@ #include "Image.h" #include "ImageData.h" #include "JPEGEncoder.h" +#include "NotImplemented.h" #include "PNGEncoder.h" #include "SharedBitmap.h" +#include "UnusedParam.h" #include <wtf/UnusedParam.h> namespace WebCore { @@ -43,24 +45,24 @@ public: virtual IntSize size() const { return IntSize(m_data->m_bitmap->width(), m_data->m_bitmap->height()); } virtual void destroyDecodedData(bool destroyAll = true) {} virtual unsigned decodedSize() const { return 0; } - virtual void draw(GraphicsContext*, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator); + virtual void draw(GraphicsContext*, const FloatRect& dstRect, const FloatRect& srcRect, ColorSpace styleColorSpace, CompositeOperator); virtual void drawPattern(GraphicsContext*, const FloatRect& srcRect, const AffineTransform& patternTransform, - const FloatPoint& phase, CompositeOperator, const FloatRect& destRect); + const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator, const FloatRect& destRect); const ImageBufferData* m_data; }; -void BufferedImage::draw(GraphicsContext* ctxt, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator compositeOp) +void BufferedImage::draw(GraphicsContext* ctxt, const FloatRect& dstRect, const FloatRect& srcRect, ColorSpace styleColorSpace, CompositeOperator compositeOp) { IntRect intDstRect = enclosingIntRect(dstRect); IntRect intSrcRect(srcRect); - m_data->m_bitmap->draw(ctxt, intDstRect, intSrcRect, compositeOp); + m_data->m_bitmap->draw(ctxt, intDstRect, intSrcRect, styleColorSpace, compositeOp); } void BufferedImage::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRectIn, const AffineTransform& patternTransform, - const FloatPoint& phase, CompositeOperator op, const FloatRect& destRect) + const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect) { - m_data->m_bitmap->drawPattern(ctxt, tileRectIn, patternTransform, phase, op, destRect, size()); + m_data->m_bitmap->drawPattern(ctxt, tileRectIn, patternTransform, phase, styleColorSpace, op, destRect, size()); } ImageBufferData::ImageBufferData(const IntSize& size) @@ -216,6 +218,12 @@ void ImageBuffer::putPremultipliedImageData(ImageData* source, const IntRect& so putImageData<true>(source, sourceRect, destPoint, m_data.m_bitmap.get()); } +void ImageBuffer::platformTransformColorSpace(const Vector<int>& lookUpTable) +{ + UNUSED_PARAM(lookUpTable); + notImplemented(); +} + String ImageBuffer::toDataURL(const String& mimeType, const double*) const { if (!m_data.m_bitmap->bytes()) diff --git a/WebCore/platform/graphics/wince/PlatformPathWince.cpp b/WebCore/platform/graphics/wince/PlatformPathWince.cpp index cde5461..b42b52c 100644 --- a/WebCore/platform/graphics/wince/PlatformPathWince.cpp +++ b/WebCore/platform/graphics/wince/PlatformPathWince.cpp @@ -671,7 +671,7 @@ void PlatformPath::addArcTo(const FloatPoint& fp1, const FloatPoint& fp2, float double d01 = v01.length(); double d21 = v21.length(); - double angle = (piDouble - abs(asin(cross / (d01 * d21)))) * 0.5; + double angle = (piDouble - fabs(asin(cross / (d01 * d21)))) * 0.5; double span = radius * tan(angle); double rate = span / d01; PathPoint startPoint; diff --git a/WebCore/platform/graphics/wx/FontPlatformDataWx.cpp b/WebCore/platform/graphics/wx/FontPlatformDataWx.cpp index 2951223..b77a03b 100644 --- a/WebCore/platform/graphics/wx/FontPlatformDataWx.cpp +++ b/WebCore/platform/graphics/wx/FontPlatformDataWx.cpp @@ -81,23 +81,23 @@ FontPlatformData::FontPlatformData(const FontDescription& desc, const AtomicStri // this is a moot issue on Linux and Mac as they only accept the point argument. So, // we use the pixel size constructor on Windows, but we use point size on Linux and Mac. #if __WXMSW__ - m_font = new FontHolder(new wxFont( wxSize(0, -desc.computedPixelSize()), + m_font = adoptRef(new FontHolder(new wxFont( wxSize(0, -desc.computedPixelSize()), fontFamilyToWxFontFamily(desc.genericFamily()), italicToWxFontStyle(desc.italic()), fontWeightToWxFontWeight(desc.weight()), false, family.string() ) - ); + )); #else - m_font = new FontHolder(new wxFont( desc.computedPixelSize(), + m_font = adoptRef(new FontHolder(new wxFont( desc.computedPixelSize(), fontFamilyToWxFontFamily(desc.genericFamily()), italicToWxFontStyle(desc.italic()), fontWeightToWxFontWeight(desc.weight()), false, family.string() ) - ); + )); #endif #if OS(DARWIN) && !defined(wxOSX_USE_CORE_TEXT) #if wxCHECK_VERSION(2,9,0) diff --git a/WebCore/platform/graphics/wx/GraphicsContextWx.cpp b/WebCore/platform/graphics/wx/GraphicsContextWx.cpp index 01dce9e..4d5afd7 100644 --- a/WebCore/platform/graphics/wx/GraphicsContextWx.cpp +++ b/WebCore/platform/graphics/wx/GraphicsContextWx.cpp @@ -256,7 +256,7 @@ void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points delete [] polygon; } -void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint* points) +void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint* points, bool antialiased) { if (paintingDisabled()) return; |