diff options
Diffstat (limited to 'WebCore/platform/graphics/gpu')
-rw-r--r-- | WebCore/platform/graphics/gpu/Shader.cpp | 111 | ||||
-rw-r--r-- | WebCore/platform/graphics/gpu/Shader.h | 58 | ||||
-rw-r--r-- | WebCore/platform/graphics/gpu/SolidFillShader.cpp | 86 | ||||
-rw-r--r-- | WebCore/platform/graphics/gpu/SolidFillShader.h | 53 | ||||
-rw-r--r-- | WebCore/platform/graphics/gpu/TexShader.cpp | 93 | ||||
-rw-r--r-- | WebCore/platform/graphics/gpu/TexShader.h | 55 | ||||
-rw-r--r-- | WebCore/platform/graphics/gpu/Texture.cpp | 180 | ||||
-rw-r--r-- | WebCore/platform/graphics/gpu/Texture.h | 63 | ||||
-rw-r--r-- | WebCore/platform/graphics/gpu/TilingData.cpp | 222 | ||||
-rw-r--r-- | WebCore/platform/graphics/gpu/TilingData.h | 87 |
10 files changed, 1008 insertions, 0 deletions
diff --git a/WebCore/platform/graphics/gpu/Shader.cpp b/WebCore/platform/graphics/gpu/Shader.cpp new file mode 100644 index 0000000..59c50a7 --- /dev/null +++ b/WebCore/platform/graphics/gpu/Shader.cpp @@ -0,0 +1,111 @@ +/* + * 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" +#include "Shader.h" + +#include "AffineTransform.h" +#include "GraphicsContext3D.h" + +#include <wtf/text/CString.h> + +namespace WebCore { + +// static +void Shader::affineTo3x3(const AffineTransform& transform, float 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; +} + +// static +unsigned Shader::loadShader(GraphicsContext3D* context, unsigned type, const char* shaderSource) +{ + unsigned shader = context->createShader(type); + if (!shader) + return 0; + + String shaderSourceStr(shaderSource); + context->shaderSource(shader, shaderSourceStr); + context->compileShader(shader); + int compileStatus; + context->getShaderiv(shader, GraphicsContext3D::COMPILE_STATUS, &compileStatus); + if (!compileStatus) { + String infoLog = context->getShaderInfoLog(shader); + LOG_ERROR("%s", infoLog.utf8().data()); + context->deleteShader(shader); + return 0; + } + return shader; +} + +// static +unsigned Shader::loadProgram(GraphicsContext3D* context, const char* vertexShaderSource, const char* fragmentShaderSource) +{ + unsigned vertexShader = loadShader(context, GraphicsContext3D::VERTEX_SHADER, vertexShaderSource); + if (!vertexShader) + return 0; + unsigned fragmentShader = loadShader(context, GraphicsContext3D::FRAGMENT_SHADER, fragmentShaderSource); + if (!fragmentShader) + return 0; + unsigned program = context->createProgram(); + if (!program) + return 0; + context->attachShader(program, vertexShader); + context->attachShader(program, fragmentShader); + context->linkProgram(program); + int linkStatus; + context->getProgramiv(program, GraphicsContext3D::LINK_STATUS, &linkStatus); + if (!linkStatus) + context->deleteProgram(program); + context->deleteShader(vertexShader); + context->deleteShader(fragmentShader); + return program; +} + +Shader::Shader(GraphicsContext3D* context, unsigned program) + : m_context(context) + , m_program(program) +{ +} + +Shader::~Shader() +{ + m_context->deleteProgram(m_program); +} + +} diff --git a/WebCore/platform/graphics/gpu/Shader.h b/WebCore/platform/graphics/gpu/Shader.h new file mode 100644 index 0000000..e5bd8de --- /dev/null +++ b/WebCore/platform/graphics/gpu/Shader.h @@ -0,0 +1,58 @@ +/* + * 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 Shader_h +#define Shader_h + +#include <wtf/Noncopyable.h> +#include <wtf/PassOwnPtr.h> + +namespace WebCore { + +class AffineTransform; +class GraphicsContext3D; +class Color; + +class Shader : public Noncopyable { +protected: + Shader(GraphicsContext3D*, unsigned program); + ~Shader(); + + static void affineTo3x3(const AffineTransform&, float mat[9]); + static unsigned loadShader(GraphicsContext3D*, unsigned type, const char* shaderSource); + static unsigned loadProgram(GraphicsContext3D*, const char* vertexShaderSource, const char* fragmentShaderSource); + + GraphicsContext3D* m_context; + unsigned m_program; +}; + +} + +#endif // Shader_h diff --git a/WebCore/platform/graphics/gpu/SolidFillShader.cpp b/WebCore/platform/graphics/gpu/SolidFillShader.cpp new file mode 100644 index 0000000..bbc4792 --- /dev/null +++ b/WebCore/platform/graphics/gpu/SolidFillShader.cpp @@ -0,0 +1,86 @@ +/* + * 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" +#include "SolidFillShader.h" + +#include "Color.h" +#include "GraphicsContext3D.h" + +namespace WebCore { + +SolidFillShader::SolidFillShader(GraphicsContext3D* context, unsigned program) + : Shader(context, program) +{ + m_matrixLocation = context->getUniformLocation(program, "matrix"); + m_colorLocation = context->getUniformLocation(program, "color"); + m_positionLocation = context->getAttribLocation(program, "position"); +} + +PassOwnPtr<SolidFillShader> SolidFillShader::create(GraphicsContext3D* context) +{ + static const char* vertexShaderSource = + "uniform mat3 matrix;\n" + "uniform vec4 color;\n" + "attribute vec3 position;\n" + "void main() {\n" + " gl_Position = vec4(matrix * position, 1.0);\n" + "}\n"; + static const char* fragmentShaderSource = + "precision mediump float;\n" + "uniform mat3 matrix;\n" + "uniform vec4 color;\n" + "void main() {\n" + " gl_FragColor = color;\n" + "}\n"; + unsigned program = loadProgram(context, vertexShaderSource, fragmentShaderSource); + if (!program) + return 0; + return new SolidFillShader(context, program); +} + +void SolidFillShader::use(const AffineTransform& transform, const Color& color) +{ + m_context->useProgram(m_program); + + float rgba[4]; + color.getRGBA(rgba[0], rgba[1], rgba[2], rgba[3]); + m_context->uniform4f(m_colorLocation, rgba[0] * rgba[3], rgba[1] * rgba[3], rgba[2] * rgba[3], rgba[3]); + + float matrix[9]; + affineTo3x3(transform, matrix); + m_context->uniformMatrix3fv(m_matrixLocation, false /*transpose*/, matrix, 1 /*count*/); + + m_context->vertexAttribPointer(m_positionLocation, 3, GraphicsContext3D::FLOAT, false, 0, 0); + + m_context->enableVertexAttribArray(m_positionLocation); +} + +} diff --git a/WebCore/platform/graphics/gpu/SolidFillShader.h b/WebCore/platform/graphics/gpu/SolidFillShader.h new file mode 100644 index 0000000..1071e73 --- /dev/null +++ b/WebCore/platform/graphics/gpu/SolidFillShader.h @@ -0,0 +1,53 @@ +/* + * 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 SolidFillShader_h +#define SolidFillShader_h + +#include "Shader.h" + +namespace WebCore { + +class SolidFillShader : public Shader { +public: + static PassOwnPtr<SolidFillShader> create(GraphicsContext3D* context); + void use(const AffineTransform& transform, const Color& color); + +private: + SolidFillShader(GraphicsContext3D* context, unsigned program); + + int m_matrixLocation; + int m_colorLocation; + int m_positionLocation; +}; + +} + +#endif // SolidFillShader_h diff --git a/WebCore/platform/graphics/gpu/TexShader.cpp b/WebCore/platform/graphics/gpu/TexShader.cpp new file mode 100644 index 0000000..ba3ecdd --- /dev/null +++ b/WebCore/platform/graphics/gpu/TexShader.cpp @@ -0,0 +1,93 @@ +/* + * 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" +#include "TexShader.h" + +#include "GraphicsContext3D.h" + +namespace WebCore { + +TexShader::TexShader(GraphicsContext3D* context, unsigned program) + : Shader(context, program) +{ + m_matrixLocation = context->getUniformLocation(program, "matrix"); + m_texMatrixLocation = context->getUniformLocation(program, "texMatrix"); + m_alphaLocation = context->getUniformLocation(program, "alpha"); + m_positionLocation = context->getAttribLocation(program, "position"); + m_samplerLocation = context->getUniformLocation(program, "sampler"); +} + +PassOwnPtr<TexShader> TexShader::create(GraphicsContext3D* context) +{ + static const char* vertexShaderSource = + "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"; + static const char* fragmentShaderSource = + "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"; + unsigned program = loadProgram(context, vertexShaderSource, fragmentShaderSource); + if (!program) + return 0; + return new TexShader(context, program); +} + +void TexShader::use(const AffineTransform& transform, const AffineTransform& texTransform, int sampler, float alpha) +{ + m_context->useProgram(m_program); + float matrix[9]; + affineTo3x3(transform, matrix); + m_context->uniformMatrix3fv(m_matrixLocation, false /*transpose*/, matrix, 1 /*count*/); + + float texMatrix[9]; + affineTo3x3(texTransform, texMatrix); + m_context->uniformMatrix3fv(m_texMatrixLocation, false /*transpose*/, texMatrix, 1 /*count*/); + + m_context->uniform1i(m_samplerLocation, sampler); + m_context->uniform1f(m_alphaLocation, alpha); + + m_context->vertexAttribPointer(m_positionLocation, 3, GraphicsContext3D::FLOAT, false, 0, 0); + + m_context->enableVertexAttribArray(m_positionLocation); + +} + +} diff --git a/WebCore/platform/graphics/gpu/TexShader.h b/WebCore/platform/graphics/gpu/TexShader.h new file mode 100644 index 0000000..535997d --- /dev/null +++ b/WebCore/platform/graphics/gpu/TexShader.h @@ -0,0 +1,55 @@ +/* + * 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 TexShader_h +#define TexShader_h + +#include "Shader.h" + +namespace WebCore { + +class TexShader : public Shader { +public: + static PassOwnPtr<TexShader> create(GraphicsContext3D* context); + void use(const AffineTransform& transform, const AffineTransform& texTransform, int sampler, float alpha); + +private: + TexShader(GraphicsContext3D* context, unsigned program); + + int m_matrixLocation; + int m_texMatrixLocation; + int m_samplerLocation; + int m_alphaLocation; + int m_positionLocation; +}; + +} + +#endif // TexShader_h diff --git a/WebCore/platform/graphics/gpu/Texture.cpp b/WebCore/platform/graphics/gpu/Texture.cpp new file mode 100644 index 0000000..557603c --- /dev/null +++ b/WebCore/platform/graphics/gpu/Texture.cpp @@ -0,0 +1,180 @@ +/* + * 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" + +#include "Texture.h" + +#include "GraphicsContext3D.h" +#include "IntRect.h" +#include <wtf/OwnArrayPtr.h> + +namespace WebCore { + + +Texture::Texture(GraphicsContext3D* context, PassOwnPtr<Vector<unsigned int> > tileTextureIds, Format format, int width, int height, int maxTextureSize) + : m_context(context) + , m_format(format) + , m_tiles(maxTextureSize, width, height, true) + , m_tileTextureIds(tileTextureIds) +{ +} + +Texture::~Texture() +{ + for (unsigned int i = 0; i < m_tileTextureIds->size(); i++) + m_context->deleteTexture(m_tileTextureIds->at(i)); +} + +static void convertFormat(GraphicsContext3D* context, Texture::Format format, unsigned int* glFormat, unsigned int* glType, bool* swizzle) +{ + *swizzle = false; + switch (format) { + case Texture::RGBA8: + *glFormat = GraphicsContext3D::RGBA; + *glType = GraphicsContext3D::UNSIGNED_BYTE; + break; + case Texture::BGRA8: + if (context->supportsBGRA()) { + *glFormat = GraphicsContext3D::BGRA_EXT; + *glType = GraphicsContext3D::UNSIGNED_BYTE; + } else { + *glFormat = GraphicsContext3D::RGBA; + *glType = GraphicsContext3D::UNSIGNED_BYTE; + *swizzle = true; + } + break; + default: + ASSERT_NOT_REACHED(); + break; + } +} + +PassRefPtr<Texture> Texture::create(GraphicsContext3D* context, Format format, int width, int height) +{ + int maxTextureSize = 0; + context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &maxTextureSize); + + TilingData tiling(maxTextureSize, width, height, true); + int numTiles = tiling.numTiles(); + + OwnPtr<Vector<unsigned int> > textureIds(new Vector<unsigned int>(numTiles)); + textureIds->fill(0, numTiles); + + for (int i = 0; i < numTiles; i++) { + int textureId = context->createTexture(); + if (!textureId) { + for (int i = 0; i < numTiles; i++) + context->deleteTexture(textureIds->at(i)); + return 0; + } + textureIds->at(i) = textureId; + + IntRect tileBoundsWithBorder = tiling.tileBoundsWithBorder(i); + + unsigned int glFormat = 0; + unsigned int glType = 0; + bool swizzle; + convertFormat(context, format, &glFormat, &glType, &swizzle); + context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId); + context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, glFormat, + tileBoundsWithBorder.width(), + tileBoundsWithBorder.height(), + 0, glFormat, glType, 0); + } + return adoptRef(new Texture(context, textureIds.leakPtr(), format, width, height, maxTextureSize)); +} + +template <bool swizzle> +static uint32_t* copySubRect(uint32_t* src, int srcX, int srcY, uint32_t* dst, int width, int height, int srcStride) +{ + uint32_t* srcOffset = src + srcX + srcY * srcStride; + + if (!swizzle && width == srcStride) + return srcOffset; + + uint32_t* dstPixel = dst; + for (int y = 0; y < height; y++) { + for (int x = 0; x < width ; x++) { + uint32_t pixel = srcOffset[x + y * srcStride]; + if (swizzle) + *dstPixel = pixel & 0xFF00FF00 | ((pixel & 0x00FF0000) >> 16) | ((pixel & 0x000000FF) << 16); + else + *dstPixel = pixel; + dstPixel++; + } + } + return dst; +} + +void Texture::load(void* pixels) +{ + uint32_t* pixels32 = static_cast<uint32_t*>(pixels); + unsigned int glFormat = 0; + unsigned int glType = 0; + bool swizzle; + convertFormat(m_context, m_format, &glFormat, &glType, &swizzle); + if (swizzle) { + ASSERT(glFormat == GraphicsContext3D::RGBA && glType == GraphicsContext3D::UNSIGNED_BYTE); + // FIXME: This could use PBO's to save doing an extra copy here. + } + OwnArrayPtr<uint32_t> tempBuff(new uint32_t[m_tiles.maxTextureSize() * m_tiles.maxTextureSize()]); + + for (int i = 0; i < m_tiles.numTiles(); i++) { + IntRect tileBoundsWithBorder = m_tiles.tileBoundsWithBorder(i); + + uint32_t* uploadBuff = 0; + if (swizzle) { + uploadBuff = copySubRect<true>( + pixels32, tileBoundsWithBorder.x(), tileBoundsWithBorder.y(), + tempBuff.get(), tileBoundsWithBorder.width(), tileBoundsWithBorder.height(), m_tiles.totalSizeX()); + } else { + uploadBuff = copySubRect<false>( + pixels32, tileBoundsWithBorder.x(), tileBoundsWithBorder.y(), + tempBuff.get(), tileBoundsWithBorder.width(), tileBoundsWithBorder.height(), m_tiles.totalSizeX()); + } + + m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_tileTextureIds->at(i)); + m_context->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, 0, 0, + tileBoundsWithBorder.width(), + tileBoundsWithBorder.height(), glFormat, glType, uploadBuff); + } +} + +void Texture::bindTile(int tile) +{ + m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_tileTextureIds->at(tile)); + m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR); + m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR); + m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE); + m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE); +} + +} diff --git a/WebCore/platform/graphics/gpu/Texture.h b/WebCore/platform/graphics/gpu/Texture.h new file mode 100644 index 0000000..7e4a72b --- /dev/null +++ b/WebCore/platform/graphics/gpu/Texture.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 Texture_h +#define Texture_h + +#include "RefCounted.h" +#include "RefPtr.h" +#include "TilingData.h" +#include <wtf/OwnPtr.h> +#include <wtf/PassOwnPtr.h> +#include <wtf/Vector.h> + +namespace WebCore { +class GraphicsContext3D; + +class Texture : public RefCounted<Texture> { +public: + ~Texture(); + enum Format { RGBA8, BGRA8 }; + static PassRefPtr<Texture> create(GraphicsContext3D*, Format, int width, int height); + void bindTile(int tile); + void load(void* pixels); + Format format() const { return m_format; } + const TilingData& tiles() const { return m_tiles; } +private: + Texture(GraphicsContext3D*, PassOwnPtr<Vector<unsigned int> > tileTextureIds, Format format, int width, int height, int maxTextureSize); + GraphicsContext3D* m_context; + Format m_format; + TilingData m_tiles; + OwnPtr<Vector<unsigned int> > m_tileTextureIds; +}; + +} + +#endif // Texture_h diff --git a/WebCore/platform/graphics/gpu/TilingData.cpp b/WebCore/platform/graphics/gpu/TilingData.cpp new file mode 100644 index 0000000..4da242b --- /dev/null +++ b/WebCore/platform/graphics/gpu/TilingData.cpp @@ -0,0 +1,222 @@ +/* + * 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" +#include "TilingData.h" + +#include "FloatRect.h" +#include "IntRect.h" +#include <algorithm> + +using namespace std; + +namespace WebCore { + +static int computeNumTiles(int maxTextureSize, int totalSize, int borderTexels) +{ + return max(1, 1 + (totalSize - 1 - 2 * borderTexels) / (maxTextureSize - 2 * borderTexels)); +} + +TilingData::TilingData(int maxTextureSize, int totalSizeX, int totalSizeY, bool hasBorderTexels) + : m_maxTextureSize(maxTextureSize) + , m_totalSizeX(totalSizeX) + , m_totalSizeY(totalSizeY) + , m_borderTexels(hasBorderTexels ? 1 : 0) +{ + m_numTilesX = computeNumTiles(maxTextureSize, m_totalSizeX, m_borderTexels); + m_numTilesY = computeNumTiles(maxTextureSize, m_totalSizeY, m_borderTexels); +} + +int TilingData::tileXIndexFromSrcCoord(int srcPos) const +{ + int x = (srcPos - m_borderTexels) / (m_maxTextureSize - 2 * m_borderTexels); + return min(max(x, 0), numTilesX() - 1); +} + +int TilingData::tileYIndexFromSrcCoord(int srcPos) const +{ + int y = (srcPos - m_borderTexels) / (m_maxTextureSize - 2 * m_borderTexels); + return min(max(y, 0), numTilesY() - 1); +} + +IntRect TilingData::tileBounds(int tile) const +{ + assertTile(tile); + int ix = tileXIndex(tile); + int iy = tileYIndex(tile); + int x = tilePositionX(ix); + int y = tilePositionY(iy); + int width = tileSizeX(ix); + int height = tileSizeY(iy); + ASSERT(x >= 0 && y >= 0 && width >= 0 && height >= 0); + ASSERT(x <= totalSizeX() && y <= totalSizeY()); + return IntRect(x, y, width, height); +} + +IntRect TilingData::tileBoundsWithBorder(int tile) const +{ + IntRect bounds = tileBounds(tile); + + if (m_borderTexels) { + int x1 = bounds.x(); + int x2 = bounds.right(); + int y1 = bounds.y(); + int y2 = bounds.bottom(); + + if (tileXIndex(tile) > 0) + x1--; + if (tileXIndex(tile) < (numTilesX() - 1)) + x2++; + if (tileYIndex(tile) > 0) + y1--; + if (tileYIndex(tile) < (numTilesY() - 1)) + y2++; + + bounds = IntRect(x1, y1, x2 - x1, y2 - y1); + } + + return bounds; +} + +FloatRect TilingData::tileBoundsNormalized(int tile) const +{ + assertTile(tile); + FloatRect bounds(tileBounds(tile)); + bounds.scale(1.0f / m_totalSizeX, 1.0f / m_totalSizeY); + return bounds; +} + +int TilingData::tilePositionX(int xIndex) const +{ + ASSERT(xIndex >= 0 && xIndex < numTilesX()); + + int pos = 0; + for (int i = 0; i < xIndex; i++) + pos += tileSizeX(i); + + return pos; +} + +int TilingData::tilePositionY(int yIndex) const +{ + ASSERT(yIndex >= 0 && yIndex < numTilesY()); + + int pos = 0; + for (int i = 0; i < yIndex; i++) + pos += tileSizeY(i); + + return pos; +} + +int TilingData::tileSizeX(int xIndex) const +{ + ASSERT(xIndex >= 0 && xIndex < numTilesX()); + + int size = maxTextureSize(); + size = min(size, totalSizeX()); + + if (!xIndex && m_numTilesX == 1) + return m_totalSizeX; + if (!xIndex && m_numTilesX > 1) + return m_maxTextureSize - m_borderTexels; + if (xIndex < numTilesX() - 1) + return m_maxTextureSize - 2 * m_borderTexels; + if (xIndex == numTilesX() - 1) + return m_totalSizeX - tilePositionX(xIndex); + + ASSERT_NOT_REACHED(); + return 0; +} + +int TilingData::tileSizeY(int yIndex) const +{ + ASSERT(yIndex >= 0 && yIndex < numTilesY()); + + int size = maxTextureSize(); + size = min(size, totalSizeY()); + + if (!yIndex && m_numTilesY == 1) + return m_totalSizeY; + if (!yIndex && m_numTilesY > 1) + return m_maxTextureSize - m_borderTexels; + if (yIndex < numTilesY() - 1) + return m_maxTextureSize - 2 * m_borderTexels; + if (yIndex == numTilesY() - 1) + return m_totalSizeY - tilePositionY(yIndex); + + ASSERT_NOT_REACHED(); + return 0; +} + +IntRect TilingData::overlappedTileIndices(const WebCore::IntRect &srcRect) const +{ + int x = tileXIndexFromSrcCoord(srcRect.x()); + int y = tileYIndexFromSrcCoord(srcRect.y()); + int r = tileXIndexFromSrcCoord(srcRect.right()); + int b = tileYIndexFromSrcCoord(srcRect.bottom()); + return IntRect(x, y, r - x, b - y); +} + +IntRect TilingData::overlappedTileIndices(const WebCore::FloatRect &srcRect) const +{ + return overlappedTileIndices(enclosingIntRect(srcRect)); +} + +void TilingData::intersectDrawQuad(const FloatRect& srcRect, const FloatRect& dstRect, int tile, + FloatRect* newSrc, FloatRect* newDst) const +{ + // Intersect with tile + FloatRect tileBounds = this->tileBounds(tile); + FloatRect srcRectIntersected = srcRect; + srcRectIntersected.intersect(tileBounds); + + if (srcRectIntersected.isEmpty()) { + *newSrc = *newDst = FloatRect(0, 0, 0, 0); + return; + } + + float srcRectIntersectedNormX = (srcRectIntersected.x() - srcRect.x()) / srcRect.width(); + float srcRectIntersectedNormY = (srcRectIntersected.y() - srcRect.y()) / srcRect.height(); + float srcRectIntersectedNormW = srcRectIntersected.width() / srcRect.width(); + float srcRectIntersectedNormH = srcRectIntersected.height() / srcRect.height(); + + *newSrc = srcRectIntersected; + newSrc->move( + -tileBounds.x() + ((tileXIndex(tile) > 0) ? m_borderTexels : 0), + -tileBounds.y() + ((tileYIndex(tile) > 0) ? m_borderTexels : 0)); + + *newDst = FloatRect( + srcRectIntersectedNormX * dstRect.width() + dstRect.x(), + srcRectIntersectedNormY * dstRect.height() + dstRect.y(), + srcRectIntersectedNormW * dstRect.width(), + srcRectIntersectedNormH * dstRect.height()); +} + +} diff --git a/WebCore/platform/graphics/gpu/TilingData.h b/WebCore/platform/graphics/gpu/TilingData.h new file mode 100644 index 0000000..f12e66e --- /dev/null +++ b/WebCore/platform/graphics/gpu/TilingData.h @@ -0,0 +1,87 @@ +/* + * 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 TilingData_h +#define TilingData_h + +#include <wtf/Noncopyable.h> + +namespace WebCore { + +class FloatRect; +class IntRect; + +class TilingData : public Noncopyable { +public: + TilingData(int maxTextureSize, int totalSizeX, int totalSizeY, bool hasBorderTexels); + int maxTextureSize() const { return m_maxTextureSize; } + int totalSizeX() const { return m_totalSizeX; } + int totalSizeY() const { return m_totalSizeY; } + + int numTiles() const { return numTilesX() * numTilesY(); } + int numTilesX() const { return m_numTilesX; } + int numTilesY() const { return m_numTilesY; } + int tileIndex(int x, int y) const { return x + y * numTilesX(); } + int tileXIndex(int tile) const { assertTile(tile); return tile % numTilesX(); } + int tileYIndex(int tile) const { assertTile(tile); return tile / numTilesX(); } + int tileXIndexFromSrcCoord(int) const; + int tileYIndexFromSrcCoord(int) const; + + IntRect tileBounds(int tile) const; + IntRect tileBoundsWithBorder(int tile) const; + FloatRect tileBoundsNormalized(int tile) const; + int tilePositionX(int xIndex) const; + int tilePositionY(int yIndex) const; + int tileSizeX(int xIndex) const; + int tileSizeY(int yIndex) const; + IntRect overlappedTileIndices(const IntRect& srcRect) const; + IntRect overlappedTileIndices(const FloatRect& srcRect) const; + + // Given a set of source and destination coordinates for a drawing quad + // in texel units, returns adjusted data to render just the one tile. + void intersectDrawQuad(const FloatRect& srcRect, const FloatRect& dstRect, int tile, FloatRect* newSrc, FloatRect* newDst) const; + +private: + TilingData() : m_maxTextureSize(0), m_totalSizeX(0), m_totalSizeY(0) {} + void assertTile(int tile) const { ASSERT(tile >= 0 && tile < numTiles()); } + + int m_maxTextureSize; + int m_totalSizeX; + int m_totalSizeY; + int m_borderTexels; // 0 or 1 + + // computed values: + int m_numTilesX; + int m_numTilesY; +}; + +} + +#endif // TilingData_h |