summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/graphics/chromium
diff options
context:
space:
mode:
authorIain Merrick <husky@google.com>2010-08-19 17:55:56 +0100
committerIain Merrick <husky@google.com>2010-08-23 11:05:40 +0100
commitf486d19d62f1bc33246748b14b14a9dfa617b57f (patch)
tree195485454c93125455a30e553a73981c3816144d /WebCore/platform/graphics/chromium
parent6ba0b43722d16bc295606bec39f396f596e4fef1 (diff)
downloadexternal_webkit-f486d19d62f1bc33246748b14b14a9dfa617b57f.zip
external_webkit-f486d19d62f1bc33246748b14b14a9dfa617b57f.tar.gz
external_webkit-f486d19d62f1bc33246748b14b14a9dfa617b57f.tar.bz2
Merge WebKit at r65615 : Initial merge by git.
Change-Id: Ifbf384f4531e3b58475a662e38195c2d9152ae79
Diffstat (limited to 'WebCore/platform/graphics/chromium')
-rw-r--r--WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp2
-rw-r--r--WebCore/platform/graphics/chromium/FontCacheLinux.cpp2
-rw-r--r--WebCore/platform/graphics/chromium/FontLinux.cpp115
-rw-r--r--WebCore/platform/graphics/chromium/FontPlatformDataChromiumWin.h2
-rw-r--r--WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp3
-rw-r--r--WebCore/platform/graphics/chromium/FontPlatformDataLinux.h2
-rw-r--r--WebCore/platform/graphics/chromium/FontUtilsChromiumWin.cpp2
-rw-r--r--WebCore/platform/graphics/chromium/GLES2Canvas.cpp46
-rw-r--r--WebCore/platform/graphics/chromium/GLES2Canvas.h1
-rw-r--r--WebCore/platform/graphics/chromium/GLES2Texture.cpp144
-rw-r--r--WebCore/platform/graphics/chromium/GLES2Texture.h16
-rw-r--r--WebCore/platform/graphics/chromium/ImageLayerChromium.cpp2
-rw-r--r--WebCore/platform/graphics/chromium/LayerChromium.cpp3
-rw-r--r--WebCore/platform/graphics/chromium/LayerChromium.h2
-rw-r--r--WebCore/platform/graphics/chromium/LayerRendererChromium.cpp3
-rwxr-xr-xWebCore/platform/graphics/chromium/TilingData.cpp218
-rwxr-xr-xWebCore/platform/graphics/chromium/TilingData.h87
17 files changed, 573 insertions, 77 deletions
diff --git a/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp b/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp
index 8ba37c6..7c3e450 100644
--- a/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp
+++ b/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp
@@ -38,8 +38,8 @@
#include "HashMap.h"
#include "HashSet.h"
#include "SimpleFontData.h"
-#include "StringHash.h"
#include <unicode/uniset.h>
+#include <wtf/text/StringHash.h>
#include <windows.h>
#include <objidl.h>
diff --git a/WebCore/platform/graphics/chromium/FontCacheLinux.cpp b/WebCore/platform/graphics/chromium/FontCacheLinux.cpp
index 53f4a52..2fda22d 100644
--- a/WebCore/platform/graphics/chromium/FontCacheLinux.cpp
+++ b/WebCore/platform/graphics/chromium/FontCacheLinux.cpp
@@ -31,7 +31,6 @@
#include "config.h"
#include "FontCache.h"
-#include "AtomicString.h"
#include "ChromiumBridge.h"
#include "Font.h"
#include "FontDescription.h"
@@ -46,6 +45,7 @@
#include <unicode/utf16.h>
#include <wtf/Assertions.h>
+#include <wtf/text/AtomicString.h>
#include <wtf/text/CString.h>
namespace WebCore {
diff --git a/WebCore/platform/graphics/chromium/FontLinux.cpp b/WebCore/platform/graphics/chromium/FontLinux.cpp
index 1953dd8..ec79b82 100644
--- a/WebCore/platform/graphics/chromium/FontLinux.cpp
+++ b/WebCore/platform/graphics/chromium/FontLinux.cpp
@@ -166,6 +166,9 @@ public:
, m_offsetX(m_startingX)
, m_run(getTextRun(run))
, m_iterateBackwards(m_run.rtl())
+ , m_wordSpacingAdjustment(0)
+ , m_padding(0)
+ , m_padError(0)
{
// Do not use |run| inside this constructor. Use |m_run| instead.
@@ -207,6 +210,56 @@ public:
delete[] m_item.string;
}
+ // setWordSpacingAdjustment sets a delta (in pixels) which is applied at
+ // each word break in the TextRun.
+ void setWordSpacingAdjustment(int wordSpacingAdjustment)
+ {
+ m_wordSpacingAdjustment = wordSpacingAdjustment;
+ }
+
+ // setLetterSpacingAdjustment sets an additional number of pixels that is
+ // added to the advance after each output cluster. This matches the behaviour
+ // of WidthIterator::advance.
+ //
+ // (NOTE: currently does nothing because I don't know how to get the
+ // cluster information from Harfbuzz.)
+ void setLetterSpacingAdjustment(int letterSpacingAdjustment)
+ {
+ m_letterSpacing = letterSpacingAdjustment;
+ }
+
+ bool isWordBreak(unsigned i, bool isRTL)
+ {
+ if (!isRTL)
+ return i && isCodepointSpace(m_item.string[i]) && !isCodepointSpace(m_item.string[i - 1]);
+ return i != m_item.stringLength - 1 && isCodepointSpace(m_item.string[i]) && !isCodepointSpace(m_item.string[i + 1]);
+ }
+
+ // setPadding sets a number of pixels to be distributed across the TextRun.
+ // WebKit uses this to justify text.
+ void setPadding(int padding)
+ {
+ m_padding = padding;
+ if (!m_padding)
+ return;
+
+ // If we have padding to distribute, then we try to give an equal
+ // amount to each space. The last space gets the smaller amount, if
+ // any.
+ unsigned numWordBreaks = 0;
+ bool isRTL = m_iterateBackwards;
+
+ for (unsigned i = 0; i < m_item.stringLength; i++) {
+ if (isWordBreak(i, isRTL))
+ numWordBreaks++;
+ }
+
+ if (numWordBreaks)
+ m_padPerWordBreak = m_padding / numWordBreaks;
+ else
+ m_padPerWordBreak = 0;
+ }
+
void reset()
{
if (m_iterateBackwards)
@@ -453,8 +506,15 @@ private:
void setGlyphXPositions(bool isRTL)
{
double position = 0;
+ // logClustersIndex indexes logClusters for the first (or last when
+ // RTL) codepoint of the current glyph. Each time we advance a glyph,
+ // we skip over all the codepoints that contributed to the current
+ // glyph.
+ unsigned logClustersIndex = isRTL ? m_item.num_glyphs - 1 : 0;
+
for (int iter = 0; iter < m_item.num_glyphs; ++iter) {
- // Glyphs are stored in logical order, but for layout purposes we always go left to right.
+ // Glyphs are stored in logical order, but for layout purposes we
+ // always go left to right.
int i = isRTL ? m_item.num_glyphs - iter - 1 : iter;
m_glyphs16[i] = m_item.glyphs[i];
@@ -462,12 +522,48 @@ private:
m_xPositions[i] = m_offsetX + position + offsetX;
double advance = truncateFixedPointToInteger(m_item.advances[i]);
+ unsigned glyphIndex = m_item.item.pos + logClustersIndex;
+ if (isWordBreak(glyphIndex, isRTL)) {
+ advance += m_wordSpacingAdjustment;
+
+ if (m_padding > 0) {
+ unsigned toPad = roundf(m_padPerWordBreak + m_padError);
+ m_padError += m_padPerWordBreak - toPad;
+
+ if (m_padding < toPad)
+ toPad = m_padding;
+ m_padding -= toPad;
+ advance += toPad;
+ }
+ }
+
+ // We would like to add m_letterSpacing after each cluster, but I
+ // don't know where the cluster information is. This is typically
+ // fine for Roman languages, but breaks more complex languages
+ // terribly.
+ // advance += m_letterSpacing;
+
+ if (isRTL) {
+ while (logClustersIndex > 0 && logClusters()[logClustersIndex] == i)
+ logClustersIndex--;
+ } else {
+ while (logClustersIndex < m_item.num_glyphs && logClusters()[logClustersIndex] == i)
+ logClustersIndex++;
+ }
+
position += advance;
}
+
m_pixelWidth = position;
m_offsetX += m_pixelWidth;
}
+ static bool isCodepointSpace(HB_UChar16 c)
+ {
+ // This matches the logic in RenderBlock::findNextLineBreak
+ return c == ' ' || c == '\t';
+ }
+
void mirrorCharacters(UChar* destination, const UChar* source, int length) const
{
int position = 0;
@@ -498,6 +594,14 @@ private:
OwnArrayPtr<UChar> m_normalizedBuffer; // A buffer for normalized run.
const TextRun& m_run;
bool m_iterateBackwards;
+ int m_wordSpacingAdjustment; // delta adjustment (pixels) for each word break.
+ float m_padding; // pixels to be distributed over the line at word breaks.
+ float m_padPerWordBreak; // pixels to be added to each word break.
+ float m_padError; // |m_padPerWordBreak| might have a fractional component.
+ // Since we only add a whole number of padding pixels at
+ // each word break we accumulate error. This is the
+ // number of pixels that we are behind so far.
+ unsigned m_letterSpacing; // pixels to be added after each glyph.
};
static void setupForTextPainting(SkPaint* paint, SkColor color)
@@ -534,6 +638,9 @@ void Font::drawComplexText(GraphicsContext* gc, const TextRun& run,
TextRunWalker walker(run, point.x(), this);
bool haveMultipleLayers = isCanvasMultiLayered(canvas);
+ walker.setWordSpacingAdjustment(wordSpacing());
+ walker.setLetterSpacingAdjustment(letterSpacing());
+ walker.setPadding(run.padding());
while (walker.nextScriptRun()) {
if (fill) {
@@ -553,6 +660,8 @@ void Font::drawComplexText(GraphicsContext* gc, const TextRun& run,
float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* /* fallbackFonts */, GlyphOverflow* /* glyphOverflow */) const
{
TextRunWalker walker(run, 0, this);
+ walker.setWordSpacingAdjustment(wordSpacing());
+ walker.setLetterSpacingAdjustment(letterSpacing());
return walker.widthOfFullRun();
}
@@ -588,6 +697,8 @@ int Font::offsetForPositionForComplexText(const TextRun& run, float xFloat,
// (Mac code ignores includePartialGlyphs, and they don't know what it's
// supposed to do, so we just ignore it as well.)
TextRunWalker walker(run, 0, this);
+ walker.setWordSpacingAdjustment(wordSpacing());
+ walker.setLetterSpacingAdjustment(letterSpacing());
// If this is RTL text, the first glyph from the left is actually the last
// code point. So we need to know how many code points there are total in
@@ -664,6 +775,8 @@ FloatRect Font::selectionRectForComplexText(const TextRun& run,
{
int fromX = -1, toX = -1, fromAdvance = -1, toAdvance = -1;
TextRunWalker walker(run, 0, this);
+ walker.setWordSpacingAdjustment(wordSpacing());
+ walker.setLetterSpacingAdjustment(letterSpacing());
// Base will point to the x offset for the current script run. Note that, in
// the LTR case, width will be 0.
diff --git a/WebCore/platform/graphics/chromium/FontPlatformDataChromiumWin.h b/WebCore/platform/graphics/chromium/FontPlatformDataChromiumWin.h
index 1d6cc8e..beac0bf 100644
--- a/WebCore/platform/graphics/chromium/FontPlatformDataChromiumWin.h
+++ b/WebCore/platform/graphics/chromium/FontPlatformDataChromiumWin.h
@@ -34,10 +34,10 @@
#include "config.h"
-#include "StringImpl.h"
#include <wtf/Forward.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
+#include <wtf/text/StringImpl.h>
#include <usp10.h>
diff --git a/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp b/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp
index 9b54732..b51eb8c 100644
--- a/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp
+++ b/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp
@@ -35,11 +35,12 @@
#include "HarfbuzzSkia.h"
#include "NotImplemented.h"
#include "PlatformString.h"
-#include "StringImpl.h"
#include "SkPaint.h"
#include "SkTypeface.h"
+#include <wtf/text/StringImpl.h>
+
namespace WebCore {
static SkPaint::Hinting skiaHinting = SkPaint::kNormal_Hinting;
diff --git a/WebCore/platform/graphics/chromium/FontPlatformDataLinux.h b/WebCore/platform/graphics/chromium/FontPlatformDataLinux.h
index de12832..363e55f 100644
--- a/WebCore/platform/graphics/chromium/FontPlatformDataLinux.h
+++ b/WebCore/platform/graphics/chromium/FontPlatformDataLinux.h
@@ -32,10 +32,10 @@
#define FontPlatformDataLinux_h
#include "FontRenderStyle.h"
-#include "StringImpl.h"
#include <wtf/Forward.h>
#include <wtf/RefPtr.h>
#include <wtf/text/CString.h>
+#include <wtf/text/StringImpl.h>
#include <SkPaint.h>
class SkTypeface;
diff --git a/WebCore/platform/graphics/chromium/FontUtilsChromiumWin.cpp b/WebCore/platform/graphics/chromium/FontUtilsChromiumWin.cpp
index 78170a9..e725c50 100644
--- a/WebCore/platform/graphics/chromium/FontUtilsChromiumWin.cpp
+++ b/WebCore/platform/graphics/chromium/FontUtilsChromiumWin.cpp
@@ -34,11 +34,11 @@
#include <limits>
#include "PlatformString.h"
-#include "StringHash.h"
#include "UniscribeHelper.h"
#include <unicode/locid.h>
#include <unicode/uchar.h>
#include <wtf/HashMap.h>
+#include <wtf/text/StringHash.h>
namespace WebCore {
diff --git a/WebCore/platform/graphics/chromium/GLES2Canvas.cpp b/WebCore/platform/graphics/chromium/GLES2Canvas.cpp
index 8a9bde1..534de7b 100644
--- a/WebCore/platform/graphics/chromium/GLES2Canvas.cpp
+++ b/WebCore/platform/graphics/chromium/GLES2Canvas.cpp
@@ -38,14 +38,15 @@
#include "FloatRect.h"
#include "GLES2Texture.h"
#include "GraphicsContext3D.h"
+#include "IntRect.h"
#include "PlatformString.h"
#include "Uint16Array.h"
#define _USE_MATH_DEFINES
#include <math.h>
-#include <wtf/text/CString.h>
#include <wtf/OwnArrayPtr.h>
+#include <wtf/text/CString.h>
namespace WebCore {
@@ -221,7 +222,6 @@ void GLES2Canvas::drawTexturedRect(GLES2Texture* texture, const FloatRect& srcRe
checkGLError("glUseProgram");
m_context->activeTexture(GraphicsContext3D::TEXTURE0);
- texture->bind();
m_context->uniform1i(m_texSamplerLocation, 0);
checkGLError("glUniform1i");
@@ -229,28 +229,52 @@ void GLES2Canvas::drawTexturedRect(GLES2Texture* texture, const FloatRect& srcRe
m_context->uniform1f(m_texAlphaLocation, alpha);
checkGLError("glUniform1f for alpha");
+ m_context->vertexAttribPointer(m_texPositionLocation, 3, GraphicsContext3D::FLOAT, false, 0, 0);
+
+ m_context->enableVertexAttribArray(m_texPositionLocation);
+
+ const TilingData& tiles = texture->tiles();
+ IntRect tileIdxRect = tiles.overlappedTileIndices(srcRect);
+
+ for (int y = tileIdxRect.y(); y <= tileIdxRect.bottom(); y++) {
+ for (int x = tileIdxRect.x(); x <= tileIdxRect.right(); x++)
+ drawTexturedRectTile(texture, tiles.tileIndex(x, y), srcRect, dstRect, transform);
+ }
+}
+
+void GLES2Canvas::drawTexturedRectTile(GLES2Texture* texture, int tile, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform& transform)
+{
+ if (dstRect.isEmpty())
+ return;
+
+ const TilingData& tiles = texture->tiles();
+
+ texture->bindTile(tile);
+
+ FloatRect srcRectClippedInTileSpace;
+ FloatRect dstRectIntersected;
+ tiles.intersectDrawQuad(srcRect, dstRect, tile, &srcRectClippedInTileSpace, &dstRectIntersected);
+
+ IntRect tileBoundsWithBorder = tiles.tileBoundsWithBorder(tile);
+
AffineTransform matrix(m_flipMatrix);
matrix.multLeft(transform);
- matrix.translate(dstRect.x(), dstRect.y());
- matrix.scale(dstRect.width(), dstRect.height());
+ matrix.translate(dstRectIntersected.x(), dstRectIntersected.y());
+ matrix.scale(dstRectIntersected.width(), dstRectIntersected.height());
float mat[9];
affineTo3x3(matrix, mat);
m_context->uniformMatrix3fv(m_texMatrixLocation, false /*transpose*/, mat, 1 /*count*/);
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());
+ texMatrix.scale(1.0f / tileBoundsWithBorder.width(), 1.0f / tileBoundsWithBorder.height());
+ texMatrix.translate(srcRectClippedInTileSpace.x(), srcRectClippedInTileSpace.y());
+ texMatrix.scale(srcRectClippedInTileSpace.width(), srcRectClippedInTileSpace.height());
float texMat[9];
affineTo3x3(texMatrix, texMat);
m_context->uniformMatrix3fv(m_texTexMatrixLocation, false /*transpose*/, texMat, 1 /*count*/);
checkGLError("glUniformMatrix3fv");
- m_context->vertexAttribPointer(m_texPositionLocation, 3, GraphicsContext3D::FLOAT, false, 0, 0);
-
- m_context->enableVertexAttribArray(m_texPositionLocation);
-
m_context->drawElements(GraphicsContext3D::TRIANGLES, 6, GraphicsContext3D::UNSIGNED_SHORT, 0);
checkGLError("glDrawElements");
}
diff --git a/WebCore/platform/graphics/chromium/GLES2Canvas.h b/WebCore/platform/graphics/chromium/GLES2Canvas.h
index cea90ae..0ad07fc 100644
--- a/WebCore/platform/graphics/chromium/GLES2Canvas.h
+++ b/WebCore/platform/graphics/chromium/GLES2Canvas.h
@@ -81,6 +81,7 @@ public:
GLES2Texture* getTexture(NativeImagePtr);
private:
+ void drawTexturedRectTile(GLES2Texture* texture, int tile, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform&);
void applyCompositeOperator(CompositeOperator);
void checkGLError(const char* header);
unsigned getQuadVertices();
diff --git a/WebCore/platform/graphics/chromium/GLES2Texture.cpp b/WebCore/platform/graphics/chromium/GLES2Texture.cpp
index 5e8a141..ae230db 100644
--- a/WebCore/platform/graphics/chromium/GLES2Texture.cpp
+++ b/WebCore/platform/graphics/chromium/GLES2Texture.cpp
@@ -35,45 +35,27 @@
#include "GLES2Texture.h"
#include "GraphicsContext3D.h"
-
+#include "IntRect.h"
#include <wtf/OwnArrayPtr.h>
namespace WebCore {
-GLES2Texture::GLES2Texture(GraphicsContext3D* context, unsigned textureId, Format format, int width, int height)
+
+GLES2Texture::GLES2Texture(GraphicsContext3D* context, PassOwnPtr<Vector<unsigned int> > tileTextureIds, Format format, int width, int height, int maxTextureSize)
: m_context(context)
- , m_textureId(textureId)
, m_format(format)
- , m_width(width)
- , m_height(height)
+ , m_tiles(maxTextureSize, width, height, true)
+ , m_tileTextureIds(tileTextureIds)
{
}
GLES2Texture::~GLES2Texture()
{
- m_context->deleteTexture(m_textureId);
-}
-
-PassRefPtr<GLES2Texture> GLES2Texture::create(GraphicsContext3D* context, Format format, int width, int height)
-{
- int max;
- context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &max);
- if (width > max || height > max) {
- ASSERT(!"texture too big");
- return 0;
- }
-
- unsigned textureId = context->createTexture();
- if (!textureId)
- return 0;
-
- context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId);
- context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, width, height, 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, 0);
-
- return adoptRef(new GLES2Texture(context, textureId, format, width, height));
+ for (unsigned int i = 0; i < m_tileTextureIds->size(); i++)
+ m_context->deleteTexture(m_tileTextureIds->at(i));
}
-static void convertFormat(GLES2Texture::Format format, unsigned int* glFormat, unsigned int* glType, bool* swizzle)
+static void convertFormat(GraphicsContext3D* context, GLES2Texture::Format format, unsigned int* glFormat, unsigned int* glType, bool* swizzle)
{
*swizzle = false;
switch (format) {
@@ -82,43 +64,113 @@ static void convertFormat(GLES2Texture::Format format, unsigned int* glFormat, u
*glType = GraphicsContext3D::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 = GraphicsContext3D::RGBA;
- *glType = GraphicsContext3D::UNSIGNED_BYTE;
- *swizzle = true;
+ if (context->supportsBGRA()) {
+ *glFormat = GraphicsContext3D::BGRA_EXT;
+ *glType = GraphicsContext3D::UNSIGNED_BYTE;
+ } else {
+ *glFormat = GraphicsContext3D::RGBA;
+ *glType = GraphicsContext3D::UNSIGNED_BYTE;
+ *swizzle = true;
+ }
break;
default:
- ASSERT(!"bad format");
+ ASSERT_NOT_REACHED();
break;
}
}
+PassRefPtr<GLES2Texture> GLES2Texture::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, glType;
+ 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 GLES2Texture(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 GLES2Texture::load(void* pixels)
{
+ uint32_t* pixels32 = static_cast<uint32_t*>(pixels);
unsigned int glFormat, glType;
bool swizzle;
- convertFormat(m_format, &glFormat, &glType, &swizzle);
- m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textureId);
+ 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.
- 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);
+ }
+ 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->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, 0, 0, m_width, m_height, glFormat, glType, buf.get());
- } else
- m_context->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, 0, 0, m_width, m_height, glFormat, glType, pixels);
+
+ 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 GLES2Texture::bind()
+void GLES2Texture::bindTile(int tile)
{
- m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textureId);
+ 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);
diff --git a/WebCore/platform/graphics/chromium/GLES2Texture.h b/WebCore/platform/graphics/chromium/GLES2Texture.h
index 4d351cd..43a4955 100644
--- a/WebCore/platform/graphics/chromium/GLES2Texture.h
+++ b/WebCore/platform/graphics/chromium/GLES2Texture.h
@@ -35,6 +35,10 @@
#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;
@@ -44,18 +48,16 @@ public:
~GLES2Texture();
enum Format { RGBA8, BGRA8 };
static PassRefPtr<GLES2Texture> create(GraphicsContext3D*, Format, int width, int height);
- void bind();
+ void bindTile(int tile);
void load(void* pixels);
Format format() const { return m_format; }
- int width() const { return m_width; }
- int height() const { return m_height; }
+ const TilingData& tiles() const { return m_tiles; }
private:
- GLES2Texture(GraphicsContext3D*, unsigned textureId, Format, int width, int height);
+ GLES2Texture(GraphicsContext3D*, PassOwnPtr<Vector<unsigned int> > tileTextureIds, Format format, int width, int height, int maxTextureSize);
GraphicsContext3D* m_context;
- unsigned m_textureId;
Format m_format;
- int m_width;
- int m_height;
+ TilingData m_tiles;
+ OwnPtr<Vector<unsigned int> > m_tileTextureIds;
};
}
diff --git a/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp b/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp
index 9f6ee17..3cc7cad 100644
--- a/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp
+++ b/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp
@@ -114,7 +114,7 @@ void ImageLayerChromium::updateTextureContents(unsigned textureId)
case kCGColorSpaceModelDeviceN:
break;
default:
- colorSpace.adoptCF(CGColorSpaceCreateWithName(kCGColorSpaceGenericRGBLinear));
+ colorSpace.adoptCF(CGColorSpaceCreateDeviceRGB());
break;
}
RetainPtr<CGContextRef> tempContext(AdoptCF, CGBitmapContextCreate(tempVector.data(),
diff --git a/WebCore/platform/graphics/chromium/LayerChromium.cpp b/WebCore/platform/graphics/chromium/LayerChromium.cpp
index bba65f4..21d8d12 100644
--- a/WebCore/platform/graphics/chromium/LayerChromium.cpp
+++ b/WebCore/platform/graphics/chromium/LayerChromium.cpp
@@ -180,8 +180,7 @@ void LayerChromium::updateTextureContents(unsigned textureId)
int rowBytes = 4 * dirtyRect.width();
tempVector.resize(rowBytes * dirtyRect.height());
memset(tempVector.data(), 0, tempVector.size());
- // FIXME: unsure whether this is the best color space choice.
- RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateWithName(kCGColorSpaceGenericRGBLinear));
+ RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB());
RetainPtr<CGContextRef> contextCG(AdoptCF, CGBitmapContextCreate(tempVector.data(),
dirtyRect.width(), dirtyRect.height(), 8, rowBytes,
colorSpace.get(),
diff --git a/WebCore/platform/graphics/chromium/LayerChromium.h b/WebCore/platform/graphics/chromium/LayerChromium.h
index ebb4504..9fba415 100644
--- a/WebCore/platform/graphics/chromium/LayerChromium.h
+++ b/WebCore/platform/graphics/chromium/LayerChromium.h
@@ -38,12 +38,12 @@
#include "GraphicsContext.h"
#include "GraphicsLayerChromium.h"
#include "PlatformString.h"
-#include "StringHash.h"
#include "TransformationMatrix.h"
#include <wtf/OwnPtr.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
#include <wtf/Vector.h>
+#include <wtf/text/StringHash.h>
namespace skia {
diff --git a/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp b/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
index 15acfa5..2f70efa 100644
--- a/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
+++ b/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
@@ -255,8 +255,7 @@ void LayerRendererChromium::setRootLayerCanvasSize(const IntSize& size)
int rowBytes = 4 * size.width();
m_rootLayerBackingStore.resize(rowBytes * size.height());
memset(m_rootLayerBackingStore.data(), 0, m_rootLayerBackingStore.size());
- // FIXME: unsure whether this is the best color space choice.
- RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateWithName(kCGColorSpaceGenericRGBLinear));
+ RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB());
m_rootLayerCGContext.adoptCF(CGBitmapContextCreate(m_rootLayerBackingStore.data(),
size.width(), size.height(), 8, rowBytes,
colorSpace.get(),
diff --git a/WebCore/platform/graphics/chromium/TilingData.cpp b/WebCore/platform/graphics/chromium/TilingData.cpp
new file mode 100755
index 0000000..c52288d
--- /dev/null
+++ b/WebCore/platform/graphics/chromium/TilingData.cpp
@@ -0,0 +1,218 @@
+/*
+ * 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());
+
+ if (!xIndex)
+ return 0;
+ return tilePositionX(xIndex - 1) + tileSizeX(xIndex - 1);
+}
+
+int TilingData::tilePositionY(int yIndex) const
+{
+ ASSERT(yIndex >= 0 && yIndex < numTilesY());
+
+ if (!yIndex)
+ return 0;
+ return tilePositionX(yIndex - 1) + tileSizeY(yIndex - 1);
+}
+
+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/chromium/TilingData.h b/WebCore/platform/graphics/chromium/TilingData.h
new file mode 100755
index 0000000..f12e66e
--- /dev/null
+++ b/WebCore/platform/graphics/chromium/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