summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform/graphics/chromium
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2011-05-24 11:24:40 +0100
committerBen Murdoch <benm@google.com>2011-06-02 09:53:15 +0100
commit81bc750723a18f21cd17d1b173cd2a4dda9cea6e (patch)
tree7a9e5ed86ff429fd347a25153107221543909b19 /Source/WebCore/platform/graphics/chromium
parent94088a6d336c1dd80a1e734af51e96abcbb689a7 (diff)
downloadexternal_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.zip
external_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.tar.gz
external_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.tar.bz2
Merge WebKit at r80534: Intial merge by Git
Change-Id: Ia7a83357124c9e1cdb1debf55d9661ec0bd09a61
Diffstat (limited to 'Source/WebCore/platform/graphics/chromium')
-rw-r--r--Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h2
-rw-r--r--Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp74
-rw-r--r--Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.h24
-rw-r--r--Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp283
-rw-r--r--Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h41
-rw-r--r--Source/WebCore/platform/graphics/chromium/Extensions3DChromium.h4
-rw-r--r--Source/WebCore/platform/graphics/chromium/FontCacheLinux.cpp4
-rw-r--r--Source/WebCore/platform/graphics/chromium/GLES2Canvas.cpp85
-rw-r--r--Source/WebCore/platform/graphics/chromium/GLES2Canvas.h6
-rw-r--r--Source/WebCore/platform/graphics/chromium/GeometryBinding.cpp82
-rw-r--r--Source/WebCore/platform/graphics/chromium/GeometryBinding.h67
-rw-r--r--Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp14
-rw-r--r--Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h3
-rw-r--r--Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp91
-rw-r--r--Source/WebCore/platform/graphics/chromium/ImageLayerChromium.h9
-rw-r--r--Source/WebCore/platform/graphics/chromium/LayerChromium.cpp303
-rw-r--r--Source/WebCore/platform/graphics/chromium/LayerChromium.h141
-rw-r--r--Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp452
-rw-r--r--Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h87
-rw-r--r--Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp196
-rw-r--r--Source/WebCore/platform/graphics/chromium/LayerTilerChromium.h26
-rw-r--r--Source/WebCore/platform/graphics/chromium/PlatformCanvas.cpp116
-rw-r--r--Source/WebCore/platform/graphics/chromium/PlatformCanvas.h109
-rw-r--r--Source/WebCore/platform/graphics/chromium/PlatformImage.cpp111
-rw-r--r--Source/WebCore/platform/graphics/chromium/PlatformImage.h53
-rw-r--r--Source/WebCore/platform/graphics/chromium/PluginLayerChromium.cpp68
-rw-r--r--Source/WebCore/platform/graphics/chromium/PluginLayerChromium.h23
-rw-r--r--Source/WebCore/platform/graphics/chromium/ProgramBinding.cpp123
-rw-r--r--Source/WebCore/platform/graphics/chromium/ProgramBinding.h85
-rw-r--r--Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp140
-rw-r--r--Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h53
-rw-r--r--Source/WebCore/platform/graphics/chromium/ShaderChromium.cpp317
-rw-r--r--Source/WebCore/platform/graphics/chromium/ShaderChromium.h188
-rw-r--r--Source/WebCore/platform/graphics/chromium/TextureManager.cpp2
-rw-r--r--Source/WebCore/platform/graphics/chromium/VideoFrameChromium.h3
-rw-r--r--Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp207
-rw-r--r--Source/WebCore/platform/graphics/chromium/VideoLayerChromium.h46
-rw-r--r--Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp1
-rw-r--r--Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.h5
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp172
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.h79
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp197
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h164
43 files changed, 2873 insertions, 1383 deletions
diff --git a/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h b/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h
index 44ef050..a14cb98 100644
--- a/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h
@@ -45,7 +45,7 @@ class Canvas2DLayerChromium : public CanvasLayerChromium {
public:
static PassRefPtr<Canvas2DLayerChromium> create(DrawingBuffer*, GraphicsLayerChromium* owner);
virtual ~Canvas2DLayerChromium();
- virtual bool drawsContent() { return true; }
+ virtual bool drawsContent() const { return true; }
virtual void updateContentsIfDirty();
void setTextureChanged();
diff --git a/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp
index 4aef25b..0264868 100644
--- a/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp
@@ -34,6 +34,7 @@
#include "CanvasLayerChromium.h"
+#include "cc/CCLayerImpl.h"
#include "GraphicsContext3D.h"
#include "LayerRendererChromium.h"
@@ -41,64 +42,11 @@ namespace WebCore {
unsigned CanvasLayerChromium::m_shaderProgramId = 0;
-CanvasLayerChromium::SharedValues::SharedValues(GraphicsContext3D* context)
- : m_context(context)
- , m_canvasShaderProgram(0)
- , m_shaderSamplerLocation(-1)
- , m_shaderMatrixLocation(-1)
- , m_shaderAlphaLocation(-1)
- , m_initialized(false)
-{
- char vertexShaderString[] =
- "attribute vec4 a_position; \n"
- "attribute vec2 a_texCoord; \n"
- "uniform mat4 matrix; \n"
- "varying vec2 v_texCoord; \n"
- "void main() \n"
- "{ \n"
- " gl_Position = matrix * a_position; \n"
- " v_texCoord = a_texCoord; \n"
- "} \n";
-
- // Canvas layers need to be flipped vertically and their colors shouldn't be
- // swizzled.
- char fragmentShaderString[] =
- "precision mediump float; \n"
- "varying vec2 v_texCoord; \n"
- "uniform sampler2D s_texture; \n"
- "uniform float alpha; \n"
- "void main() \n"
- "{ \n"
- " vec4 texColor = texture2D(s_texture, vec2(v_texCoord.x, 1.0 - v_texCoord.y)); \n"
- " gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha; \n"
- "} \n";
-
- m_canvasShaderProgram = createShaderProgram(m_context, vertexShaderString, fragmentShaderString);
- if (!m_canvasShaderProgram) {
- LOG_ERROR("CanvasLayerChromium: Failed to create shader program");
- return;
- }
-
- m_shaderSamplerLocation = m_context->getUniformLocation(m_canvasShaderProgram, "s_texture");
- m_shaderMatrixLocation = m_context->getUniformLocation(m_canvasShaderProgram, "matrix");
- m_shaderAlphaLocation = m_context->getUniformLocation(m_canvasShaderProgram, "alpha");
- ASSERT(m_shaderSamplerLocation != -1);
- ASSERT(m_shaderMatrixLocation != -1);
- ASSERT(m_shaderAlphaLocation != -1);
-
- m_initialized = true;
-}
-
-CanvasLayerChromium::SharedValues::~SharedValues()
-{
- if (m_canvasShaderProgram)
- GLC(m_context, m_context->deleteProgram(m_canvasShaderProgram));
-}
-
CanvasLayerChromium::CanvasLayerChromium(GraphicsLayerChromium* owner)
: LayerChromium(owner)
, m_textureChanged(true)
, m_textureId(0)
+ , m_premultipliedAlpha(true)
{
}
@@ -109,17 +57,19 @@ CanvasLayerChromium::~CanvasLayerChromium()
void CanvasLayerChromium::draw()
{
ASSERT(layerRenderer());
- const CanvasLayerChromium::SharedValues* sv = layerRenderer()->canvasLayerSharedValues();
- ASSERT(sv && sv->initialized());
+ const CanvasLayerChromium::Program* program = layerRenderer()->canvasLayerProgram();
+ ASSERT(program && program->initialized());
GraphicsContext3D* context = layerRendererContext();
GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textureId));
- layerRenderer()->useShader(sv->canvasShaderProgram());
- GLC(context, context->uniform1i(sv->shaderSamplerLocation(), 0));
- drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(),
- bounds().width(), bounds().height(), drawOpacity(),
- sv->shaderMatrixLocation(), sv->shaderAlphaLocation());
-
+ GC3Denum sfactor = m_premultipliedAlpha ? GraphicsContext3D::ONE : GraphicsContext3D::SRC_ALPHA;
+ GLC(context, context->blendFunc(sfactor, GraphicsContext3D::ONE_MINUS_SRC_ALPHA));
+ layerRenderer()->useShader(program->program());
+ GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0));
+ drawTexturedQuad(context, layerRenderer()->projectionMatrix(), ccLayerImpl()->drawTransform(),
+ bounds().width(), bounds().height(), ccLayerImpl()->drawOpacity(),
+ program->vertexShader().matrixLocation(),
+ program->fragmentShader().alphaLocation());
}
}
diff --git a/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.h b/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.h
index 6520b55..ed3a06f 100644
--- a/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.h
@@ -45,30 +45,16 @@ public:
virtual void draw();
- class SharedValues {
- public:
- explicit SharedValues(GraphicsContext3D*);
- ~SharedValues();
-
- unsigned canvasShaderProgram() const { return m_canvasShaderProgram; }
- int shaderSamplerLocation() const { return m_shaderSamplerLocation; }
- int shaderMatrixLocation() const { return m_shaderMatrixLocation; }
- int shaderAlphaLocation() const { return m_shaderAlphaLocation; }
- bool initialized() const { return m_initialized; }
-
- private:
- GraphicsContext3D* m_context;
- unsigned m_canvasShaderProgram;
- int m_shaderSamplerLocation;
- int m_shaderMatrixLocation;
- int m_shaderAlphaLocation;
- bool m_initialized;
- };
+ typedef ProgramBinding<VertexShaderPosTex, FragmentShaderRGBATexFlipAlpha> Program;
protected:
explicit CanvasLayerChromium(GraphicsLayerChromium* owner);
+
+ virtual const char* layerTypeAsString() const { return "CanvasLayer"; }
+
bool m_textureChanged;
unsigned m_textureId;
+ bool m_premultipliedAlpha;
private:
static unsigned m_shaderProgramId;
diff --git a/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp
index a38f6bd..78f93d5 100644
--- a/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp
@@ -34,97 +34,15 @@
#include "ContentLayerChromium.h"
+#include "cc/CCLayerImpl.h"
#include "GraphicsContext3D.h"
#include "LayerRendererChromium.h"
#include "LayerTexture.h"
#include "RenderLayerBacking.h"
-
-#if PLATFORM(SKIA)
-#include "NativeImageSkia.h"
-#include "PlatformContextSkia.h"
-#include "SkColorPriv.h"
-#include "skia/ext/platform_canvas.h"
-#elif PLATFORM(CG)
-#include <CoreGraphics/CGBitmapContext.h>
-#endif
+#include "TextStream.h"
namespace WebCore {
-ContentLayerChromium::SharedValues::SharedValues(GraphicsContext3D* context)
- : m_context(context)
- , m_contentShaderProgram(0)
- , m_shaderSamplerLocation(-1)
- , m_shaderMatrixLocation(-1)
- , m_shaderAlphaLocation(-1)
- , m_initialized(false)
-{
- // Shaders for drawing the layer contents.
- char vertexShaderString[] =
- "attribute vec4 a_position; \n"
- "attribute vec2 a_texCoord; \n"
- "uniform mat4 matrix; \n"
- "varying vec2 v_texCoord; \n"
- "void main() \n"
- "{ \n"
- " gl_Position = matrix * a_position; \n"
- " v_texCoord = a_texCoord; \n"
- "} \n";
-
-#if PLATFORM(SKIA)
- // Color is in RGBA order.
- char rgbaFragmentShaderString[] =
- "precision mediump float; \n"
- "varying vec2 v_texCoord; \n"
- "uniform sampler2D s_texture; \n"
- "uniform float alpha; \n"
- "void main() \n"
- "{ \n"
- " vec4 texColor = texture2D(s_texture, v_texCoord); \n"
- " gl_FragColor = texColor * alpha; \n"
- "} \n";
-#endif
-
- // Color is in BGRA order.
- char bgraFragmentShaderString[] =
- "precision mediump float; \n"
- "varying vec2 v_texCoord; \n"
- "uniform sampler2D s_texture; \n"
- "uniform float alpha; \n"
- "void main() \n"
- "{ \n"
- " vec4 texColor = texture2D(s_texture, v_texCoord); \n"
- " gl_FragColor = vec4(texColor.z, texColor.y, texColor.x, texColor.w) * alpha; \n"
- "} \n";
-
-#if PLATFORM(SKIA)
- // Assuming the packing is either Skia default RGBA or Chromium default BGRA.
- char* fragmentShaderString = SK_B32_SHIFT ? rgbaFragmentShaderString : bgraFragmentShaderString;
-#else
- char* fragmentShaderString = bgraFragmentShaderString;
-#endif
- m_contentShaderProgram = createShaderProgram(m_context, vertexShaderString, fragmentShaderString);
- if (!m_contentShaderProgram) {
- LOG_ERROR("ContentLayerChromium: Failed to create shader program");
- return;
- }
-
- m_shaderSamplerLocation = m_context->getUniformLocation(m_contentShaderProgram, "s_texture");
- m_shaderMatrixLocation = m_context->getUniformLocation(m_contentShaderProgram, "matrix");
- m_shaderAlphaLocation = m_context->getUniformLocation(m_contentShaderProgram, "alpha");
- ASSERT(m_shaderSamplerLocation != -1);
- ASSERT(m_shaderMatrixLocation != -1);
- ASSERT(m_shaderAlphaLocation != -1);
-
- m_initialized = true;
-}
-
-ContentLayerChromium::SharedValues::~SharedValues()
-{
- if (m_contentShaderProgram)
- GLC(m_context, m_context->deleteProgram(m_contentShaderProgram));
-}
-
-
PassRefPtr<ContentLayerChromium> ContentLayerChromium::create(GraphicsLayerChromium* owner)
{
return adoptRef(new ContentLayerChromium(owner));
@@ -154,9 +72,9 @@ bool ContentLayerChromium::requiresClippedUpdateRect() const
// one of the layer's dimensions is larger than 2000 pixels or the size of
// surface it's rendering into. This is a temporary measure until layer tiling is implemented.
static const int maxLayerSize = 2000;
- return (m_bounds.width() > max(maxLayerSize, m_targetRenderSurface->contentRect().width())
- || m_bounds.height() > max(maxLayerSize, m_targetRenderSurface->contentRect().height())
- || !layerRenderer()->checkTextureSize(m_bounds));
+ return (bounds().width() > max(maxLayerSize, ccLayerImpl()->targetRenderSurface()->contentRect().width())
+ || bounds().height() > max(maxLayerSize, ccLayerImpl()->targetRenderSurface()->contentRect().height())
+ || !layerRenderer()->checkTextureSize(bounds()));
}
void ContentLayerChromium::updateContentsIfDirty()
@@ -169,28 +87,25 @@ void ContentLayerChromium::updateContentsIfDirty()
ASSERT(layerRenderer());
- void* pixels = 0;
IntRect dirtyRect;
- IntRect updateRect;
- IntSize requiredTextureSize;
- IntSize bitmapSize;
- IntRect boundsRect(IntPoint(0, 0), m_bounds);
+ IntRect boundsRect(IntPoint(0, 0), bounds());
+ IntPoint paintingOffset;
// FIXME: Remove this test when tiled layers are implemented.
if (requiresClippedUpdateRect()) {
// A layer with 3D transforms could require an arbitrarily large number
// of texels to be repainted, so ignore these layers until tiling is
// implemented.
- if (!drawTransform().isIdentityOrTranslation()) {
+ if (!ccLayerImpl()->drawTransform().isIdentityOrTranslation()) {
m_skipsDraw = true;
return;
}
// Calculate the region of this layer that is currently visible.
- const IntRect clipRect = m_targetRenderSurface->contentRect();
+ const IntRect clipRect = ccLayerImpl()->targetRenderSurface()->contentRect();
- TransformationMatrix layerOriginTransform = drawTransform();
- layerOriginTransform.translate3d(-0.5 * m_bounds.width(), -0.5 * m_bounds.height(), 0);
+ TransformationMatrix layerOriginTransform = ccLayerImpl()->drawTransform();
+ layerOriginTransform.translate3d(-0.5 * bounds().width(), -0.5 * bounds().height(), 0);
// For now we apply the large layer treatment only for layers that are either untransformed
// or are purely translated. Their matrix is expected to be invertible.
@@ -198,7 +113,7 @@ void ContentLayerChromium::updateContentsIfDirty()
TransformationMatrix targetToLayerMatrix = layerOriginTransform.inverse();
IntRect visibleRectInLayerCoords = targetToLayerMatrix.mapRect(clipRect);
- visibleRectInLayerCoords.intersect(IntRect(0, 0, m_bounds.width(), m_bounds.height()));
+ visibleRectInLayerCoords.intersect(IntRect(0, 0, bounds().width(), bounds().height()));
// For normal layers, the center of the texture corresponds with the center of the layer.
// In large layers the center of the texture is the center of the visible region so we have
@@ -212,9 +127,13 @@ void ContentLayerChromium::updateContentsIfDirty()
return;
}
- // If the visible portion of the layer is different from the last upload, or if our backing
- // texture has been evicted, then the whole layer is considered dirty.
- if (visibleRectInLayerCoords != m_visibleRectInLayerCoords || !m_contentsTexture || !m_contentsTexture->isValid(requiredTextureSize, GraphicsContext3D::RGBA))
+ // If we need to resize the upload buffer we have to repaint everything.
+ if (m_canvas.size() != visibleRectInLayerCoords.size()) {
+ resizeUploadBuffer(visibleRectInLayerCoords.size());
+ m_dirtyRect = boundsRect;
+ }
+ // If the visible portion of the layer is different from the last upload.
+ if (visibleRectInLayerCoords != m_visibleRectInLayerCoords)
m_dirtyRect = boundsRect;
m_visibleRectInLayerCoords = visibleRectInLayerCoords;
@@ -224,92 +143,52 @@ void ContentLayerChromium::updateContentsIfDirty()
// What the rectangles mean:
// dirtyRect: The region of this layer that will be updated.
- // updateRect: The region of the layer's texture that will be uploaded into.
- // requiredTextureSize: is the required size of this layer's texture.
+ // m_uploadUpdateRect: The region of the layer's texture that will be uploaded into.
dirtyRect = visibleDirtyRectInLayerSpace;
- updateRect = dirtyRect;
+ m_uploadUpdateRect = dirtyRect;
IntSize visibleRectOffsetInLayerCoords(visibleRectInLayerCoords.x(), visibleRectInLayerCoords.y());
- updateRect.move(-visibleRectOffsetInLayerCoords);
- requiredTextureSize = visibleRectInLayerCoords.size();
+ paintingOffset = IntPoint(visibleRectOffsetInLayerCoords);
+ m_uploadUpdateRect.move(-visibleRectOffsetInLayerCoords);
} else {
dirtyRect = IntRect(m_dirtyRect);
- requiredTextureSize = m_bounds;
// If the texture needs to be reallocated then we must redraw the entire
// contents of the layer.
- if (!m_contentsTexture || !m_contentsTexture->isValid(requiredTextureSize, GraphicsContext3D::RGBA))
+ if (m_canvas.size() != bounds()) {
+ resizeUploadBuffer(bounds());
dirtyRect = boundsRect;
- else {
+ } else {
// Clip the dirtyRect to the size of the layer to avoid drawing
// outside the bounds of the backing texture.
dirtyRect.intersect(boundsRect);
}
- updateRect = dirtyRect;
+ m_uploadUpdateRect = dirtyRect;
}
if (dirtyRect.isEmpty())
return;
-#if PLATFORM(SKIA)
- const SkBitmap* skiaBitmap = 0;
- OwnPtr<skia::PlatformCanvas> canvas;
- OwnPtr<PlatformContextSkia> skiaContext;
- OwnPtr<GraphicsContext> graphicsContext;
-
- canvas.set(new skia::PlatformCanvas(dirtyRect.width(), dirtyRect.height(), false));
- skiaContext.set(new PlatformContextSkia(canvas.get()));
-
- // This is needed to get text to show up correctly.
- // FIXME: Does this take us down a very slow text rendering path?
- skiaContext->setDrawingToImageBuffer(true);
-
- graphicsContext.set(new GraphicsContext(reinterpret_cast<PlatformGraphicsContext*>(skiaContext.get())));
+ PlatformCanvas::Painter painter(&m_canvas);
+ painter.context()->save();
+ painter.context()->translate(-paintingOffset.x(), -paintingOffset.y());
+ painter.context()->clearRect(dirtyRect);
+ painter.context()->clip(dirtyRect);
- // Bring the canvas into the coordinate system of the paint rect.
- canvas->translate(static_cast<SkScalar>(-dirtyRect.x()), static_cast<SkScalar>(-dirtyRect.y()));
+ m_owner->paintGraphicsLayerContents(*painter.context(), dirtyRect);
+ painter.context()->restore();
+}
- m_owner->paintGraphicsLayerContents(*graphicsContext, dirtyRect);
- const SkBitmap& bitmap = canvas->getDevice()->accessBitmap(false);
- skiaBitmap = &bitmap;
- ASSERT(skiaBitmap);
+void ContentLayerChromium::resizeUploadBuffer(const IntSize& size)
+{
+ m_canvas.resize(size);
+}
- SkAutoLockPixels lock(*skiaBitmap);
- SkBitmap::Config skiaConfig = skiaBitmap->config();
- // FIXME: do we need to support more image configurations?
- if (skiaConfig == SkBitmap::kARGB_8888_Config) {
- pixels = skiaBitmap->getPixels();
- bitmapSize = IntSize(skiaBitmap->width(), skiaBitmap->height());
- }
-#elif PLATFORM(CG)
- Vector<uint8_t> tempVector;
- int rowBytes = 4 * dirtyRect.width();
- tempVector.resize(rowBytes * dirtyRect.height());
- memset(tempVector.data(), 0, tempVector.size());
- RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB());
- RetainPtr<CGContextRef> contextCG(AdoptCF, CGBitmapContextCreate(tempVector.data(),
- dirtyRect.width(), dirtyRect.height(), 8, rowBytes,
- colorSpace.get(),
- kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host));
- CGContextTranslateCTM(contextCG.get(), 0, dirtyRect.height());
- CGContextScaleCTM(contextCG.get(), 1, -1);
-
- GraphicsContext graphicsContext(contextCG.get());
-
- // Translate the graphics context into the coordinate system of the dirty rect.
- graphicsContext.translate(-dirtyRect.x(), -dirtyRect.y());
-
- m_owner->paintGraphicsLayerContents(graphicsContext, dirtyRect);
-
- pixels = tempVector.data();
- bitmapSize = dirtyRect.size();
-#else
-#error "Need to implement for your platform."
-#endif
-
- if (pixels)
- updateTextureRect(pixels, requiredTextureSize, updateRect);
+void ContentLayerChromium::updateTextureIfNeeded()
+{
+ PlatformCanvas::AutoLocker locker(&m_canvas);
+ updateTexture(locker.pixels(), m_canvas.size());
}
-void ContentLayerChromium::updateTextureRect(void* pixels, const IntSize& requiredTextureSize, const IntRect& updateRect)
+void ContentLayerChromium::updateTexture(const uint8_t* pixels, const IntSize& size)
{
if (!pixels)
return;
@@ -318,15 +197,43 @@ void ContentLayerChromium::updateTextureRect(void* pixels, const IntSize& requir
if (!m_contentsTexture)
m_contentsTexture = LayerTexture::create(context, layerRenderer()->textureManager());
- if (!m_contentsTexture->reserve(requiredTextureSize, GraphicsContext3D::RGBA)) {
+ // If we have to allocate a new texture we have to upload the full contents.
+ if (!m_contentsTexture->isValid(size, GraphicsContext3D::RGBA))
+ m_uploadUpdateRect = IntRect(IntPoint(0, 0), size);
+
+ if (!m_contentsTexture->reserve(size, GraphicsContext3D::RGBA)) {
m_skipsDraw = true;
return;
}
- m_contentsTexture->bindTexture();
+ IntRect srcRect = IntRect(IntPoint(0, 0), size);
+ if (requiresClippedUpdateRect())
+ srcRect = m_visibleRectInLayerCoords;
+
+ const size_t destStride = m_uploadUpdateRect.width() * 4;
+ const size_t srcStride = srcRect.width() * 4;
+
+ const uint8_t* uploadPixels = pixels + srcStride * m_uploadUpdateRect.y();
+ Vector<uint8_t> uploadBuffer;
+ if (srcStride != destStride || m_uploadUpdateRect.x()) {
+ uploadBuffer.resize(m_uploadUpdateRect.height() * destStride);
+ for (int row = 0; row < m_uploadUpdateRect.height(); ++row) {
+ size_t srcOffset = (m_uploadUpdateRect.y() + row) * srcStride + m_uploadUpdateRect.x() * 4;
+ ASSERT(srcOffset + destStride <= static_cast<size_t>(size.width() * size.height() * 4));
+ size_t destOffset = row * destStride;
+ ASSERT(destOffset + destStride <= uploadBuffer.size());
+ memcpy(uploadBuffer.data() + destOffset, pixels + srcOffset, destStride);
+ }
+ uploadPixels = uploadBuffer.data();
+ }
- GLC(context, context->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, updateRect.x(), updateRect.y(), updateRect.width(), updateRect.height(), GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels));
+ m_contentsTexture->bindTexture();
+ GLC(context, context->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0,
+ m_uploadUpdateRect.x(), m_uploadUpdateRect.y(), m_uploadUpdateRect.width(), m_uploadUpdateRect.height(),
+ GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE,
+ uploadPixels));
+ m_uploadUpdateRect = IntRect();
m_dirtyRect.setSize(FloatSize());
// Large layers always stay dirty, because they need to update when the content rect changes.
m_contentsDirty = requiresClippedUpdateRect();
@@ -339,43 +246,59 @@ void ContentLayerChromium::draw()
ASSERT(layerRenderer());
- const ContentLayerChromium::SharedValues* sv = layerRenderer()->contentLayerSharedValues();
- ASSERT(sv && sv->initialized());
+ const ContentLayerChromium::Program* program = layerRenderer()->contentLayerProgram();
+ ASSERT(program && program->initialized());
GraphicsContext3D* context = layerRendererContext();
GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
bindContentsTexture();
- layerRenderer()->useShader(sv->contentShaderProgram());
- GLC(context, context->uniform1i(sv->shaderSamplerLocation(), 0));
+ layerRenderer()->useShader(program->program());
+ GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0));
+ GLC(context, context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA));
if (requiresClippedUpdateRect()) {
- float m43 = drawTransform().m43();
+ float m43 = ccLayerImpl()->drawTransform().m43();
TransformationMatrix transform;
transform.translate3d(m_layerCenterInSurfaceCoords.x(), m_layerCenterInSurfaceCoords.y(), m43);
drawTexturedQuad(context, layerRenderer()->projectionMatrix(),
transform, m_visibleRectInLayerCoords.width(),
- m_visibleRectInLayerCoords.height(), drawOpacity(),
- sv->shaderMatrixLocation(), sv->shaderAlphaLocation());
+ m_visibleRectInLayerCoords.height(), ccLayerImpl()->drawOpacity(),
+ program->vertexShader().matrixLocation(),
+ program->fragmentShader().alphaLocation());
} else {
drawTexturedQuad(context, layerRenderer()->projectionMatrix(),
- drawTransform(), m_bounds.width(), m_bounds.height(),
- drawOpacity(), sv->shaderMatrixLocation(),
- sv->shaderAlphaLocation());
+ ccLayerImpl()->drawTransform(), bounds().width(), bounds().height(),
+ ccLayerImpl()->drawOpacity(), program->vertexShader().matrixLocation(),
+ program->fragmentShader().alphaLocation());
}
unreserveContentsTexture();
}
void ContentLayerChromium::unreserveContentsTexture()
{
- if (m_contentsTexture)
+ if (!m_skipsDraw && m_contentsTexture)
m_contentsTexture->unreserve();
}
void ContentLayerChromium::bindContentsTexture()
{
- if (m_contentsTexture)
+ updateTextureIfNeeded();
+
+ if (!m_skipsDraw && m_contentsTexture)
m_contentsTexture->bindTexture();
}
+static void writeIndent(TextStream& ts, int indent)
+{
+ for (int i = 0; i != indent; ++i)
+ ts << " ";
+}
+
+void ContentLayerChromium::dumpLayerProperties(TextStream& ts, int indent) const
+{
+ LayerChromium::dumpLayerProperties(ts, indent);
+ writeIndent(ts, indent);
+ ts << "skipsDraw: " << m_skipsDraw << "\n";
+}
}
#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h b/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h
index 3363518..6f070c2 100644
--- a/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h
@@ -35,6 +35,7 @@
#if USE(ACCELERATED_COMPOSITING)
#include "LayerChromium.h"
+#include "PlatformCanvas.h"
#include "TextureManager.h"
namespace WebCore {
@@ -54,43 +55,31 @@ public:
virtual void bindContentsTexture();
virtual void draw();
- virtual bool drawsContent() { return m_owner && m_owner->drawsContent(); }
-
- // Stores values that are shared between instances of this class that are
- // associated with the same LayerRendererChromium (and hence the same GL
- // context).
- class SharedValues {
- public:
- explicit SharedValues(GraphicsContext3D*);
- ~SharedValues();
-
- unsigned contentShaderProgram() const { return m_contentShaderProgram; }
- int shaderSamplerLocation() const { return m_shaderSamplerLocation; }
- int shaderMatrixLocation() const { return m_shaderMatrixLocation; }
- int shaderAlphaLocation() const { return m_shaderAlphaLocation; }
- int initialized() const { return m_initialized; }
-
- private:
- GraphicsContext3D* m_context;
- unsigned m_contentShaderProgram;
- int m_shaderSamplerLocation;
- int m_shaderMatrixLocation;
- int m_shaderAlphaLocation;
- int m_initialized;
- };
+ virtual bool drawsContent() const { return m_owner && m_owner->drawsContent(); }
+
+ typedef ProgramBinding<VertexShaderPosTex, FragmentShaderTexAlpha> Program;
protected:
explicit ContentLayerChromium(GraphicsLayerChromium* owner);
- void updateTextureRect(void* pixels, const IntSize& requiredTextureSize, const IntRect& updateRect);
-
virtual void cleanupResources();
bool requiresClippedUpdateRect() const;
+ void resizeUploadBuffer(const IntSize&);
+
+ virtual const char* layerTypeAsString() const { return "ContentLayer"; }
+ virtual void dumpLayerProperties(TextStream&, int indent) const;
OwnPtr<LayerTexture> m_contentsTexture;
bool m_skipsDraw;
+ // The portion of the upload buffer that has a pending update, in the coordinates of the texture.
+ IntRect m_uploadUpdateRect;
+
+ virtual void updateTextureIfNeeded();
+ void updateTexture(const uint8_t* pixels, const IntSize&);
+
private:
+ PlatformCanvas m_canvas;
IntRect m_visibleRectInLayerCoords;
FloatPoint m_layerCenterInSurfaceCoords;
diff --git a/Source/WebCore/platform/graphics/chromium/Extensions3DChromium.h b/Source/WebCore/platform/graphics/chromium/Extensions3DChromium.h
index 92fb7b3..3b0fdbf 100644
--- a/Source/WebCore/platform/graphics/chromium/Extensions3DChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/Extensions3DChromium.h
@@ -46,6 +46,10 @@ public:
virtual int getGraphicsResetStatusARB();
virtual void blitFramebuffer(long srcX0, long srcY0, long srcX1, long srcY1, long dstX0, long dstY0, long dstX1, long dstY1, unsigned long mask, unsigned long filter);
virtual void renderbufferStorageMultisample(unsigned long target, unsigned long samples, unsigned long internalformat, unsigned long width, unsigned long height);
+ virtual Platform3DObject createVertexArrayOES();
+ virtual void deleteVertexArrayOES(Platform3DObject);
+ virtual GC3Dboolean isVertexArrayOES(Platform3DObject);
+ virtual void bindVertexArrayOES(Platform3DObject);
enum {
// GL_CHROMIUM_map_sub (enums inherited from GL_ARB_vertex_buffer_object)
diff --git a/Source/WebCore/platform/graphics/chromium/FontCacheLinux.cpp b/Source/WebCore/platform/graphics/chromium/FontCacheLinux.cpp
index a849a6c..bbe6d62 100644
--- a/Source/WebCore/platform/graphics/chromium/FontCacheLinux.cpp
+++ b/Source/WebCore/platform/graphics/chromium/FontCacheLinux.cpp
@@ -43,6 +43,7 @@
#include "SkTypeface.h"
#include "SkUtils.h"
+#include <unicode/locid.h>
#include <wtf/Assertions.h>
#include <wtf/text/AtomicString.h>
#include <wtf/text/CString.h>
@@ -57,7 +58,8 @@ const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font,
const UChar* characters,
int length)
{
- String family = PlatformBridge::getFontFamilyForCharacters(characters, length);
+ icu::Locale locale = icu::Locale::getDefault();
+ String family = PlatformBridge::getFontFamilyForCharacters(characters, length, locale.getLanguage());
if (family.isEmpty())
return 0;
diff --git a/Source/WebCore/platform/graphics/chromium/GLES2Canvas.cpp b/Source/WebCore/platform/graphics/chromium/GLES2Canvas.cpp
index 953ee2f..2ff6b8b 100644
--- a/Source/WebCore/platform/graphics/chromium/GLES2Canvas.cpp
+++ b/Source/WebCore/platform/graphics/chromium/GLES2Canvas.cpp
@@ -38,10 +38,12 @@
#include "GraphicsContext3D.h"
#include "internal_glu.h"
#include "IntRect.h"
+#include "LoopBlinnPathProcessor.h"
+#include "LoopBlinnSolidFillShader.h"
#include "Path.h"
#include "PlatformString.h"
#include "SharedGraphicsContext3D.h"
-#if PLATFORM(SKIA)
+#if USE(SKIA)
#include "SkPath.h"
#endif
#include "Texture.h"
@@ -170,6 +172,7 @@ GLES2Canvas::GLES2Canvas(SharedGraphicsContext3D* context, DrawingBuffer* drawin
, m_context(context)
, m_drawingBuffer(drawingBuffer)
, m_state(0)
+ , m_pathVertexBuffer(0)
{
m_flipMatrix.translate(-1.0f, 1.0f);
m_flipMatrix.scale(2.0f / size.width(), -2.0f / size.height());
@@ -191,7 +194,7 @@ void GLES2Canvas::clearRect(const FloatRect& rect)
{
bindFramebuffer();
if (m_state->m_ctm.isIdentity() && !m_state->m_clippingEnabled) {
- m_context->scissor(rect);
+ m_context->scissor(rect.x(), m_size.height() - rect.height() - rect.y(), rect.width(), rect.height());
m_context->enable(GraphicsContext3D::SCISSOR_TEST);
m_context->clearColor(Color(RGBA32(0)));
m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT);
@@ -263,6 +266,11 @@ void GLES2Canvas::concatCTM(const AffineTransform& affine)
m_state->m_ctm *= affine;
}
+void GLES2Canvas::setCTM(const AffineTransform& affine)
+{
+ m_state->m_ctm = affine;
+}
+
void GLES2Canvas::clipPath(const Path& path)
{
bindFramebuffer();
@@ -396,9 +404,9 @@ Texture* GLES2Canvas::getTexture(NativeImagePtr ptr)
return m_context->getTexture(ptr);
}
-#if PLATFORM(SKIA)
+#if USE(SKIA)
// This is actually cross-platform code, but since its only caller is inside a
-// PLATFORM(SKIA), it will cause a warning-as-error on Chrome/Mac.
+// USE(SKIA), it will cause a warning-as-error on Chrome/Mac.
static void interpolateQuadratic(DoubleVector* vertices, const FloatPoint& p0, const FloatPoint& p1, const FloatPoint& p2)
{
float tIncrement = 1.0f / pathTesselation, t = tIncrement;
@@ -473,7 +481,7 @@ void GLES2Canvas::createVertexBufferFromPath(const Path& path, int* count, unsig
checkGLError("createVertexBufferFromPath, createBuffer");
DoubleVector inVertices;
WTF::Vector<size_t> contours;
-#if PLATFORM(SKIA)
+#if USE(SKIA)
const SkPath* skPath = path.platformPath();
SkPoint pts[4];
SkPath::Iter iter(*skPath, true);
@@ -548,28 +556,61 @@ void GLES2Canvas::createVertexBufferFromPath(const Path& path, int* count, unsig
void GLES2Canvas::fillPath(const Path& path, const Color& color)
{
- int count;
- unsigned vertexBuffer, indexBuffer;
- createVertexBufferFromPath(path, &count, &vertexBuffer, &indexBuffer);
- m_context->graphicsContext3D()->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, vertexBuffer);
- checkGLError("bindBuffer");
- m_context->graphicsContext3D()->bindBuffer(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, indexBuffer);
- checkGLError("bindBuffer");
+ if (SharedGraphicsContext3D::useLoopBlinnForPathRendering()) {
+ bindFramebuffer();
+ m_context->applyCompositeOperator(m_state->m_compositeOp);
+
+ m_pathCache.clear();
+ LoopBlinnPathProcessor processor;
+ processor.process(path, m_pathCache);
+ if (!m_pathVertexBuffer)
+ m_pathVertexBuffer = m_context->createBuffer();
+ m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_pathVertexBuffer);
+ int byteSizeOfVertices = 2 * m_pathCache.numberOfVertices() * sizeof(float);
+ int byteSizeOfTexCoords = 3 * m_pathCache.numberOfVertices() * sizeof(float);
+ int byteSizeOfInteriorVertices = 2 * m_pathCache.numberOfInteriorVertices() * sizeof(float);
+ m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER,
+ byteSizeOfVertices + byteSizeOfTexCoords + byteSizeOfInteriorVertices,
+ GraphicsContext3D::STATIC_DRAW);
+ m_context->bufferSubData(GraphicsContext3D::ARRAY_BUFFER, 0, byteSizeOfVertices, m_pathCache.vertices());
+ m_context->bufferSubData(GraphicsContext3D::ARRAY_BUFFER, byteSizeOfVertices, byteSizeOfTexCoords, m_pathCache.texcoords());
+ m_context->bufferSubData(GraphicsContext3D::ARRAY_BUFFER, byteSizeOfVertices + byteSizeOfTexCoords, byteSizeOfInteriorVertices, m_pathCache.interiorVertices());
+
+ AffineTransform matrix(m_flipMatrix);
+ matrix *= m_state->m_ctm;
+
+ // Draw the exterior
+ m_context->useLoopBlinnExteriorProgram(0, byteSizeOfVertices, matrix, color);
+ m_context->drawArrays(GraphicsContext3D::TRIANGLES, 0, m_pathCache.numberOfVertices());
+
+ // Draw the interior
+ m_context->useLoopBlinnInteriorProgram(byteSizeOfVertices + byteSizeOfTexCoords, matrix, color);
+ m_context->drawArrays(GraphicsContext3D::TRIANGLES, 0, m_pathCache.numberOfInteriorVertices());
+ } else {
+ int count;
+ unsigned vertexBuffer, indexBuffer;
+ createVertexBufferFromPath(path, &count, &vertexBuffer, &indexBuffer);
+ m_context->graphicsContext3D()->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, vertexBuffer);
+ checkGLError("bindBuffer");
+ m_context->graphicsContext3D()->bindBuffer(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, indexBuffer);
+ checkGLError("bindBuffer");
- AffineTransform matrix(m_flipMatrix);
- matrix *= m_state->m_ctm;
+ AffineTransform matrix(m_flipMatrix);
+ matrix *= m_state->m_ctm;
- m_context->useFillSolidProgram(matrix, color);
- checkGLError("useFillSolidProgram");
+ m_context->useFillSolidProgram(matrix, color);
+ checkGLError("useFillSolidProgram");
- m_context->graphicsContext3D()->drawElements(GraphicsContext3D::TRIANGLES, count, GraphicsContext3D::UNSIGNED_SHORT, 0);
- checkGLError("drawArrays");
+ bindFramebuffer();
+ m_context->graphicsContext3D()->drawElements(GraphicsContext3D::TRIANGLES, count, GraphicsContext3D::UNSIGNED_SHORT, 0);
+ checkGLError("drawArrays");
- m_context->graphicsContext3D()->deleteBuffer(vertexBuffer);
- checkGLError("deleteBuffer");
+ m_context->graphicsContext3D()->deleteBuffer(vertexBuffer);
+ checkGLError("deleteBuffer");
- m_context->graphicsContext3D()->deleteBuffer(indexBuffer);
- checkGLError("deleteBuffer");
+ m_context->graphicsContext3D()->deleteBuffer(indexBuffer);
+ checkGLError("deleteBuffer");
+ }
}
void GLES2Canvas::beginStencilDraw()
diff --git a/Source/WebCore/platform/graphics/chromium/GLES2Canvas.h b/Source/WebCore/platform/graphics/chromium/GLES2Canvas.h
index 605f86f..8887a16 100644
--- a/Source/WebCore/platform/graphics/chromium/GLES2Canvas.h
+++ b/Source/WebCore/platform/graphics/chromium/GLES2Canvas.h
@@ -36,6 +36,7 @@
#include "ColorSpace.h"
#include "GraphicsTypes.h"
#include "ImageSource.h"
+#include "LoopBlinnPathCache.h"
#include "Texture.h"
#include <wtf/HashMap.h>
@@ -68,6 +69,7 @@ public:
void rotate(float angleInRadians);
void scale(const FloatSize&);
void concatCTM(const AffineTransform&);
+ void setCTM(const AffineTransform&);
void clipPath(const Path&);
void clipOut(const Path&);
@@ -113,6 +115,10 @@ private:
StateVector m_stateStack;
State* m_state;
AffineTransform m_flipMatrix;
+
+ // Members for GPU-accelerated path rendering.
+ LoopBlinnPathCache m_pathCache;
+ unsigned m_pathVertexBuffer;
};
}
diff --git a/Source/WebCore/platform/graphics/chromium/GeometryBinding.cpp b/Source/WebCore/platform/graphics/chromium/GeometryBinding.cpp
new file mode 100644
index 0000000..a859aae
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/GeometryBinding.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2011 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS 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 APPLE OR ITS 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(ACCELERATED_COMPOSITING)
+
+#include "GeometryBinding.h"
+
+#include "GraphicsContext.h"
+#include "GraphicsContext3D.h"
+#include "LayerRendererChromium.h"
+
+namespace WebCore {
+
+GeometryBinding::GeometryBinding(GraphicsContext3D* context)
+ : m_context(context)
+ , m_quadVerticesVbo(0)
+ , m_quadElementsVbo(0)
+ , m_initialized(false)
+{
+ // Vertex positions and texture coordinates for the 4 corners of a 1x1 quad.
+ float vertices[] = { -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, -0.5f, 0.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.0f, 1.0f, 1.0f };
+ uint16_t indices[] = { 0, 1, 2, 0, 2, 3, // The two triangles that make up the layer quad.
+ 0, 1, 2, 3}; // A line path for drawing the layer border.
+
+ GLC(m_context, m_quadVerticesVbo = m_context->createBuffer());
+ GLC(m_context, m_quadElementsVbo = m_context->createBuffer());
+ GLC(m_context, m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_quadVerticesVbo));
+ GLC(m_context, m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER, sizeof(vertices), vertices, GraphicsContext3D::STATIC_DRAW));
+ GLC(m_context, m_context->bindBuffer(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, m_quadElementsVbo));
+ GLC(m_context, m_context->bufferData(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GraphicsContext3D::STATIC_DRAW));
+
+ m_initialized = true;
+}
+
+GeometryBinding::~GeometryBinding()
+{
+ GLC(m_context, m_context->deleteBuffer(m_quadVerticesVbo));
+ GLC(m_context, m_context->deleteBuffer(m_quadElementsVbo));
+}
+
+void GeometryBinding::prepareForDraw()
+{
+ GLC(m_context, m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, quadVerticesVbo()));
+ GLC(m_context, m_context->bindBuffer(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, quadElementsVbo()));
+ unsigned offset = 0;
+ GLC(m_context, m_context->vertexAttribPointer(positionAttribLocation(), 3, GraphicsContext3D::FLOAT, false, 5 * sizeof(float), offset));
+ offset += 3 * sizeof(float);
+ GLC(m_context, m_context->vertexAttribPointer(texCoordAttribLocation(), 2, GraphicsContext3D::FLOAT, false, 5 * sizeof(float), offset));
+ GLC(m_context, m_context->enableVertexAttribArray(positionAttribLocation()));
+ GLC(m_context, m_context->enableVertexAttribArray(texCoordAttribLocation()));
+}
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/chromium/GeometryBinding.h b/Source/WebCore/platform/graphics/chromium/GeometryBinding.h
new file mode 100644
index 0000000..ec19970
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/GeometryBinding.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2011 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS 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 APPLE OR ITS 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 GeometryBinding_h
+#define GeometryBinding_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "PlatformString.h"
+
+namespace WebCore {
+
+class GraphicsContext3D;
+
+class GeometryBinding {
+public:
+ explicit GeometryBinding(GraphicsContext3D*);
+ ~GeometryBinding();
+
+ bool initialized() const { return m_initialized; }
+
+ GraphicsContext3D* context() const { return m_context; }
+ unsigned quadVerticesVbo() const { return m_quadVerticesVbo; }
+ unsigned quadElementsVbo() const { return m_quadElementsVbo; }
+
+ void prepareForDraw();
+
+ // All layer shaders share the same attribute locations for the vertex
+ // positions and texture coordinates. This allows switching shaders without
+ // rebinding attribute arrays.
+ static int positionAttribLocation() { return 0; }
+ static int texCoordAttribLocation() { return 1; }
+
+private:
+ GraphicsContext3D* m_context;
+ unsigned m_quadVerticesVbo;
+ unsigned m_quadElementsVbo;
+ bool m_initialized;
+};
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
+#endif
diff --git a/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp
index 488230c..067c54d 100644
--- a/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp
@@ -111,8 +111,20 @@ GraphicsLayerChromium::~GraphicsLayerChromium()
void GraphicsLayerChromium::setName(const String& inName)
{
+ m_nameBase = inName;
String name = String::format("GraphicsLayerChromium(%p) GraphicsLayer(%p) ", m_layer.get(), this) + inName;
GraphicsLayer::setName(name);
+ updateNames();
+}
+
+void GraphicsLayerChromium::updateNames()
+{
+ if (m_layer)
+ m_layer->setName("Layer for " + m_nameBase);
+ if (m_transformLayer)
+ m_transformLayer->setName("TransformLayer for " + m_nameBase);
+ if (m_contentsLayer)
+ m_contentsLayer->setName("ContentsLayer for " + m_nameBase);
}
bool GraphicsLayerChromium::setChildren(const Vector<GraphicsLayer*>& children)
@@ -590,6 +602,7 @@ void GraphicsLayerChromium::updateLayerPreserves3D()
}
updateOpacityOnLayer();
+ updateNames();
}
void GraphicsLayerChromium::updateLayerDrawsContent()
@@ -653,6 +666,7 @@ void GraphicsLayerChromium::setupContentsLayer(LayerChromium* contentsLayer)
}
}
updateDebugIndicators();
+ updateNames();
}
// This function simply mimics the operation of GraphicsLayerCA
diff --git a/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h b/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h
index 92c61fe..db8c6f7 100644
--- a/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h
@@ -107,6 +107,7 @@ private:
LayerChromium* hostLayerForSublayers() const;
LayerChromium* layerForSuperlayer() const;
+ void updateNames();
void updateSublayerList();
void updateLayerPosition();
void updateLayerSize();
@@ -127,6 +128,8 @@ private:
void setupContentsLayer(LayerChromium*);
LayerChromium* contentsLayer() const { return m_contentsLayer.get(); }
+ String m_nameBase;
+
RefPtr<LayerChromium> m_layer;
RefPtr<LayerChromium> m_transformLayer;
RefPtr<LayerChromium> m_contentsLayer;
diff --git a/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp
index cd299c1..7c42366 100644
--- a/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp
@@ -38,18 +38,6 @@
#include "LayerRendererChromium.h"
#include "LayerTexture.h"
-#if PLATFORM(SKIA)
-#include "NativeImageSkia.h"
-#include "PlatformContextSkia.h"
-#endif
-
-#if PLATFORM(CG)
-#include <CoreGraphics/CGBitmapContext.h>
-#include <CoreGraphics/CGContext.h>
-#include <CoreGraphics/CGImage.h>
-#include <wtf/RetainPtr.h>
-#endif
-
namespace WebCore {
PassRefPtr<ImageLayerChromium> ImageLayerChromium::create(GraphicsLayerChromium* owner)
@@ -84,80 +72,17 @@ void ImageLayerChromium::updateContentsIfDirty()
return;
}
- void* pixels = 0;
- IntSize bitmapSize;
-
- NativeImagePtr nativeImage = m_contents->nativeImageForCurrentFrame();
-
-#if PLATFORM(SKIA)
- // The layer contains an Image.
- NativeImageSkia* skiaImage = static_cast<NativeImageSkia*>(nativeImage);
- const SkBitmap* skiaBitmap = skiaImage;
- bitmapSize = IntSize(skiaBitmap->width(), skiaBitmap->height());
- ASSERT(skiaBitmap);
-#elif PLATFORM(CG)
- // NativeImagePtr is a CGImageRef on Mac OS X.
- int width = CGImageGetWidth(nativeImage);
- int height = CGImageGetHeight(nativeImage);
- bitmapSize = IntSize(width, height);
-#endif
-
- // Clip the dirty rect to the bitmap dimensions.
- IntRect dirtyRect(m_dirtyRect);
- dirtyRect.intersect(IntRect(IntPoint(0, 0), bitmapSize));
+ m_decodedImage.updateFromImage(m_contents->nativeImageForCurrentFrame());
+}
- if (!m_contentsTexture || !m_contentsTexture->isValid(bitmapSize, GraphicsContext3D::RGBA))
- dirtyRect = IntRect(IntPoint(0, 0), bitmapSize);
- else if (!m_contentsDirty) {
- m_contentsTexture->reserve(bitmapSize, GraphicsContext3D::RGBA);
+void ImageLayerChromium::updateTextureIfNeeded()
+{
+ // FIXME: Remove this test when tiled layers are implemented.
+ if (requiresClippedUpdateRect()) {
+ ContentLayerChromium::updateTextureIfNeeded();
return;
}
-
-#if PLATFORM(SKIA)
- SkAutoLockPixels lock(*skiaBitmap);
- SkBitmap::Config skiaConfig = skiaBitmap->config();
- // FIXME: do we need to support more image configurations?
- if (skiaConfig == SkBitmap::kARGB_8888_Config)
- pixels = skiaBitmap->getPixels();
-#elif PLATFORM(CG)
- // FIXME: we should get rid of this temporary copy where possible.
- int tempRowBytes = width * 4;
- Vector<uint8_t> tempVector;
- tempVector.resize(height * tempRowBytes);
- // Note we do not zero this vector since we are going to
- // completely overwrite its contents with the image below.
- // Try to reuse the color space from the image to preserve its colors.
- // Some images use a color space (such as indexed) unsupported by the bitmap context.
- RetainPtr<CGColorSpaceRef> colorSpaceReleaser;
- CGColorSpaceRef colorSpace = CGImageGetColorSpace(nativeImage);
- CGColorSpaceModel colorSpaceModel = CGColorSpaceGetModel(colorSpace);
- switch (colorSpaceModel) {
- case kCGColorSpaceModelMonochrome:
- case kCGColorSpaceModelRGB:
- case kCGColorSpaceModelCMYK:
- case kCGColorSpaceModelLab:
- case kCGColorSpaceModelDeviceN:
- break;
- default:
- colorSpaceReleaser.adoptCF(CGColorSpaceCreateDeviceRGB());
- colorSpace = colorSpaceReleaser.get();
- break;
- }
- RetainPtr<CGContextRef> tempContext(AdoptCF, CGBitmapContextCreate(tempVector.data(),
- width, height, 8, tempRowBytes,
- colorSpace,
- kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host));
- CGContextSetBlendMode(tempContext.get(), kCGBlendModeCopy);
- CGContextDrawImage(tempContext.get(),
- CGRectMake(0, 0, static_cast<CGFloat>(width), static_cast<CGFloat>(height)),
- nativeImage);
- pixels = tempVector.data();
-#else
-#error "Need to implement for your platform."
-#endif
-
- if (pixels)
- updateTextureRect(pixels, bitmapSize, dirtyRect);
+ updateTexture(m_decodedImage.pixels(), m_decodedImage.size());
}
}
diff --git a/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.h b/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.h
index a5c1450..cc9064d 100644
--- a/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.h
@@ -35,6 +35,7 @@
#if USE(ACCELERATED_COMPOSITING)
#include "ContentLayerChromium.h"
+#include "PlatformImage.h"
#if PLATFORM(CG)
#include <wtf/RetainPtr.h>
@@ -50,13 +51,19 @@ public:
static PassRefPtr<ImageLayerChromium> create(GraphicsLayerChromium* owner = 0);
virtual void updateContentsIfDirty();
- virtual bool drawsContent() { return m_contents; }
+ virtual bool drawsContent() const { return m_contents; }
void setContents(Image* image);
+protected:
+ virtual const char* layerTypeAsString() const { return "ImageLayer"; }
+
private:
+ virtual void updateTextureIfNeeded();
+
ImageLayerChromium(GraphicsLayerChromium* owner);
+ PlatformImage m_decodedImage;
RefPtr<Image> m_contents;
};
diff --git a/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp
index 8d01d9b..95b7386 100644
--- a/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp
@@ -34,106 +34,24 @@
#include "LayerChromium.h"
+#include "cc/CCLayerImpl.h"
#include "GraphicsContext3D.h"
#include "LayerRendererChromium.h"
-#if PLATFORM(SKIA)
+#if USE(SKIA)
#include "NativeImageSkia.h"
#include "PlatformContextSkia.h"
#endif
#include "RenderLayerBacking.h"
+#include "TextStream.h"
#include "skia/ext/platform_canvas.h"
-#include <wtf/text/WTFString.h>
namespace WebCore {
using namespace std;
-const unsigned LayerChromium::s_positionAttribLocation = 0;
-const unsigned LayerChromium::s_texCoordAttribLocation = 1;
-
-static unsigned loadShader(GraphicsContext3D* context, unsigned type, const char* shaderSource)
-{
- unsigned shader = context->createShader(type);
- if (!shader)
- return 0;
- String sourceString(shaderSource);
- GLC(context, context->shaderSource(shader, sourceString));
- GLC(context, context->compileShader(shader));
- int compiled = 0;
- GLC(context, context->getShaderiv(shader, GraphicsContext3D::COMPILE_STATUS, &compiled));
- if (!compiled) {
- GLC(context, context->deleteShader(shader));
- return 0;
- }
- return shader;
-}
-
-LayerChromium::SharedValues::SharedValues(GraphicsContext3D* context)
- : m_context(context)
- , m_quadVerticesVbo(0)
- , m_quadElementsVbo(0)
- , m_maxTextureSize(0)
- , m_borderShaderProgram(0)
- , m_borderShaderMatrixLocation(-1)
- , m_borderShaderColorLocation(-1)
- , m_initialized(false)
-{
- // Vertex positions and texture coordinates for the 4 corners of a 1x1 quad.
- float vertices[] = { -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
- -0.5f, -0.5f, 0.0f, 0.0f, 0.0f,
- 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
- 0.5f, 0.5f, 0.0f, 1.0f, 1.0f };
- uint16_t indices[] = { 0, 1, 2, 0, 2, 3, // The two triangles that make up the layer quad.
- 0, 1, 2, 3}; // A line path for drawing the layer border.
-
- GLC(m_context, m_quadVerticesVbo = m_context->createBuffer());
- GLC(m_context, m_quadElementsVbo = m_context->createBuffer());
- GLC(m_context, m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_quadVerticesVbo));
- GLC(m_context, m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER, sizeof(vertices), vertices, GraphicsContext3D::STATIC_DRAW));
- GLC(m_context, m_context->bindBuffer(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, m_quadElementsVbo));
- GLC(m_context, m_context->bufferData(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GraphicsContext3D::STATIC_DRAW));
-
- // Get the max texture size supported by the system.
- GLC(m_context, m_context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &m_maxTextureSize));
-
- // Shaders for drawing the debug borders around the layers.
- char borderVertexShaderString[] =
- "attribute vec4 a_position; \n"
- "uniform mat4 matrix; \n"
- "void main() \n"
- "{ \n"
- " gl_Position = matrix * a_position; \n"
- "} \n";
- char borderFragmentShaderString[] =
- "precision mediump float; \n"
- "uniform vec4 color; \n"
- "void main() \n"
- "{ \n"
- " gl_FragColor = vec4(color.xyz * color.w, color.w);\n"
- "} \n";
-
- m_borderShaderProgram = createShaderProgram(m_context, borderVertexShaderString, borderFragmentShaderString);
- if (!m_borderShaderProgram) {
- LOG_ERROR("ContentLayerChromium: Failed to create shader program");
- return;
- }
-
- m_borderShaderMatrixLocation = m_context->getUniformLocation(m_borderShaderProgram, "matrix");
- m_borderShaderColorLocation = m_context->getUniformLocation(m_borderShaderProgram, "color");
- ASSERT(m_borderShaderMatrixLocation != -1);
- ASSERT(m_borderShaderColorLocation != -1);
-
- m_initialized = true;
-}
-
-LayerChromium::SharedValues::~SharedValues()
-{
- GLC(m_context, m_context->deleteBuffer(m_quadVerticesVbo));
- GLC(m_context, m_context->deleteBuffer(m_quadElementsVbo));
- if (m_borderShaderProgram)
- GLC(m_context, m_context->deleteProgram(m_borderShaderProgram));
-}
-
+#ifndef NDEBUG
+static int s_nextLayerDebugID = 1;
+#endif
PassRefPtr<LayerChromium> LayerChromium::create(GraphicsLayerChromium* owner)
{
@@ -144,25 +62,22 @@ LayerChromium::LayerChromium(GraphicsLayerChromium* owner)
: m_owner(owner)
, m_contentsDirty(false)
, m_maskLayer(0)
- , m_targetRenderSurface(0)
, m_superlayer(0)
+#ifndef NDEBUG
+ , m_debugID(s_nextLayerDebugID++)
+#endif
, m_anchorPoint(0.5, 0.5)
, m_backgroundColor(0, 0, 0, 0)
- , m_borderColor(0, 0, 0, 0)
, m_opacity(1.0)
, m_zPosition(0.0)
, m_anchorPointZ(0)
- , m_borderWidth(0)
, m_clearsContext(false)
- , m_doubleSided(true)
, m_hidden(false)
, m_masksToBounds(false)
, m_opaque(true)
, m_geometryFlipped(false)
, m_needsDisplayOnBoundsChange(false)
- , m_drawDepth(0)
- , m_layerRenderer(0)
- , m_renderSurface(0)
+ , m_ccLayerImpl(CCLayerImpl::create(this))
, m_replicaLayer(0)
{
}
@@ -179,8 +94,7 @@ LayerChromium::~LayerChromium()
void LayerChromium::cleanupResources()
{
- if (m_renderSurface)
- m_renderSurface->cleanupResources();
+ m_ccLayerImpl->cleanupResources();
}
void LayerChromium::setLayerRenderer(LayerRendererChromium* renderer)
@@ -192,55 +106,7 @@ void LayerChromium::setLayerRenderer(LayerRendererChromium* renderer)
setNeedsDisplay();
}
- m_layerRenderer = renderer;
-}
-
-RenderSurfaceChromium* LayerChromium::createRenderSurface()
-{
- m_renderSurface = new RenderSurfaceChromium(this);
- return m_renderSurface.get();
-}
-
-unsigned LayerChromium::createShaderProgram(GraphicsContext3D* context, const char* vertexShaderSource, const char* fragmentShaderSource)
-{
- unsigned vertexShader = loadShader(context, GraphicsContext3D::VERTEX_SHADER, vertexShaderSource);
- if (!vertexShader) {
- LOG_ERROR("Failed to create vertex shader");
- return 0;
- }
-
- unsigned fragmentShader = loadShader(context, GraphicsContext3D::FRAGMENT_SHADER, fragmentShaderSource);
- if (!fragmentShader) {
- GLC(context, context->deleteShader(vertexShader));
- LOG_ERROR("Failed to create fragment shader");
- return 0;
- }
-
- unsigned programObject = context->createProgram();
- if (!programObject) {
- LOG_ERROR("Failed to create shader program");
- return 0;
- }
-
- GLC(context, context->attachShader(programObject, vertexShader));
- GLC(context, context->attachShader(programObject, fragmentShader));
-
- // Bind the common attrib locations.
- GLC(context, context->bindAttribLocation(programObject, s_positionAttribLocation, "a_position"));
- GLC(context, context->bindAttribLocation(programObject, s_texCoordAttribLocation, "a_texCoord"));
-
- GLC(context, context->linkProgram(programObject));
- int linked = 0;
- GLC(context, context->getProgramiv(programObject, GraphicsContext3D::LINK_STATUS, &linked));
- if (!linked) {
- LOG_ERROR("Failed to link shader program");
- GLC(context, context->deleteProgram(programObject));
- return 0;
- }
-
- GLC(context, context->deleteShader(vertexShader));
- GLC(context, context->deleteShader(fragmentShader));
- return programObject;
+ m_ccLayerImpl->setLayerRenderer(renderer);
}
void LayerChromium::setNeedsCommit()
@@ -317,16 +183,15 @@ int LayerChromium::indexOfSublayer(const LayerChromium* reference)
void LayerChromium::setBounds(const IntSize& size)
{
- if (m_bounds == size)
+ if (bounds() == size)
return;
- bool firstResize = !m_bounds.width() && !m_bounds.height() && size.width() && size.height();
+ bool firstResize = !bounds().width() && !bounds().height() && size.width() && size.height();
- m_bounds = size;
- m_backingStoreSize = size;
+ m_ccLayerImpl->setBounds(size);
if (firstResize)
- setNeedsDisplay(FloatRect(0, 0, m_bounds.width(), m_bounds.height()));
+ setNeedsDisplay(FloatRect(0, 0, bounds().width(), bounds().height()));
else
setNeedsCommit();
}
@@ -337,7 +202,7 @@ void LayerChromium::setFrame(const FloatRect& rect)
return;
m_frame = rect;
- setNeedsDisplay(FloatRect(0, 0, m_bounds.width(), m_bounds.height()));
+ setNeedsDisplay(FloatRect(0, 0, bounds().width(), bounds().height()));
}
const LayerChromium* LayerChromium::rootLayer() const
@@ -372,6 +237,12 @@ LayerChromium* LayerChromium::superlayer() const
return m_superlayer;
}
+void LayerChromium::setName(const String& name)
+{
+ m_name = name;
+ m_ccLayerImpl->setName(name);
+}
+
void LayerChromium::setNeedsDisplay(const FloatRect& dirtyRect)
{
// Simply mark the contents as dirty. For non-root layers, the call to
@@ -386,7 +257,7 @@ void LayerChromium::setNeedsDisplay(const FloatRect& dirtyRect)
void LayerChromium::setNeedsDisplay()
{
m_dirtyRect.setLocation(FloatPoint());
- m_dirtyRect.setSize(m_bounds);
+ m_dirtyRect.setSize(bounds());
m_contentsDirty = true;
setNeedsCommit();
}
@@ -445,38 +316,7 @@ void LayerChromium::drawTexturedQuad(GraphicsContext3D* context, const Transform
GLC(context, context->drawElements(GraphicsContext3D::TRIANGLES, 6, GraphicsContext3D::UNSIGNED_SHORT, 0));
}
-void LayerChromium::drawDebugBorder()
-{
- static float glMatrix[16];
- if (!borderColor().alpha())
- return;
-
- ASSERT(layerRenderer());
- const SharedValues* sv = layerRenderer()->layerSharedValues();
- ASSERT(sv && sv->initialized());
- layerRenderer()->useShader(sv->borderShaderProgram());
- TransformationMatrix renderMatrix = drawTransform();
- renderMatrix.scale3d(bounds().width(), bounds().height(), 1);
- toGLMatrix(&glMatrix[0], layerRenderer()->projectionMatrix() * renderMatrix);
- GraphicsContext3D* context = layerRendererContext();
- GLC(context, context->uniformMatrix4fv(sv->borderShaderMatrixLocation(), false, &glMatrix[0], 1));
-
- GLC(context, context->uniform4f(sv->borderShaderColorLocation(), borderColor().red() / 255.0, borderColor().green() / 255.0, borderColor().blue() / 255.0, 1));
- GLC(context, context->lineWidth(borderWidth()));
-
- // The indices for the line are stored in the same array as the triangle indices.
- GLC(context, context->drawElements(GraphicsContext3D::LINE_LOOP, 4, GraphicsContext3D::UNSIGNED_SHORT, 6 * sizeof(unsigned short)));
-}
-
-const IntRect LayerChromium::getDrawRect() const
-{
- // Form the matrix used by the shader to map the corners of the layer's
- // bounds into the view space.
- FloatRect layerRect(-0.5 * bounds().width(), -0.5 * bounds().height(), bounds().width(), bounds().height());
- IntRect mappedRect = enclosingIntRect(drawTransform().mapRect(layerRect));
- return mappedRect;
-}
// Returns true if any of the layer's descendants has drawable content.
bool LayerChromium::descendantsDrawContent()
@@ -501,19 +341,92 @@ bool LayerChromium::descendantsDrawContentRecursive()
return false;
}
-// static
-void LayerChromium::prepareForDraw(const SharedValues* sv)
+String LayerChromium::layerTreeAsText() const
+{
+ TextStream ts;
+ dumpLayer(ts, 0);
+ return ts.release();
+}
+
+static void writeIndent(TextStream& ts, int indent)
+{
+ for (int i = 0; i != indent; ++i)
+ ts << " ";
+}
+
+void LayerChromium::dumpLayer(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << layerTypeAsString() << "(" << m_name << ")\n";
+ dumpLayerProperties(ts, indent+2);
+ m_ccLayerImpl->dumpLayerProperties(ts, indent+2);
+ if (m_replicaLayer) {
+ writeIndent(ts, indent+2);
+ ts << "Replica:\n";
+ m_replicaLayer->dumpLayer(ts, indent+3);
+ }
+ if (m_maskLayer) {
+ writeIndent(ts, indent+2);
+ ts << "Mask:\n";
+ m_maskLayer->dumpLayer(ts, indent+3);
+ }
+ for (size_t i = 0; i < m_sublayers.size(); ++i)
+ m_sublayers[i]->dumpLayer(ts, indent+1);
+}
+
+void LayerChromium::dumpLayerProperties(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+#ifndef NDEBUG
+ ts << "debugID: " << debugID() << ", ";
+#else
+#endif
+ ts << "drawsContent: " << drawsContent() << "\n";
+
+}
+
+// Begin calls that forward to the CCLayerImpl.
+// ==============================================
+// These exists just for debugging (via drawDebugBorder()).
+void LayerChromium::setBorderColor(const Color& color)
+{
+ m_ccLayerImpl->setDebugBorderColor(color);
+ setNeedsCommit();
+}
+
+Color LayerChromium::borderColor() const
+{
+ return m_ccLayerImpl->debugBorderColor();
+}
+
+void LayerChromium::setBorderWidth(float width)
+{
+ m_ccLayerImpl->setDebugBorderWidth(width);
+ setNeedsCommit();
+}
+
+float LayerChromium::borderWidth() const
+{
+ return m_ccLayerImpl->debugBorderWidth();
+}
+
+LayerRendererChromium* LayerChromium::layerRenderer() const
+{
+ return m_ccLayerImpl->layerRenderer();
+}
+
+void LayerChromium::setDoubleSided(bool doubleSided)
+{
+ m_ccLayerImpl->setDoubleSided(doubleSided);
+ setNeedsCommit();
+}
+
+const IntSize& LayerChromium::bounds() const
{
- GraphicsContext3D* context = sv->context();
- GLC(context, context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, sv->quadVerticesVbo()));
- GLC(context, context->bindBuffer(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, sv->quadElementsVbo()));
- unsigned offset = 0;
- GLC(context, context->vertexAttribPointer(s_positionAttribLocation, 3, GraphicsContext3D::FLOAT, false, 5 * sizeof(float), offset));
- offset += 3 * sizeof(float);
- GLC(context, context->vertexAttribPointer(s_texCoordAttribLocation, 2, GraphicsContext3D::FLOAT, false, 5 * sizeof(float), offset));
- GLC(context, context->enableVertexAttribArray(s_positionAttribLocation));
- GLC(context, context->enableVertexAttribArray(s_texCoordAttribLocation));
+ return m_ccLayerImpl->bounds();
}
+// ==============================================
+// End calls that forward to the CCLayerImpl.
}
#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/chromium/LayerChromium.h b/Source/WebCore/platform/graphics/chromium/LayerChromium.h
index 5c7e2b1..29a2165 100644
--- a/Source/WebCore/platform/graphics/chromium/LayerChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/LayerChromium.h
@@ -38,13 +38,17 @@
#include "GraphicsContext.h"
#include "GraphicsLayerChromium.h"
#include "PlatformString.h"
+#include "ProgramBinding.h"
#include "RenderSurfaceChromium.h"
+#include "ShaderChromium.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>
+#include <wtf/text/WTFString.h>
namespace skia {
@@ -53,13 +57,13 @@ class PlatformCanvas;
namespace WebCore {
+class CCLayerImpl;
class GraphicsContext3D;
class LayerRendererChromium;
// Base class for composited layers. Special layer types are derived from
// this class.
class LayerChromium : public RefCounted<LayerChromium> {
- friend class LayerRendererChromium;
friend class LayerTilerChromium;
public:
static PassRefPtr<LayerChromium> create(GraphicsLayerChromium* owner = 0);
@@ -85,21 +89,9 @@ public:
void setBackgroundColor(const Color& color) { m_backgroundColor = color; setNeedsCommit(); }
Color backgroundColor() const { return m_backgroundColor; }
- void setBorderColor(const Color& color) { m_borderColor = color; setNeedsCommit(); }
- Color borderColor() const { return m_borderColor; }
-
- void setBorderWidth(float width) { m_borderWidth = width; setNeedsCommit(); }
- float borderWidth() const { return m_borderWidth; }
-
- void setBounds(const IntSize&);
- IntSize bounds() const { return m_bounds; }
-
void setClearsContext(bool clears) { m_clearsContext = clears; setNeedsCommit(); }
bool clearsContext() const { return m_clearsContext; }
- void setDoubleSided(bool doubleSided) { m_doubleSided = doubleSided; setNeedsCommit(); }
- bool doubleSided() const { return m_doubleSided; }
-
void setFrame(const FloatRect&);
FloatRect frame() const { return m_frame; }
@@ -109,10 +101,11 @@ public:
void setMasksToBounds(bool masksToBounds) { m_masksToBounds = masksToBounds; }
bool masksToBounds() const { return m_masksToBounds; }
- void setName(const String& name) { m_name = name; }
- String name() const { return m_name; }
+ void setName(const String&);
+ const String& name() const { return m_name; }
void setMaskLayer(LayerChromium* maskLayer) { m_maskLayer = maskLayer; }
+ CCLayerImpl* maskDrawLayer() const { return m_maskLayer ? m_maskLayer->ccLayerImpl() : 0; }
LayerChromium* maskLayer() const { return m_maskLayer.get(); }
void setNeedsDisplay(const FloatRect& dirtyRect);
@@ -144,75 +137,60 @@ public:
void setGeometryFlipped(bool flipped) { m_geometryFlipped = flipped; setNeedsCommit(); }
bool geometryFlipped() const { return m_geometryFlipped; }
- const TransformationMatrix& drawTransform() const { return m_drawTransform; }
- float drawOpacity() const { return m_drawOpacity; }
-
bool preserves3D() { return m_owner && m_owner->preserves3D(); }
// Derived types must override this method if they need to react to a change
// in the LayerRendererChromium.
virtual void setLayerRenderer(LayerRendererChromium*);
+ // Returns true if any of the layer's descendants has content to draw.
+ bool descendantsDrawContent();
+
void setOwner(GraphicsLayerChromium* owner) { m_owner = owner; }
void setReplicaLayer(LayerChromium* layer) { m_replicaLayer = layer; }
LayerChromium* replicaLayer() { return m_replicaLayer; }
- // Returns the rect containtaining this layer in the current view's coordinate system.
- const IntRect getDrawRect() const;
-
// These methods typically need to be overwritten by derived classes.
- virtual bool drawsContent() { return false; }
+ virtual bool drawsContent() const { return false; }
virtual void updateContentsIfDirty() { }
virtual void unreserveContentsTexture() { }
virtual void bindContentsTexture() { }
virtual void draw() { }
+ // These exists just for debugging (via drawDebugBorder()).
+ void setBorderColor(const Color&);
+ Color borderColor() const;
+
+#ifndef NDEBUG
+ int debugID() const { return m_debugID; }
+#endif
+
void drawDebugBorder();
+ String layerTreeAsText() const;
+
+ void setBorderWidth(float);
+ float borderWidth() const;
+
+ // Everything from here down in the public section will move to CCLayerImpl.
- RenderSurfaceChromium* createRenderSurface();
-
- // Stores values that are shared between instances of this class that are
- // associated with the same LayerRendererChromium (and hence the same GL
- // context).
- class SharedValues {
- public:
- explicit SharedValues(GraphicsContext3D*);
- ~SharedValues();
-
- GraphicsContext3D* context() const { return m_context; }
- unsigned quadVerticesVbo() const { return m_quadVerticesVbo; }
- unsigned quadElementsVbo() const { return m_quadElementsVbo; }
- int maxTextureSize() const { return m_maxTextureSize; }
- unsigned borderShaderProgram() const { return m_borderShaderProgram; }
- int borderShaderMatrixLocation() const { return m_borderShaderMatrixLocation; }
- int borderShaderColorLocation() const { return m_borderShaderColorLocation; }
- bool initialized() const { return m_initialized; }
-
- private:
- GraphicsContext3D* m_context;
- unsigned m_quadVerticesVbo;
- unsigned m_quadElementsVbo;
- int m_maxTextureSize;
- unsigned m_borderShaderProgram;
- int m_borderShaderMatrixLocation;
- int m_borderShaderColorLocation;
- bool m_initialized;
- };
-
- static void prepareForDraw(const SharedValues*);
-
- LayerRendererChromium* layerRenderer() const { return m_layerRenderer.get(); }
-
- static unsigned createShaderProgram(GraphicsContext3D*, const char* vertexShaderSource, const char* fragmentShaderSource);
+ CCLayerImpl* ccLayerImpl() const { return m_ccLayerImpl.get(); }
static void drawTexturedQuad(GraphicsContext3D*, const TransformationMatrix& projectionMatrix, const TransformationMatrix& layerMatrix,
float width, float height, float opacity,
int matrixLocation, int alphaLocation);
+ // Begin calls that forward to the CCLayerImpl.
+ LayerRendererChromium* layerRenderer() const;
+ void setDoubleSided(bool);
+ void setBounds(const IntSize&);
+ const IntSize& bounds() const;
+ // End calls that forward to the CCLayerImpl.
+
+ typedef ProgramBinding<VertexShaderPos, FragmentShaderColor> BorderProgram;
protected:
GraphicsLayerChromium* m_owner;
- LayerChromium(GraphicsLayerChromium* owner);
+ explicit LayerChromium(GraphicsLayerChromium* owner);
// This is called to clean up resources being held in the same context as
// layerRendererContext(). Subclasses should override this method if they
@@ -221,23 +199,18 @@ protected:
GraphicsContext3D* layerRendererContext() const;
- // Returns true if any of the layer's descendants has content to draw.
- bool descendantsDrawContent();
-
static void toGLMatrix(float*, const TransformationMatrix&);
- IntSize m_bounds;
+ void dumpLayer(TextStream&, int indent) const;
+
+ virtual const char* layerTypeAsString() const { return "LayerChromium"; }
+ virtual void dumpLayerProperties(TextStream&, int indent) const;
+
FloatRect m_dirtyRect;
bool m_contentsDirty;
RefPtr<LayerChromium> m_maskLayer;
- // Render surface this layer draws into. This is a surface that can belong
- // either to this layer (if m_targetRenderSurface == m_renderSurface) or
- // to an ancestor of this layer. The target render surface determines the
- // coordinate system the layer's transforms are relative to.
- RenderSurfaceChromium* m_targetRenderSurface;
-
// All layer shaders share the same attribute locations for the vertex positions
// and texture coordinates. This allows switching shaders without rebinding attribute
// arrays.
@@ -265,48 +238,30 @@ private:
Vector<RefPtr<LayerChromium> > m_sublayers;
LayerChromium* m_superlayer;
+#ifndef NDEBUG
+ int m_debugID;
+#endif
+
// Layer properties.
- IntSize m_backingStoreSize;
FloatPoint m_position;
FloatPoint m_anchorPoint;
Color m_backgroundColor;
- Color m_borderColor;
float m_opacity;
float m_zPosition;
float m_anchorPointZ;
- float m_borderWidth;
- float m_drawOpacity;
bool m_clearsContext;
- bool m_doubleSided;
bool m_hidden;
bool m_masksToBounds;
bool m_opaque;
bool m_geometryFlipped;
bool m_needsDisplayOnBoundsChange;
- // The global depth value of the center of the layer. This value is used
- // to sort layers from back to front.
- float m_drawDepth;
-
- // Points to the layer renderer that updates and draws this layer.
- RefPtr<LayerRendererChromium> m_layerRenderer;
-
- FloatRect m_frame;
TransformationMatrix m_transform;
TransformationMatrix m_sublayerTransform;
- TransformationMatrix m_drawTransform;
-
- // The scissor rectangle that should be used when this layer is drawn.
- // Inherited by the parent layer and further restricted if this layer masks
- // to bounds.
- IntRect m_scissorRect;
- // Render surface associated with this layer. The layer and its descendants
- // will render to this surface.
- OwnPtr<RenderSurfaceChromium> m_renderSurface;
-
- // Hierarchical bounding rect containing the layer and its descendants.
- IntRect m_drawableContentRect;
+ FloatRect m_frame;
+ // For now, the LayerChromium directly owns its CCLayerImpl.
+ RefPtr<CCLayerImpl> m_ccLayerImpl;
// Replica layer used for reflections.
LayerChromium* m_replicaLayer;
diff --git a/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp b/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
index f5548c9..e7b299f 100644
--- a/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
@@ -34,14 +34,18 @@
#if USE(ACCELERATED_COMPOSITING)
#include "LayerRendererChromium.h"
+#include "cc/CCLayerImpl.h"
#include "Canvas2DLayerChromium.h"
+#include "GeometryBinding.h"
#include "GraphicsContext3D.h"
#include "LayerChromium.h"
#include "LayerTexture.h"
#include "NotImplemented.h"
+#include "TextStream.h"
#include "TextureManager.h"
#include "WebGLLayerChromium.h"
-#if PLATFORM(SKIA)
+#include "cc/CCLayerImpl.h"
+#if USE(SKIA)
#include "NativeImageSkia.h"
#include "PlatformContextSkia.h"
#elif PLATFORM(CG)
@@ -82,9 +86,9 @@ static bool isScaleOrTranslation(const TransformationMatrix& m)
}
-bool LayerRendererChromium::compareLayerZ(const LayerChromium* a, const LayerChromium* b)
+bool LayerRendererChromium::compareLayerZ(const CCLayerImpl* a, const CCLayerImpl* b)
{
- return a->m_drawDepth < b->m_drawDepth;
+ return a->drawDepth() < b->drawDepth();
}
PassRefPtr<LayerRendererChromium> LayerRendererChromium::create(PassRefPtr<GraphicsContext3D> context)
@@ -100,9 +104,7 @@ PassRefPtr<LayerRendererChromium> LayerRendererChromium::create(PassRefPtr<Graph
}
LayerRendererChromium::LayerRendererChromium(PassRefPtr<GraphicsContext3D> context)
- : m_rootLayerTextureWidth(0)
- , m_rootLayerTextureHeight(0)
- , m_rootLayer(0)
+ : m_rootLayer(0)
, m_scrollPosition(IntPoint(-1, -1))
, m_currentShader(0)
, m_currentRenderSurface(0)
@@ -112,12 +114,15 @@ LayerRendererChromium::LayerRendererChromium(PassRefPtr<GraphicsContext3D> conte
, m_defaultRenderSurface(0)
{
m_hardwareCompositing = initializeSharedObjects();
- m_rootLayerTiler = LayerTilerChromium::create(this, IntSize(256, 256));
+ m_rootLayerTiler = LayerTilerChromium::create(this, IntSize(256, 256), LayerTilerChromium::NoBorderTexels);
ASSERT(m_rootLayerTiler);
+
+ m_headsUpDisplay = CCHeadsUpDisplay::create(this);
}
LayerRendererChromium::~LayerRendererChromium()
{
+ m_headsUpDisplay.clear(); // Explicitly destroy the HUD before the TextureManager dies.
cleanupSharedObjects();
}
@@ -172,71 +177,125 @@ void LayerRendererChromium::invalidateRootLayerRect(const IntRect& dirtyRect, co
}
}
-void LayerRendererChromium::updateAndDrawRootLayer(TilePaintInterface& tilePaint, TilePaintInterface& scrollbarPaint, const IntRect& visibleRect, const IntRect& contentRect)
+void LayerRendererChromium::updateRootLayerContents(TilePaintInterface& tilePaint, const IntRect& visibleRect)
{
m_rootLayerTiler->update(tilePaint, visibleRect);
- m_rootLayerTiler->draw(visibleRect);
+}
+void LayerRendererChromium::updateRootLayerScrollbars(TilePaintInterface& scrollbarPaint, const IntRect& visibleRect, const IntRect& contentRect)
+{
if (visibleRect.width() > contentRect.width()) {
IntRect verticalScrollbar = verticalScrollbarRect(visibleRect, contentRect);
IntSize tileSize = verticalScrollbar.size().shrunkTo(IntSize(m_maxTextureSize, m_maxTextureSize));
if (!m_verticalScrollbarTiler)
- m_verticalScrollbarTiler = LayerTilerChromium::create(this, tileSize);
+ m_verticalScrollbarTiler = LayerTilerChromium::create(this, tileSize, LayerTilerChromium::NoBorderTexels);
else
m_verticalScrollbarTiler->setTileSize(tileSize);
m_verticalScrollbarTiler->setLayerPosition(verticalScrollbar.location());
m_verticalScrollbarTiler->update(scrollbarPaint, visibleRect);
- m_verticalScrollbarTiler->draw(visibleRect);
- }
+ } else
+ m_verticalScrollbarTiler.clear();
if (visibleRect.height() > contentRect.height()) {
IntRect horizontalScrollbar = horizontalScrollbarRect(visibleRect, contentRect);
IntSize tileSize = horizontalScrollbar.size().shrunkTo(IntSize(m_maxTextureSize, m_maxTextureSize));
if (!m_horizontalScrollbarTiler)
- m_horizontalScrollbarTiler = LayerTilerChromium::create(this, tileSize);
+ m_horizontalScrollbarTiler = LayerTilerChromium::create(this, tileSize, LayerTilerChromium::NoBorderTexels);
else
m_horizontalScrollbarTiler->setTileSize(tileSize);
m_horizontalScrollbarTiler->setLayerPosition(horizontalScrollbar.location());
m_horizontalScrollbarTiler->update(scrollbarPaint, visibleRect);
- m_horizontalScrollbarTiler->draw(visibleRect);
- }
+ } else
+ m_horizontalScrollbarTiler.clear();
+}
+
+void LayerRendererChromium::drawRootLayer()
+{
+ m_rootLayerTiler->draw(m_visibleRect);
+
+ if (m_verticalScrollbarTiler)
+ m_verticalScrollbarTiler->draw(m_visibleRect);
+
+ if (m_horizontalScrollbarTiler)
+ m_horizontalScrollbarTiler->draw(m_visibleRect);
}
-void LayerRendererChromium::drawLayers(const IntRect& visibleRect, const IntRect& contentRect,
- const IntPoint& scrollPosition, TilePaintInterface& tilePaint,
- TilePaintInterface& scrollbarPaint)
+void LayerRendererChromium::updateAndDrawLayers(const IntRect& visibleRect, const IntRect& contentRect, const IntPoint& scrollPosition,
+ TilePaintInterface& tilePaint, TilePaintInterface& scrollbarPaint)
{
ASSERT(m_hardwareCompositing);
if (!m_rootLayer)
return;
- makeContextCurrent();
+ updateRootLayerContents(tilePaint, visibleRect);
+ // Recheck that we still have a root layer. This may become null if
+ // compositing gets turned off during a paint operation.
+ if (!m_rootLayer)
+ return;
+
+ updateRootLayerScrollbars(scrollbarPaint, visibleRect, contentRect);
+
+ Vector<CCLayerImpl*> renderSurfaceLayerList;
+ updateLayers(visibleRect, contentRect, scrollPosition, renderSurfaceLayerList);
+
+ drawLayers(renderSurfaceLayerList);
+}
+
+void LayerRendererChromium::updateLayers(const IntRect& visibleRect, const IntRect& contentRect, const IntPoint& scrollPosition,
+ Vector<CCLayerImpl*>& renderSurfaceLayerList)
+{
+ CCLayerImpl* rootDrawLayer = m_rootLayer->ccLayerImpl();
+
+ if (!rootDrawLayer->renderSurface())
+ rootDrawLayer->createRenderSurface();
+ ASSERT(rootDrawLayer->renderSurface());
// If the size of the visible area has changed then allocate a new texture
// to store the contents of the root layer and adjust the projection matrix
// and viewport.
- int visibleRectWidth = visibleRect.width();
- int visibleRectHeight = visibleRect.height();
-
- if (!m_rootLayer->m_renderSurface)
- m_rootLayer->createRenderSurface();
- m_rootLayer->m_renderSurface->m_contentRect = IntRect(0, 0, visibleRectWidth, visibleRectHeight);
- if (visibleRectWidth != m_rootLayerTextureWidth || visibleRectHeight != m_rootLayerTextureHeight) {
- m_rootLayerTextureWidth = visibleRectWidth;
- m_rootLayerTextureHeight = visibleRectHeight;
+ rootDrawLayer->renderSurface()->m_contentRect = IntRect(IntPoint(0, 0), visibleRect.size());
+ if (visibleRect.size() != m_visibleRect.size()) {
// Reset the current render surface to force an update of the viewport and
// projection matrix next time useRenderSurface is called.
m_currentRenderSurface = 0;
}
+ m_visibleRect = visibleRect;
+
+ m_scrollPosition = scrollPosition;
+ // Scissor out the scrollbars to avoid rendering on top of them.
+ IntRect rootScissorRect(contentRect);
+ // The scissorRect should not include the scroll offset.
+ rootScissorRect.move(-m_scrollPosition.x(), -m_scrollPosition.y());
+ rootDrawLayer->setScissorRect(rootScissorRect);
+
+ m_defaultRenderSurface = rootDrawLayer->renderSurface();
+
+ renderSurfaceLayerList.append(rootDrawLayer);
+
+ TransformationMatrix identityMatrix;
+ m_defaultRenderSurface->m_layerList.clear();
+ // Unfortunately, updatePropertiesAndRenderSurfaces() currently both updates the layers and updates the draw state
+ // (transforms, etc). It'd be nicer if operations on the presentation layers happened later, but the draw
+ // transforms are needed by large layers to determine visibility. Tiling will fix this by eliminating the
+ // concept of a large content layer.
+ updatePropertiesAndRenderSurfaces(m_rootLayer.get(), identityMatrix, renderSurfaceLayerList, m_defaultRenderSurface->m_layerList);
+
+ updateContentsRecursive(m_rootLayer.get());
+}
+
+void LayerRendererChromium::drawLayers(const Vector<CCLayerImpl*>& renderSurfaceLayerList)
+{
+ CCLayerImpl* rootDrawLayer = m_rootLayer->ccLayerImpl();
+ makeContextCurrent();
// The GL viewport covers the entire visible area, including the scrollbars.
- GLC(m_context.get(), m_context->viewport(0, 0, visibleRectWidth, visibleRectHeight));
+ GLC(m_context.get(), m_context->viewport(0, 0, m_visibleRect.width(), m_visibleRect.height()));
// Bind the common vertex attributes used for drawing all the layers.
- LayerChromium::prepareForDraw(layerSharedValues());
+ m_sharedGeometry->prepareForDraw();
// FIXME: These calls can be made once, when the compositor context is initialized.
GLC(m_context.get(), m_context->disable(GraphicsContext3D::DEPTH_TEST));
@@ -245,11 +304,6 @@ void LayerRendererChromium::drawLayers(const IntRect& visibleRect, const IntRect
// Blending disabled by default. Root layer alpha channel on Windows is incorrect when Skia uses ClearType.
GLC(m_context.get(), m_context->disable(GraphicsContext3D::BLEND));
- m_scrollPosition = scrollPosition;
-
- ASSERT(m_rootLayer->m_renderSurface);
- m_defaultRenderSurface = m_rootLayer->m_renderSurface.get();
-
useRenderSurface(m_defaultRenderSurface);
// Clear to blue to make it easier to spot unrendered regions.
@@ -260,66 +314,49 @@ void LayerRendererChromium::drawLayers(const IntRect& visibleRect, const IntRect
// zero alpha values on text glyphs. The root layer is always opaque.
m_context->colorMask(true, true, true, false);
- updateAndDrawRootLayer(tilePaint, scrollbarPaint, visibleRect, contentRect);
+ drawRootLayer();
// Re-enable color writes to layers, which may be partially transparent.
m_context->colorMask(true, true, true, true);
- // Recheck that we still have a root layer. This may become null if
- // compositing gets turned off during a paint operation.
- if (!m_rootLayer)
- return;
-
- // Set the root visible/content rects --- used by subsequent drawLayers calls.
- m_rootVisibleRect = visibleRect;
- m_rootContentRect = contentRect;
-
- // Scissor out the scrollbars to avoid rendering on top of them.
- IntRect rootScissorRect(contentRect);
- // The scissorRect should not include the scroll offset.
- rootScissorRect.move(-m_scrollPosition.x(), -m_scrollPosition.y());
- m_rootLayer->m_scissorRect = rootScissorRect;
-
- Vector<LayerChromium*> renderSurfaceLayerList;
- renderSurfaceLayerList.append(m_rootLayer.get());
-
- TransformationMatrix identityMatrix;
- m_defaultRenderSurface->m_layerList.clear();
- updateLayersRecursive(m_rootLayer.get(), identityMatrix, renderSurfaceLayerList, m_defaultRenderSurface->m_layerList);
-
- // The shader used to render layers returns pre-multiplied alpha colors
- // so we need to send the blending mode appropriately.
GLC(m_context.get(), m_context->enable(GraphicsContext3D::BLEND));
- GLC(m_context.get(), m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA));
GLC(m_context.get(), m_context->enable(GraphicsContext3D::SCISSOR_TEST));
// Update the contents of the render surfaces. We traverse the array from
// back to front to guarantee that nested render surfaces get rendered in the
// correct order.
for (int surfaceIndex = renderSurfaceLayerList.size() - 1; surfaceIndex >= 0 ; --surfaceIndex) {
- LayerChromium* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex];
- ASSERT(renderSurfaceLayer->m_renderSurface);
+ CCLayerImpl* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex];
+ ASSERT(renderSurfaceLayer->renderSurface());
// Render surfaces whose drawable area has zero width or height
// will have no layers associated with them and should be skipped.
- if (!renderSurfaceLayer->m_renderSurface->m_layerList.size())
+ if (!renderSurfaceLayer->renderSurface()->m_layerList.size())
continue;
- if (useRenderSurface(renderSurfaceLayer->m_renderSurface.get())) {
- if (renderSurfaceLayer != m_rootLayer) {
+ if (useRenderSurface(renderSurfaceLayer->renderSurface())) {
+ if (renderSurfaceLayer != rootDrawLayer) {
GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST));
GLC(m_context.get(), m_context->clearColor(0, 0, 0, 0));
GLC(m_context.get(), m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT));
GLC(m_context.get(), m_context->enable(GraphicsContext3D::SCISSOR_TEST));
}
- Vector<LayerChromium*>& layerList = renderSurfaceLayer->m_renderSurface->m_layerList;
+ Vector<CCLayerImpl*>& layerList = renderSurfaceLayer->renderSurface()->m_layerList;
ASSERT(layerList.size());
for (unsigned layerIndex = 0; layerIndex < layerList.size(); ++layerIndex)
- drawLayer(layerList[layerIndex], renderSurfaceLayer->m_renderSurface.get());
+ drawLayer(layerList[layerIndex], renderSurfaceLayer->renderSurface());
}
}
+ if (m_headsUpDisplay->enabled()) {
+ GLC(m_context.get(), m_context->enable(GraphicsContext3D::BLEND));
+ GLC(m_context.get(), m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA));
+ GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST));
+ useRenderSurface(m_defaultRenderSurface);
+ m_headsUpDisplay->draw();
+ }
+
GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST));
GLC(m_context.get(), m_context->disable(GraphicsContext3D::BLEND));
}
@@ -336,11 +373,15 @@ void LayerRendererChromium::present()
// Note that currently this has the same effect as swapBuffers; we should
// consider exposing a different entry point on GraphicsContext3D.
m_context->prepareTexture();
+
+ m_headsUpDisplay->onPresent();
}
void LayerRendererChromium::setRootLayer(PassRefPtr<LayerChromium> layer)
{
m_rootLayer = layer;
+ if (m_rootLayer)
+ m_rootLayer->setLayerRenderer(this);
m_rootLayerTiler->invalidateEntireLayer();
if (m_horizontalScrollbarTiler)
m_horizontalScrollbarTiler->invalidateEntireLayer();
@@ -350,8 +391,7 @@ void LayerRendererChromium::setRootLayer(PassRefPtr<LayerChromium> layer)
void LayerRendererChromium::getFramebufferPixels(void *pixels, const IntRect& rect)
{
- ASSERT(rect.maxX() <= rootLayerTextureSize().width()
- && rect.maxY() <= rootLayerTextureSize().height());
+ ASSERT(rect.maxX() <= visibleRectSize().width() && rect.maxY() <= visibleRectSize().height());
if (!pixels)
return;
@@ -404,9 +444,10 @@ bool LayerRendererChromium::isLayerVisible(LayerChromium* layer, const Transform
// Recursively walks the layer tree starting at the given node and computes all the
// necessary transformations, scissor rectangles, render surfaces, etc.
-void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const TransformationMatrix& parentMatrix, Vector<LayerChromium*>& renderSurfaceLayerList, Vector<LayerChromium*>& layerList)
+void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* layer, const TransformationMatrix& parentMatrix, Vector<CCLayerImpl*>& renderSurfaceLayerList, Vector<CCLayerImpl*>& layerList)
{
layer->setLayerRenderer(this);
+ CCLayerImpl* drawLayer = layer->ccLayerImpl();
// Compute the new matrix transformation that will be applied to this layer and
// all its sublayers. It's important to remember that the layer's position
@@ -459,25 +500,26 @@ void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const Tr
// of their parent.
bool useSurfaceForClipping = layer->masksToBounds() && !isScaleOrTranslation(combinedTransform);
bool useSurfaceForOpacity = layer->opacity() != 1 && !layer->preserves3D();
- bool useSurfaceForMasking = layer->maskLayer();
+ bool useSurfaceForMasking = layer->maskDrawLayer();
bool useSurfaceForReflection = layer->replicaLayer();
if (((useSurfaceForClipping || useSurfaceForOpacity) && layer->descendantsDrawContent())
|| useSurfaceForMasking || useSurfaceForReflection) {
- RenderSurfaceChromium* renderSurface = layer->m_renderSurface.get();
+ RenderSurfaceChromium* renderSurface = drawLayer->renderSurface();
if (!renderSurface)
- renderSurface = layer->createRenderSurface();
+ renderSurface = drawLayer->createRenderSurface();
// The origin of the new surface is the upper left corner of the layer.
- layer->m_drawTransform = TransformationMatrix();
- layer->m_drawTransform.translate3d(0.5 * bounds.width(), 0.5 * bounds.height(), 0);
+ TransformationMatrix drawTransform;
+ drawTransform.translate3d(0.5 * bounds.width(), 0.5 * bounds.height(), 0);
+ drawLayer->setDrawTransform(drawTransform);
transformedLayerRect = IntRect(0, 0, bounds.width(), bounds.height());
// Layer's opacity will be applied when drawing the render surface.
renderSurface->m_drawOpacity = layer->opacity();
- if (layer->superlayer()->preserves3D())
- renderSurface->m_drawOpacity *= layer->superlayer()->drawOpacity();
- layer->m_drawOpacity = 1;
+ if (layer->superlayer() && layer->superlayer()->preserves3D())
+ renderSurface->m_drawOpacity *= drawLayer->superlayer()->drawOpacity();
+ drawLayer->setDrawOpacity(1);
TransformationMatrix layerOriginTransform = combinedTransform;
layerOriginTransform.translate3d(-0.5 * bounds.width(), -0.5 * bounds.height(), 0);
@@ -485,69 +527,72 @@ void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const Tr
if (layerOriginTransform.isInvertible() && layer->superlayer()) {
TransformationMatrix parentToLayer = layerOriginTransform.inverse();
- layer->m_scissorRect = parentToLayer.mapRect(layer->superlayer()->m_scissorRect);
+ drawLayer->setScissorRect(parentToLayer.mapRect(drawLayer->superlayer()->scissorRect()));
} else
- layer->m_scissorRect = IntRect();
+ drawLayer->setScissorRect(IntRect());
// The render surface scissor rect is the scissor rect that needs to
// be applied before drawing the render surface onto its containing
// surface and is therefore expressed in the superlayer's coordinate system.
- renderSurface->m_scissorRect = layer->superlayer()->m_scissorRect;
+ renderSurface->m_scissorRect = drawLayer->superlayer() ? drawLayer->superlayer()->scissorRect() : drawLayer->scissorRect();
renderSurface->m_layerList.clear();
- if (layer->maskLayer()) {
- renderSurface->m_maskLayer = layer->maskLayer();
- layer->maskLayer()->setLayerRenderer(this);
- layer->maskLayer()->m_targetRenderSurface = renderSurface;
+ if (layer->maskDrawLayer()) {
+ renderSurface->m_maskLayer = layer->maskDrawLayer();
+ layer->maskDrawLayer()->setLayerRenderer(this);
+ layer->maskDrawLayer()->setTargetRenderSurface(renderSurface);
} else
renderSurface->m_maskLayer = 0;
- if (layer->replicaLayer() && layer->replicaLayer()->maskLayer()) {
- layer->replicaLayer()->maskLayer()->setLayerRenderer(this);
- layer->replicaLayer()->maskLayer()->m_targetRenderSurface = renderSurface;
+ if (layer->replicaLayer() && layer->replicaLayer()->maskDrawLayer()) {
+ layer->replicaLayer()->maskDrawLayer()->setLayerRenderer(this);
+ layer->replicaLayer()->maskDrawLayer()->setTargetRenderSurface(renderSurface);
}
- renderSurfaceLayerList.append(layer);
+ renderSurfaceLayerList.append(drawLayer);
} else {
// DT = M[p] * LT
- layer->m_drawTransform = combinedTransform;
- transformedLayerRect = enclosingIntRect(layer->m_drawTransform.mapRect(layerRect));
+ drawLayer->setDrawTransform(combinedTransform);
+ transformedLayerRect = enclosingIntRect(drawLayer->drawTransform().mapRect(layerRect));
- layer->m_drawOpacity = layer->opacity();
+ drawLayer->setDrawOpacity(layer->opacity());
if (layer->superlayer()) {
if (layer->superlayer()->preserves3D())
- layer->m_drawOpacity *= layer->superlayer()->m_drawOpacity;
+ drawLayer->setDrawOpacity(drawLayer->drawOpacity() * drawLayer->superlayer()->drawOpacity());
// Layers inherit the scissor rect from their superlayer.
- layer->m_scissorRect = layer->superlayer()->m_scissorRect;
+ drawLayer->setScissorRect(drawLayer->superlayer()->scissorRect());
- layer->m_targetRenderSurface = layer->superlayer()->m_targetRenderSurface;
+ drawLayer->setTargetRenderSurface(drawLayer->superlayer()->targetRenderSurface());
}
if (layer != m_rootLayer)
- layer->m_renderSurface = 0;
+ drawLayer->clearRenderSurface();
- if (layer->masksToBounds())
- layer->m_scissorRect.intersect(transformedLayerRect);
+ if (layer->masksToBounds()) {
+ IntRect scissor = drawLayer->scissorRect();
+ scissor.intersect(transformedLayerRect);
+ drawLayer->setScissorRect(scissor);
+ }
}
- if (layer->m_renderSurface)
- layer->m_targetRenderSurface = layer->m_renderSurface.get();
+ if (drawLayer->renderSurface())
+ drawLayer->setTargetRenderSurface(drawLayer->renderSurface());
else {
ASSERT(layer->superlayer());
- layer->m_targetRenderSurface = layer->superlayer()->m_targetRenderSurface;
+ drawLayer->setTargetRenderSurface(drawLayer->superlayer()->targetRenderSurface());
}
- // m_drawableContentRect is always stored in the coordinate system of the
+ // drawableContentRect() is always stored in the coordinate system of the
// RenderSurface the layer draws into.
- if (layer->drawsContent())
- layer->m_drawableContentRect = transformedLayerRect;
+ if (drawLayer->drawsContent())
+ drawLayer->setDrawableContentRect(transformedLayerRect);
else
- layer->m_drawableContentRect = IntRect();
+ drawLayer->setDrawableContentRect(IntRect());
- TransformationMatrix sublayerMatrix = layer->m_drawTransform;
+ TransformationMatrix sublayerMatrix = drawLayer->drawTransform();
// Flatten to 2D if the layer doesn't preserve 3D.
if (!layer->preserves3D()) {
@@ -568,37 +613,46 @@ void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const Tr
// M[s] = M * Tr[-center]
sublayerMatrix.translate3d(-bounds.width() * 0.5, -bounds.height() * 0.5, 0);
- Vector<LayerChromium*>& descendants = (layer->m_renderSurface ? layer->m_renderSurface->m_layerList : layerList);
- descendants.append(layer);
+ Vector<CCLayerImpl*>& descendants = (drawLayer->renderSurface() ? drawLayer->renderSurface()->m_layerList : layerList);
+ descendants.append(drawLayer);
unsigned thisLayerIndex = descendants.size() - 1;
const Vector<RefPtr<LayerChromium> >& sublayers = layer->getSublayers();
for (size_t i = 0; i < sublayers.size(); ++i) {
- LayerChromium* sublayer = sublayers[i].get();
- updateLayersRecursive(sublayer, sublayerMatrix, renderSurfaceLayerList, descendants);
-
- if (sublayer->m_renderSurface) {
- RenderSurfaceChromium* sublayerRenderSurface = sublayer->m_renderSurface.get();
- layer->m_drawableContentRect.unite(enclosingIntRect(sublayerRenderSurface->drawableContentRect()));
+ CCLayerImpl* sublayer = sublayers[i]->ccLayerImpl();
+ updatePropertiesAndRenderSurfaces(sublayers[i].get(), sublayerMatrix, renderSurfaceLayerList, descendants);
+
+ if (sublayer->renderSurface()) {
+ RenderSurfaceChromium* sublayerRenderSurface = sublayer->renderSurface();
+ IntRect drawableContentRect = drawLayer->drawableContentRect();
+ drawableContentRect.unite(enclosingIntRect(sublayerRenderSurface->drawableContentRect()));
+ drawLayer->setDrawableContentRect(drawableContentRect);
descendants.append(sublayer);
- } else
- layer->m_drawableContentRect.unite(sublayer->m_drawableContentRect);
+ } else {
+ IntRect drawableContentRect = drawLayer->drawableContentRect();
+ drawableContentRect.unite(sublayer->drawableContentRect());
+ drawLayer->setDrawableContentRect(drawableContentRect);
+ }
}
- if (layer->masksToBounds() || useSurfaceForMasking)
- layer->m_drawableContentRect.intersect(transformedLayerRect);
+ if (layer->masksToBounds() || useSurfaceForMasking) {
+ IntRect drawableContentRect = drawLayer->drawableContentRect();
+ drawableContentRect.intersect(transformedLayerRect);
+ drawLayer->setDrawableContentRect(drawableContentRect);
+ }
- if (layer->m_renderSurface && layer != m_rootLayer) {
- RenderSurfaceChromium* renderSurface = layer->m_renderSurface.get();
- renderSurface->m_contentRect = layer->m_drawableContentRect;
+ if (drawLayer->renderSurface() && layer != m_rootLayer) {
+ RenderSurfaceChromium* renderSurface = drawLayer->renderSurface();
+ renderSurface->m_contentRect = drawLayer->drawableContentRect();
FloatPoint surfaceCenter = renderSurface->contentRectCenter();
// Restrict the RenderSurface size to the portion that's visible.
FloatSize centerOffsetDueToClipping;
+
// Don't clip if the layer is reflected as the reflection shouldn't be
// clipped.
if (!layer->replicaLayer()) {
- renderSurface->m_contentRect.intersect(layer->m_scissorRect);
+ renderSurface->m_contentRect.intersect(drawLayer->scissorRect());
FloatPoint clippedSurfaceCenter = renderSurface->contentRectCenter();
centerOffsetDueToClipping = clippedSurfaceCenter - surfaceCenter;
}
@@ -613,7 +667,7 @@ void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const Tr
// Since the layer starts a new render surface we need to adjust its
// scissor rect to be expressed in the new surface's coordinate system.
- layer->m_scissorRect = layer->m_drawableContentRect;
+ drawLayer->setScissorRect(drawLayer->drawableContentRect());
// Adjust the origin of the transform to be the center of the render surface.
renderSurface->m_drawTransform = renderSurface->m_originTransform;
@@ -631,14 +685,14 @@ void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const Tr
// Compute the depth value of the center of the layer which will be used when
// sorting the layers for the preserves-3d property.
- TransformationMatrix& layerDrawMatrix = layer->m_renderSurface ? layer->m_renderSurface->m_drawTransform : layer->m_drawTransform;
+ const TransformationMatrix& layerDrawMatrix = drawLayer->renderSurface() ? drawLayer->renderSurface()->m_drawTransform : drawLayer->drawTransform();
if (layer->superlayer()) {
if (!layer->superlayer()->preserves3D())
- layer->m_drawDepth = layer->superlayer()->m_drawDepth;
+ drawLayer->setDrawDepth(drawLayer->superlayer()->drawDepth());
else
- layer->m_drawDepth = layerDrawMatrix.m43();
+ drawLayer->setDrawDepth(layerDrawMatrix.m43());
} else
- layer->m_drawDepth = 0;
+ drawLayer->setDrawDepth(0);
// If preserves-3d then sort all the descendants by the Z coordinate of their
// center. If the preserves-3d property is also set on the superlayer then
@@ -647,21 +701,50 @@ void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const Tr
std::stable_sort(&descendants.at(thisLayerIndex), descendants.end(), compareLayerZ);
}
+void LayerRendererChromium::updateContentsRecursive(LayerChromium* layer)
+{
+ const Vector<RefPtr<LayerChromium> >& sublayers = layer->getSublayers();
+ for (size_t i = 0; i < sublayers.size(); ++i)
+ updateContentsRecursive(sublayers[i].get());
+
+ if (layer->drawsContent())
+ layer->updateContentsIfDirty();
+ if (layer->maskLayer() && layer->maskLayer()->drawsContent())
+ layer->maskLayer()->updateContentsIfDirty();
+ if (layer->replicaLayer() && layer->replicaLayer()->drawsContent())
+ layer->replicaLayer()->updateContentsIfDirty();
+ if (layer->replicaLayer() && layer->replicaLayer()->maskLayer() && layer->replicaLayer()->maskLayer()->drawsContent())
+ layer->replicaLayer()->maskLayer()->updateContentsIfDirty();
+}
+
void LayerRendererChromium::setCompositeOffscreen(bool compositeOffscreen)
{
+ if (m_compositeOffscreen == compositeOffscreen)
+ return;
+
m_compositeOffscreen = compositeOffscreen;
- if (!m_rootLayer) {
- m_compositeOffscreen = false;
- return;
- }
+ if (!m_compositeOffscreen && m_rootLayer)
+ m_rootLayer->ccLayerImpl()->clearRenderSurface();
+}
+
+LayerTexture* LayerRendererChromium::getOffscreenLayerTexture()
+{
+ return m_compositeOffscreen ? m_rootLayer->ccLayerImpl()->renderSurface()->m_contentsTexture.get() : 0;
+}
+void LayerRendererChromium::copyOffscreenTextureToDisplay()
+{
if (m_compositeOffscreen) {
- // Need to explicitly set a LayerRendererChromium for the layer with the offscreen texture,
- // or else the call to prepareContentsTexture() in useRenderSurface() will fail.
- m_rootLayer->setLayerRenderer(this);
- } else
- m_rootLayer->m_renderSurface.clear();
+ makeContextCurrent();
+
+ useRenderSurface(0);
+ m_defaultRenderSurface->m_drawTransform.makeIdentity();
+ m_defaultRenderSurface->m_drawTransform.translate3d(0.5 * m_defaultRenderSurface->m_contentRect.width(),
+ 0.5 * m_defaultRenderSurface->m_contentRect.height(), 0);
+ m_defaultRenderSurface->m_drawOpacity = 1;
+ m_defaultRenderSurface->draw();
+ }
}
bool LayerRendererChromium::useRenderSurface(RenderSurfaceChromium* renderSurface)
@@ -671,9 +754,12 @@ bool LayerRendererChromium::useRenderSurface(RenderSurfaceChromium* renderSurfac
m_currentRenderSurface = renderSurface;
- if (renderSurface == m_defaultRenderSurface && !m_compositeOffscreen) {
+ if ((renderSurface == m_defaultRenderSurface && !m_compositeOffscreen) || (!renderSurface && m_compositeOffscreen)) {
GLC(m_context.get(), m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0));
- setDrawViewportRect(renderSurface->m_contentRect, true);
+ if (renderSurface)
+ setDrawViewportRect(renderSurface->m_contentRect, true);
+ else
+ setDrawViewportRect(m_defaultRenderSurface->m_contentRect, true);
return true;
}
@@ -695,36 +781,32 @@ bool LayerRendererChromium::useRenderSurface(RenderSurfaceChromium* renderSurfac
return true;
}
-void LayerRendererChromium::drawLayer(LayerChromium* layer, RenderSurfaceChromium* targetSurface)
+void LayerRendererChromium::drawLayer(CCLayerImpl* layer, RenderSurfaceChromium* targetSurface)
{
- if (layer->m_renderSurface && layer->m_renderSurface != targetSurface) {
- layer->m_renderSurface->draw();
+ if (layer->renderSurface() && layer->renderSurface() != targetSurface) {
+ layer->renderSurface()->draw();
return;
}
- if (layer->m_bounds.isEmpty())
+ if (layer->bounds().isEmpty())
return;
- setScissorToRect(layer->m_scissorRect);
+ setScissorToRect(layer->scissorRect());
// Check if the layer falls within the visible bounds of the page.
IntRect layerRect = layer->getDrawRect();
- bool isLayerVisible = layer->m_scissorRect.intersects(layerRect);
+ bool isLayerVisible = layer->scissorRect().intersects(layerRect);
if (!isLayerVisible)
return;
// FIXME: Need to take into account the commulative render surface transforms all the way from
// the default render surface in order to determine visibility.
- TransformationMatrix combinedDrawMatrix = (layer->m_renderSurface ? layer->m_renderSurface->drawTransform().multiply(layer->m_drawTransform) : layer->m_drawTransform);
+ TransformationMatrix combinedDrawMatrix = (layer->renderSurface() ? layer->renderSurface()->drawTransform().multiply(layer->drawTransform()) : layer->drawTransform());
if (!layer->doubleSided() && combinedDrawMatrix.m33() < 0)
return;
- if (layer->drawsContent()) {
- // Update the contents of the layer if necessary.
- layer->updateContentsIfDirty();
- m_context->makeContextCurrent();
+ if (layer->drawsContent())
layer->draw();
- }
// Draw the debug border if there is one.
layer->drawDebugBorder();
@@ -734,9 +816,11 @@ void LayerRendererChromium::drawLayer(LayerChromium* layer, RenderSurfaceChromiu
// scissorRect has its origin at the top left corner of the current visible rect.
void LayerRendererChromium::setScissorToRect(const IntRect& scissorRect)
{
+ IntRect contentRect = (m_currentRenderSurface ? m_currentRenderSurface->m_contentRect : m_defaultRenderSurface->m_contentRect);
+
// The scissor coordinates must be supplied in viewport space so we need to offset
// by the relative position of the top left corner of the current render surface.
- int scissorX = scissorRect.x() - m_currentRenderSurface->m_contentRect.x();
+ int scissorX = scissorRect.x() - contentRect.x();
// When rendering to the default render surface we're rendering upside down so the top
// of the GL scissor is the bottom of our layer.
// But, if rendering to offscreen texture, we reverse our sense of 'upside down'.
@@ -744,7 +828,7 @@ void LayerRendererChromium::setScissorToRect(const IntRect& scissorRect)
if (m_currentRenderSurface == m_defaultRenderSurface && !m_compositeOffscreen)
scissorY = m_currentRenderSurface->m_contentRect.height() - (scissorRect.maxY() - m_currentRenderSurface->m_contentRect.y());
else
- scissorY = scissorRect.y() - m_currentRenderSurface->m_contentRect.y();
+ scissorY = scissorRect.y() - contentRect.y();
GLC(m_context.get(), m_context->scissor(scissorX, scissorY, scissorRect.width(), scissorRect.height()));
}
@@ -793,15 +877,23 @@ bool LayerRendererChromium::initializeSharedObjects()
// Create an FBO for doing offscreen rendering.
GLC(m_context.get(), m_offscreenFramebufferId = m_context->createFramebuffer());
- m_layerSharedValues = adoptPtr(new LayerChromium::SharedValues(m_context.get()));
- m_contentLayerSharedValues = adoptPtr(new ContentLayerChromium::SharedValues(m_context.get()));
- m_canvasLayerSharedValues = adoptPtr(new CanvasLayerChromium::SharedValues(m_context.get()));
- m_videoLayerSharedValues = adoptPtr(new VideoLayerChromium::SharedValues(m_context.get()));
- m_pluginLayerSharedValues = adoptPtr(new PluginLayerChromium::SharedValues(m_context.get()));
- m_renderSurfaceSharedValues = adoptPtr(new RenderSurfaceChromium::SharedValues(m_context.get()));
-
- if (!m_layerSharedValues->initialized() || !m_contentLayerSharedValues->initialized() || !m_canvasLayerSharedValues->initialized()
- || !m_videoLayerSharedValues->initialized() || !m_pluginLayerSharedValues->initialized() || !m_renderSurfaceSharedValues->initialized()) {
+ m_sharedGeometry = adoptPtr(new GeometryBinding(m_context.get()));
+ m_borderProgram = adoptPtr(new LayerChromium::BorderProgram(m_context.get()));
+ m_contentLayerProgram = adoptPtr(new ContentLayerChromium::Program(m_context.get()));
+ m_canvasLayerProgram = adoptPtr(new CanvasLayerChromium::Program(m_context.get()));
+ m_videoLayerRGBAProgram = adoptPtr(new VideoLayerChromium::RGBAProgram(m_context.get()));
+ m_videoLayerYUVProgram = adoptPtr(new VideoLayerChromium::YUVProgram(m_context.get()));
+ m_pluginLayerProgram = adoptPtr(new PluginLayerChromium::Program(m_context.get()));
+ m_renderSurfaceProgram = adoptPtr(new RenderSurfaceChromium::Program(m_context.get()));
+ m_renderSurfaceMaskProgram = adoptPtr(new RenderSurfaceChromium::MaskProgram(m_context.get()));
+ m_tilerProgram = adoptPtr(new LayerTilerChromium::Program(m_context.get()));
+
+ if (!m_sharedGeometry->initialized() || !m_borderProgram->initialized()
+ || !m_contentLayerProgram->initialized() || !m_canvasLayerProgram->initialized()
+ || !m_videoLayerRGBAProgram->initialized() || !m_videoLayerYUVProgram->initialized()
+ || !m_pluginLayerProgram->initialized() || !m_renderSurfaceProgram->initialized()
+ || !m_renderSurfaceMaskProgram->initialized() || !m_tilerProgram->initialized()) {
+ LOG_ERROR("Compositor failed to initialize shaders. Falling back to software.");
cleanupSharedObjects();
return false;
}
@@ -814,12 +906,16 @@ void LayerRendererChromium::cleanupSharedObjects()
{
makeContextCurrent();
- m_layerSharedValues.clear();
- m_contentLayerSharedValues.clear();
- m_canvasLayerSharedValues.clear();
- m_videoLayerSharedValues.clear();
- m_pluginLayerSharedValues.clear();
- m_renderSurfaceSharedValues.clear();
+ m_sharedGeometry.clear();
+ m_borderProgram.clear();
+ m_contentLayerProgram.clear();
+ m_canvasLayerProgram.clear();
+ m_videoLayerRGBAProgram.clear();
+ m_videoLayerYUVProgram.clear();
+ m_pluginLayerProgram.clear();
+ m_renderSurfaceProgram.clear();
+ m_renderSurfaceMaskProgram.clear();
+ m_tilerProgram.clear();
if (m_offscreenFramebufferId)
GLC(m_context.get(), m_context->deleteFramebuffer(m_offscreenFramebufferId));
@@ -831,6 +927,26 @@ void LayerRendererChromium::cleanupSharedObjects()
m_textureManager.clear();
}
+String LayerRendererChromium::layerTreeAsText() const
+{
+ TextStream ts;
+ if (m_rootLayer.get()) {
+ ts << m_rootLayer->layerTreeAsText();
+ ts << "RenderSurfaces:\n";
+ dumpRenderSurfaces(ts, 1, m_rootLayer.get());
+ }
+ return ts.release();
+}
+
+void LayerRendererChromium::dumpRenderSurfaces(TextStream& ts, int indent, LayerChromium* layer) const
+{
+ if (layer->ccLayerImpl()->renderSurface())
+ layer->ccLayerImpl()->renderSurface()->dumpSurface(ts, indent);
+
+ for (size_t i = 0; i < layer->getSublayers().size(); ++i)
+ dumpRenderSurfaces(ts, indent, layer->getSublayers()[i].get());
+}
+
} // namespace WebCore
#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h b/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h
index 3d3e784..7e8850a 100644
--- a/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h
@@ -43,6 +43,7 @@
#include "RenderSurfaceChromium.h"
#include "SkBitmap.h"
#include "VideoLayerChromium.h"
+#include "cc/CCHeadsUpDisplay.h"
#include <wtf/HashMap.h>
#include <wtf/Noncopyable.h>
#include <wtf/PassOwnPtr.h>
@@ -57,7 +58,10 @@
namespace WebCore {
+class CCLayerImpl;
+class GeometryBinding;
class GraphicsContext3D;
+class CCHeadsUpDisplay;
// Class that handles drawing of composited render layers using GL.
class LayerRendererChromium : public RefCounted<LayerRendererChromium> {
@@ -71,9 +75,8 @@ public:
void invalidateRootLayerRect(const IntRect& dirtyRect, const IntRect& visibleRect, const IntRect& contentRect);
// updates and draws the current layers onto the backbuffer
- void drawLayers(const IntRect& visibleRect, const IntRect& contentRect,
- const IntPoint& scrollPosition, TilePaintInterface& tilePaint,
- TilePaintInterface& scrollbarPaint);
+ void updateAndDrawLayers(const IntRect& visibleRect, const IntRect& contentRect, const IntPoint& scrollPosition,
+ TilePaintInterface&, TilePaintInterface& scrollbarPaint);
// waits for rendering to finish
void finish();
@@ -81,6 +84,8 @@ public:
// puts backbuffer onscreen
void present();
+ IntSize visibleRectSize() const { return m_visibleRect.size(); }
+
void setRootLayer(PassRefPtr<LayerChromium> layer);
LayerChromium* rootLayer() { return m_rootLayer.get(); }
void transferRootLayer(LayerRendererChromium* other) { other->m_rootLayer = m_rootLayer.release(); }
@@ -88,12 +93,9 @@ public:
bool hardwareCompositing() const { return m_hardwareCompositing; }
void setCompositeOffscreen(bool);
- bool isCompositingOffscreen() { return m_compositeOffscreen; }
- LayerTexture* getOffscreenLayerTexture() { return m_compositeOffscreen ? m_rootLayer->m_renderSurface->m_contentsTexture.get() : 0; }
-
- void setRootLayerCanvasSize(const IntSize&);
-
- GraphicsContext* rootLayerGraphicsContext() const { return m_rootLayerGraphicsContext.get(); }
+ bool isCompositingOffscreen() const { return m_compositeOffscreen; }
+ LayerTexture* getOffscreenLayerTexture();
+ void copyOffscreenTextureToDisplay();
unsigned createLayerTexture();
void deleteLayerTexture(unsigned);
@@ -106,30 +108,43 @@ public:
bool checkTextureSize(const IntSize&);
- const LayerChromium::SharedValues* layerSharedValues() const { return m_layerSharedValues.get(); }
- const ContentLayerChromium::SharedValues* contentLayerSharedValues() const { return m_contentLayerSharedValues.get(); }
- const CanvasLayerChromium::SharedValues* canvasLayerSharedValues() const { return m_canvasLayerSharedValues.get(); }
- const VideoLayerChromium::SharedValues* videoLayerSharedValues() const { return m_videoLayerSharedValues.get(); }
- const PluginLayerChromium::SharedValues* pluginLayerSharedValues() const { return m_pluginLayerSharedValues.get(); }
- const RenderSurfaceChromium::SharedValues* renderSurfaceSharedValues() const { return m_renderSurfaceSharedValues.get(); }
+ const GeometryBinding* sharedGeometry() const { return m_sharedGeometry.get(); }
+ const LayerChromium::BorderProgram* borderProgram() const { return m_borderProgram.get(); }
+ const ContentLayerChromium::Program* contentLayerProgram() const { return m_contentLayerProgram.get(); }
+ const CanvasLayerChromium::Program* canvasLayerProgram() const { return m_canvasLayerProgram.get(); }
+ const VideoLayerChromium::RGBAProgram* videoLayerRGBAProgram() const { return m_videoLayerRGBAProgram.get(); }
+ const VideoLayerChromium::YUVProgram* videoLayerYUVProgram() const { return m_videoLayerYUVProgram.get(); }
+ const PluginLayerChromium::Program* pluginLayerProgram() const { return m_pluginLayerProgram.get(); }
+ const RenderSurfaceChromium::Program* renderSurfaceProgram() const { return m_renderSurfaceProgram.get(); }
+ const RenderSurfaceChromium::MaskProgram* renderSurfaceMaskProgram() const { return m_renderSurfaceMaskProgram.get(); }
+ const LayerTilerChromium::Program* tilerProgram() const { return m_tilerProgram.get(); }
void resizeOnscreenContent(const IntSize&);
- IntSize rootLayerTextureSize() const { return IntSize(m_rootLayerTextureWidth, m_rootLayerTextureHeight); }
- IntRect rootLayerContentRect() const { return m_rootContentRect; }
void getFramebufferPixels(void *pixels, const IntRect& rect);
TextureManager* textureManager() const { return m_textureManager.get(); }
+ CCHeadsUpDisplay* headsUpDisplay() { return m_headsUpDisplay.get(); }
+
void setScissorToRect(const IntRect&);
+ String layerTreeAsText() const;
+
private:
explicit LayerRendererChromium(PassRefPtr<GraphicsContext3D> graphicsContext3D);
- void updateLayersRecursive(LayerChromium* layer, const TransformationMatrix& parentMatrix, Vector<LayerChromium*>& renderSurfaceLayerList, Vector<LayerChromium*>& layerList);
- void drawLayer(LayerChromium*, RenderSurfaceChromium*);
+ void updateLayers(const IntRect& visibleRect, const IntRect& contentRect, const IntPoint& scrollPosition,
+ Vector<CCLayerImpl*>& renderSurfaceLayerList);
+ void updateRootLayerContents(TilePaintInterface&, const IntRect& visibleRect);
+ void updateRootLayerScrollbars(TilePaintInterface& scrollbarPaint, const IntRect& visibleRect, const IntRect& contentRect);
+ void updatePropertiesAndRenderSurfaces(LayerChromium*, const TransformationMatrix& parentMatrix, Vector<CCLayerImpl*>& renderSurfaceLayerList, Vector<CCLayerImpl*>& layerList);
+ void updateContentsRecursive(LayerChromium*);
- void updateAndDrawRootLayer(TilePaintInterface& tilePaint, TilePaintInterface& scrollbarPaint, const IntRect& visibleRect, const IntRect& contentRect);
+ void drawLayers(const Vector<CCLayerImpl*>& renderSurfaceLayerList);
+ void drawLayer(CCLayerImpl*, RenderSurfaceChromium*);
+
+ void drawRootLayer();
bool isLayerVisible(LayerChromium*, const TransformationMatrix&, const IntRect& visibleRect);
@@ -139,7 +154,9 @@ private:
bool makeContextCurrent();
- static bool compareLayerZ(const LayerChromium*, const LayerChromium*);
+ static bool compareLayerZ(const CCLayerImpl*, const CCLayerImpl*);
+
+ void dumpRenderSurfaces(TextStream&, int indent, LayerChromium*) const;
bool initializeSharedObjects();
void cleanupSharedObjects();
@@ -147,8 +164,7 @@ private:
static IntRect verticalScrollbarRect(const IntRect& visibleRect, const IntRect& contentRect);
static IntRect horizontalScrollbarRect(const IntRect& visibleRect, const IntRect& contentRect);
- int m_rootLayerTextureWidth;
- int m_rootLayerTextureHeight;
+ IntRect m_visibleRect;
TransformationMatrix m_projectionMatrix;
@@ -166,7 +182,7 @@ private:
unsigned m_offscreenFramebufferId;
bool m_compositeOffscreen;
-#if PLATFORM(SKIA)
+#if USE(SKIA)
OwnPtr<skia::PlatformCanvas> m_rootLayerCanvas;
OwnPtr<PlatformContextSkia> m_rootLayerSkiaContext;
OwnPtr<GraphicsContext> m_rootLayerGraphicsContext;
@@ -176,11 +192,6 @@ private:
OwnPtr<GraphicsContext> m_rootLayerGraphicsContext;
#endif
- IntSize m_rootLayerCanvasSize;
-
- IntRect m_rootVisibleRect;
- IntRect m_rootContentRect;
-
// Maximum texture dimensions supported.
int m_maxTextureSize;
@@ -188,15 +199,21 @@ private:
// associated with this instance of the compositor. Since there can be
// multiple instances of the compositor running in the same renderer process
// we cannot store these values in static variables.
- OwnPtr<LayerChromium::SharedValues> m_layerSharedValues;
- OwnPtr<ContentLayerChromium::SharedValues> m_contentLayerSharedValues;
- OwnPtr<CanvasLayerChromium::SharedValues> m_canvasLayerSharedValues;
- OwnPtr<VideoLayerChromium::SharedValues> m_videoLayerSharedValues;
- OwnPtr<PluginLayerChromium::SharedValues> m_pluginLayerSharedValues;
- OwnPtr<RenderSurfaceChromium::SharedValues> m_renderSurfaceSharedValues;
+ OwnPtr<GeometryBinding> m_sharedGeometry;
+ OwnPtr<LayerChromium::BorderProgram> m_borderProgram;
+ OwnPtr<ContentLayerChromium::Program> m_contentLayerProgram;
+ OwnPtr<CanvasLayerChromium::Program> m_canvasLayerProgram;
+ OwnPtr<VideoLayerChromium::RGBAProgram> m_videoLayerRGBAProgram;
+ OwnPtr<VideoLayerChromium::YUVProgram> m_videoLayerYUVProgram;
+ OwnPtr<PluginLayerChromium::Program> m_pluginLayerProgram;
+ OwnPtr<RenderSurfaceChromium::Program> m_renderSurfaceProgram;
+ OwnPtr<RenderSurfaceChromium::MaskProgram> m_renderSurfaceMaskProgram;
+ OwnPtr<LayerTilerChromium::Program> m_tilerProgram;
OwnPtr<TextureManager> m_textureManager;
+ OwnPtr<CCHeadsUpDisplay> m_headsUpDisplay;
+
RefPtr<GraphicsContext3D> m_context;
RenderSurfaceChromium* m_defaultRenderSurface;
diff --git a/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp b/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp
index e28c084..86592a6 100644
--- a/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp
@@ -35,27 +35,23 @@
#include "LayerRendererChromium.h"
#include "LayerTexture.h"
-#if PLATFORM(SKIA)
-#include "NativeImageSkia.h"
-#include "PlatformContextSkia.h"
-#elif PLATFORM(CG)
-#include <CoreGraphics/CGBitmapContext.h>
-#endif
-
#include <wtf/PassOwnArrayPtr.h>
+using namespace std;
+
namespace WebCore {
-PassOwnPtr<LayerTilerChromium> LayerTilerChromium::create(LayerRendererChromium* layerRenderer, const IntSize& tileSize)
+PassOwnPtr<LayerTilerChromium> LayerTilerChromium::create(LayerRendererChromium* layerRenderer, const IntSize& tileSize, BorderTexelOption border)
{
if (!layerRenderer || tileSize.isEmpty())
return 0;
- return adoptPtr(new LayerTilerChromium(layerRenderer, tileSize));
+ return adoptPtr(new LayerTilerChromium(layerRenderer, tileSize, border));
}
-LayerTilerChromium::LayerTilerChromium(LayerRendererChromium* layerRenderer, const IntSize& tileSize)
+LayerTilerChromium::LayerTilerChromium(LayerRendererChromium* layerRenderer, const IntSize& tileSize, BorderTexelOption border)
: m_skipsDraw(false)
+ , m_tilingData(max(tileSize.width(), tileSize.height()), 0, 0, border == HasBorderTexels)
, m_layerRenderer(layerRenderer)
{
setTileSize(tileSize);
@@ -81,6 +77,7 @@ void LayerTilerChromium::setTileSize(const IntSize& size)
m_tileSize = size;
m_tilePixels = adoptArrayPtr(new uint8_t[m_tileSize.width() * m_tileSize.height() * 4]);
+ m_tilingData.setMaxTextureSize(max(size.width(), size.height()));
}
void LayerTilerChromium::reset()
@@ -88,8 +85,7 @@ void LayerTilerChromium::reset()
m_tiles.clear();
m_unusedTiles.clear();
- m_layerSize = IntSize();
- m_layerTileSize = IntSize();
+ m_tilingData.setTotalSize(0, 0);
m_lastUpdateLayerRect = IntRect();
}
@@ -143,10 +139,10 @@ void LayerTilerChromium::contentRectToTileIndices(const IntRect& contentRect, in
{
const IntRect layerRect = contentRectToLayerRect(contentRect);
- left = layerRect.x() / m_tileSize.width();
- top = layerRect.y() / m_tileSize.height();
- right = (layerRect.maxX() - 1) / m_tileSize.width();
- bottom = (layerRect.maxY() - 1) / m_tileSize.height();
+ left = m_tilingData.tileXIndexFromSrcCoord(layerRect.x());
+ top = m_tilingData.tileYIndexFromSrcCoord(layerRect.y());
+ right = m_tilingData.tileXIndexFromSrcCoord(layerRect.maxX() - 1);
+ bottom = m_tilingData.tileYIndexFromSrcCoord(layerRect.maxY() - 1);
}
IntRect LayerTilerChromium::contentRectToLayerRect(const IntRect& contentRect) const
@@ -169,22 +165,32 @@ IntRect LayerTilerChromium::layerRectToContentRect(const IntRect& layerRect) con
int LayerTilerChromium::tileIndex(int i, int j) const
{
- ASSERT(i >= 0 && j >= 0 && i < m_layerTileSize.width() && j < m_layerTileSize.height());
- return i + j * m_layerTileSize.width();
+ return m_tilingData.tileIndex(i, j);
}
IntRect LayerTilerChromium::tileContentRect(int i, int j) const
{
- IntPoint anchor(m_layerPosition.x() + i * m_tileSize.width(), m_layerPosition.y() + j * m_tileSize.height());
- IntRect tile(anchor, m_tileSize);
- return tile;
+ IntRect contentRect = tileLayerRect(i, j);
+ contentRect.move(m_layerPosition.x(), m_layerPosition.y());
+ return contentRect;
}
IntRect LayerTilerChromium::tileLayerRect(int i, int j) const
{
- IntPoint anchor(i * m_tileSize.width(), j * m_tileSize.height());
- IntRect tile(anchor, m_tileSize);
- return tile;
+ const int index = m_tilingData.tileIndex(i, j);
+ IntRect layerRect = m_tilingData.tileBoundsWithBorder(index);
+ layerRect.setSize(m_tileSize);
+ return layerRect;
+}
+
+IntSize LayerTilerChromium::layerSize() const
+{
+ return IntSize(m_tilingData.totalSizeX(), m_tilingData.totalSizeY());
+}
+
+IntSize LayerTilerChromium::layerTileSize() const
+{
+ return IntSize(m_tilingData.numTilesX(), m_tilingData.numTilesY());
}
void LayerTilerChromium::invalidateRect(const IntRect& contentRect)
@@ -220,8 +226,7 @@ void LayerTilerChromium::invalidateEntireLayer()
}
m_tiles.clear();
- m_layerSize = IntSize();
- m_layerTileSize = IntSize();
+ m_tilingData.setTotalSize(0, 0);
m_lastUpdateLayerRect = IntRect();
}
@@ -258,55 +263,26 @@ void LayerTilerChromium::update(TilePaintInterface& painter, const IntRect& cont
return;
const IntRect paintRect = layerRectToContentRect(dirtyLayerRect);
- GraphicsContext3D* context = layerRendererContext();
-#if PLATFORM(SKIA)
- OwnPtr<skia::PlatformCanvas> canvas(new skia::PlatformCanvas(paintRect.width(), paintRect.height(), false));
- OwnPtr<PlatformContextSkia> skiaContext(new PlatformContextSkia(canvas.get()));
- OwnPtr<GraphicsContext> graphicsContext(new GraphicsContext(reinterpret_cast<PlatformGraphicsContext*>(skiaContext.get())));
-
- // Bring the canvas into the coordinate system of the paint rect.
- canvas->translate(static_cast<SkScalar>(-paintRect.x()), static_cast<SkScalar>(-paintRect.y()));
- painter.paint(*graphicsContext, paintRect);
+ m_canvas.resize(paintRect.size());
+ PlatformCanvas::Painter canvasPainter(&m_canvas);
+ canvasPainter.context()->translate(-paintRect.x(), -paintRect.y());
+ painter.paint(*canvasPainter.context(), paintRect);
- // Get the contents of the updated rect.
- const SkBitmap& bitmap = canvas->getDevice()->accessBitmap(false);
- ASSERT(bitmap.width() == paintRect.width() && bitmap.height() == paintRect.height());
- if (bitmap.width() != paintRect.width() || bitmap.height() != paintRect.height())
- CRASH();
- uint8_t* paintPixels = static_cast<uint8_t*>(bitmap.getPixels());
- if (!paintPixels)
- CRASH();
-#elif PLATFORM(CG)
- Vector<uint8_t> canvasPixels;
- int rowBytes = 4 * paintRect.width();
- canvasPixels.resize(rowBytes * paintRect.height());
- memset(canvasPixels.data(), 0, canvasPixels.size());
- RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB());
- RetainPtr<CGContextRef> m_cgContext;
- m_cgContext.adoptCF(CGBitmapContextCreate(canvasPixels.data(),
- paintRect.width(), paintRect.height(), 8, rowBytes,
- colorSpace.get(),
- kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host));
- CGContextTranslateCTM(m_cgContext.get(), 0, paintRect.height());
- CGContextScaleCTM(m_cgContext.get(), 1, -1);
- OwnPtr<GraphicsContext> m_graphicsContext(new GraphicsContext(m_cgContext.get()));
-
- // Bring the CoreGraphics context into the coordinate system of the paint rect.
- CGContextTranslateCTM(m_cgContext.get(), -paintRect.x(), -paintRect.y());
- painter.paint(*m_graphicsContext, paintRect);
-
- // Get the contents of the updated rect.
- ASSERT(static_cast<int>(CGBitmapContextGetWidth(m_cgContext.get())) == paintRect.width() && static_cast<int>(CGBitmapContextGetHeight(m_cgContext.get())) == paintRect.height());
- uint8_t* paintPixels = static_cast<uint8_t*>(canvasPixels.data());
-#else
-#error "Need to implement for your platform."
-#endif
+ PlatformCanvas::AutoLocker locker(&m_canvas);
+ updateFromPixels(paintRect, locker.pixels());
+}
+void LayerTilerChromium::updateFromPixels(const IntRect& paintRect, const uint8_t* paintPixels)
+{
// Painting could cause compositing to get turned off, which may cause the tiler to become invalidated mid-update.
if (!m_tiles.size())
return;
+ GraphicsContext3D* context = layerRendererContext();
+
+ int left, top, right, bottom;
+ contentRectToTileIndices(paintRect, left, top, right, bottom);
for (int j = top; j <= bottom; ++j) {
for (int i = left; i <= right; ++i) {
Tile* tile = m_tiles[tileIndex(i, j)].get();
@@ -346,7 +322,7 @@ void LayerTilerChromium::update(TilePaintInterface& painter, const IntRect& cont
if (paintOffset.y() + destRect.height() > paintRect.height())
CRASH();
- uint8_t* pixelSource;
+ const uint8_t* pixelSource;
if (paintRect.width() == sourceRect.width() && !paintOffset.x())
pixelSource = &paintPixels[4 * paintOffset.y() * paintRect.width()];
else {
@@ -361,6 +337,9 @@ void LayerTilerChromium::update(TilePaintInterface& painter, const IntRect& cont
}
tile->texture()->bindTexture();
+ GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::NEAREST));
+ GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::NEAREST));
+
GLC(context, context->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, destRect.x(), destRect.y(), destRect.width(), destRect.height(), GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixelSource));
tile->clearDirty();
@@ -378,26 +357,38 @@ void LayerTilerChromium::draw(const IntRect& contentRect)
if (m_skipsDraw || !m_tiles.size())
return;
- // We reuse the shader program used by ContentLayerChromium.
GraphicsContext3D* context = layerRendererContext();
- const ContentLayerChromium::SharedValues* contentLayerValues = layerRenderer()->contentLayerSharedValues();
- layerRenderer()->useShader(contentLayerValues->contentShaderProgram());
- GLC(context, context->uniform1i(contentLayerValues->shaderSamplerLocation(), 0));
+ const LayerTilerChromium::Program* program = layerRenderer()->tilerProgram();
+ layerRenderer()->useShader(program->program());
+ GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0));
int left, top, right, bottom;
contentRectToTileIndices(contentRect, left, top, right, bottom);
for (int j = top; j <= bottom; ++j) {
for (int i = left; i <= right; ++i) {
- Tile* tile = m_tiles[tileIndex(i, j)].get();
+ const int index = tileIndex(i, j);
+ Tile* tile = m_tiles[index].get();
ASSERT(tile);
tile->texture()->bindTexture();
TransformationMatrix tileMatrix;
- IntRect tileRect = tileContentRect(i, j);
+
+ // Don't use tileContentRect here, as that contains the full
+ // rect with border texels which shouldn't be drawn.
+ IntRect tileRect = m_tilingData.tileBounds(index);
+ tileRect.move(m_layerPosition.x(), m_layerPosition.y());
tileMatrix.translate3d(tileRect.x() - contentRect.x() + tileRect.width() / 2.0, tileRect.y() - contentRect.y() + tileRect.height() / 2.0, 0);
- LayerChromium::drawTexturedQuad(context, layerRenderer()->projectionMatrix(), tileMatrix, m_tileSize.width(), m_tileSize.height(), 1, contentLayerValues->shaderMatrixLocation(), contentLayerValues->shaderAlphaLocation());
+ IntPoint texOffset = m_tilingData.textureOffset(i, j);
+ float tileWidth = static_cast<float>(m_tileSize.width());
+ float tileHeight = static_cast<float>(m_tileSize.height());
+ float texTranslateX = texOffset.x() / tileWidth;
+ float texTranslateY = texOffset.y() / tileHeight;
+ float texScaleX = tileRect.width() / tileWidth;
+ float texScaleY = tileRect.height() / tileHeight;
+
+ drawTexturedQuad(context, layerRenderer()->projectionMatrix(), tileMatrix, tileRect.width(), tileRect.height(), 1, texTranslateX, texTranslateY, texScaleX, texScaleY, program);
tile->texture()->unreserve();
}
@@ -406,36 +397,63 @@ void LayerTilerChromium::draw(const IntRect& contentRect)
void LayerTilerChromium::resizeLayer(const IntSize& size)
{
- if (m_layerSize == size)
+ if (layerSize() == size)
return;
- int width = (size.width() + m_tileSize.width() - 1) / m_tileSize.width();
- int height = (size.height() + m_tileSize.height() - 1) / m_tileSize.height();
+ const IntSize oldTileSize = layerTileSize();
+ m_tilingData.setTotalSize(size.width(), size.height());
+ const IntSize newTileSize = layerTileSize();
+
+ if (oldTileSize == newTileSize)
+ return;
- if (height && (width > INT_MAX / height))
+ if (newTileSize.height() && (newTileSize.width() > INT_MAX / newTileSize.height()))
CRASH();
Vector<OwnPtr<Tile> > newTiles;
- newTiles.resize(width * height);
- for (int j = 0; j < m_layerTileSize.height(); ++j)
- for (int i = 0; i < m_layerTileSize.width(); ++i)
- newTiles[i + j * width].swap(m_tiles[i + j * m_layerTileSize.width()]);
-
+ newTiles.resize(newTileSize.width() * newTileSize.height());
+ for (int j = 0; j < oldTileSize.height(); ++j)
+ for (int i = 0; i < oldTileSize.width(); ++i)
+ newTiles[i + j * newTileSize.width()].swap(m_tiles[i + j * oldTileSize.width()]);
m_tiles.swap(newTiles);
- m_layerSize = size;
- m_layerTileSize = IntSize(width, height);
}
void LayerTilerChromium::growLayerToContain(const IntRect& contentRect)
{
// Grow the tile array to contain this content rect.
IntRect layerRect = contentRectToLayerRect(contentRect);
- IntSize layerSize = IntSize(layerRect.maxX(), layerRect.maxY());
+ IntSize rectSize = IntSize(layerRect.maxX(), layerRect.maxY());
- IntSize newSize = layerSize.expandedTo(m_layerSize);
+ IntSize newSize = rectSize.expandedTo(layerSize());
resizeLayer(newSize);
}
+void LayerTilerChromium::drawTexturedQuad(GraphicsContext3D* context, const TransformationMatrix& projectionMatrix, const TransformationMatrix& drawMatrix,
+ float width, float height, float opacity,
+ float texTranslateX, float texTranslateY,
+ float texScaleX, float texScaleY,
+ const LayerTilerChromium::Program* program)
+{
+ static float glMatrix[16];
+
+ TransformationMatrix renderMatrix = drawMatrix;
+
+ // Apply a scaling factor to size the quad from 1x1 to its intended size.
+ renderMatrix.scale3d(width, height, 1);
+
+ // Apply the projection matrix before sending the transform over to the shader.
+ LayerChromium::toGLMatrix(&glMatrix[0], projectionMatrix * renderMatrix);
+
+ GLC(context, context->uniformMatrix4fv(program->vertexShader().matrixLocation(), false, &glMatrix[0], 1));
+
+ GLC(context, context->uniform1f(program->fragmentShader().alphaLocation(), opacity));
+
+ GLC(context, context->uniform4f(program->vertexShader().texTransformLocation(),
+ texTranslateX, texTranslateY, texScaleX, texScaleY));
+
+ GLC(context, context->drawElements(GraphicsContext3D::TRIANGLES, 6, GraphicsContext3D::UNSIGNED_SHORT, 0));
+}
+
} // namespace WebCore
#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.h b/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.h
index e09693d..bdb35a5 100644
--- a/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.h
@@ -31,6 +31,8 @@
#include "LayerChromium.h"
#include "LayerTexture.h"
+#include "PlatformCanvas.h"
+#include "TilingData.h"
#include <wtf/OwnArrayPtr.h>
namespace WebCore {
@@ -46,13 +48,16 @@ public:
class LayerTilerChromium {
WTF_MAKE_NONCOPYABLE(LayerTilerChromium);
public:
- static PassOwnPtr<LayerTilerChromium> create(LayerRendererChromium* layerRenderer, const IntSize& tileSize);
+ enum BorderTexelOption { HasBorderTexels, NoBorderTexels };
+
+ static PassOwnPtr<LayerTilerChromium> create(LayerRendererChromium*, const IntSize& tileSize, BorderTexelOption);
~LayerTilerChromium();
void invalidateRect(const IntRect& contentRect);
void invalidateEntireLayer();
void update(TilePaintInterface& painter, const IntRect& contentRect);
+ void updateFromPixels(const IntRect& paintRect, const uint8_t* pixels);
void draw(const IntRect& contentRect);
// Set position of this tiled layer in content space.
@@ -60,8 +65,10 @@ public:
// Change the tile size. This may invalidate all the existing tiles.
void setTileSize(const IntSize& size);
+ typedef ProgramBinding<VertexShaderPosTexTransform, FragmentShaderTexAlpha> Program;
+
private:
- LayerTilerChromium(LayerRendererChromium* layerRenderer, const IntSize& tileSize);
+ LayerTilerChromium(LayerRendererChromium*, const IntSize& tileSize, BorderTexelOption);
class Tile {
WTF_MAKE_NONCOPYABLE(Tile);
@@ -79,6 +86,12 @@ private:
OwnPtr<LayerTexture> m_tex;
};
+ void drawTexturedQuad(GraphicsContext3D*, const TransformationMatrix& projectionMatrix, const TransformationMatrix& drawMatrix,
+ float width, float height, float opacity,
+ float texTranslateX, float texTranslateY,
+ float texScaleX, float texScaleY,
+ const LayerTilerChromium::Program*);
+
void resizeLayer(const IntSize& size);
// Grow layer size to contain this rectangle.
void growLayerToContain(const IntRect& contentRect);
@@ -100,9 +113,10 @@ private:
// Returns the bounds in layer space for a given tile location.
IntRect tileLayerRect(int i, int j) const;
+ IntSize layerSize() const;
+ IntSize layerTileSize() const;
+
IntSize m_tileSize;
- IntSize m_layerSize;
- IntSize m_layerTileSize;
IntRect m_lastUpdateLayerRect;
IntPoint m_layerPosition;
@@ -113,9 +127,13 @@ private:
// Linear array of unused tiles.
Vector<OwnPtr<Tile> > m_unusedTiles;
+ PlatformCanvas m_canvas;
+
// Cache a tile-sized pixel buffer to draw into.
OwnArrayPtr<uint8_t> m_tilePixels;
+ TilingData m_tilingData;
+
LayerRendererChromium* m_layerRenderer;
};
diff --git a/Source/WebCore/platform/graphics/chromium/PlatformCanvas.cpp b/Source/WebCore/platform/graphics/chromium/PlatformCanvas.cpp
new file mode 100644
index 0000000..29589f4
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/PlatformCanvas.cpp
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2011 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS 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 APPLE OR ITS 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 "PlatformCanvas.h"
+
+#include "GraphicsContext.h"
+
+#if USE(SKIA)
+#include "NativeImageSkia.h"
+#include "PlatformContextSkia.h"
+#include "SkColorPriv.h"
+#include "skia/ext/platform_canvas.h"
+#elif PLATFORM(CG)
+#include <CoreGraphics/CGBitmapContext.h>
+#endif
+
+namespace WebCore {
+
+PlatformCanvas::PlatformCanvas()
+{
+}
+
+PlatformCanvas::~PlatformCanvas()
+{
+}
+
+void PlatformCanvas::resize(const IntSize& size)
+{
+ m_size = size;
+#if USE(SKIA)
+ m_skiaCanvas = new skia::PlatformCanvas(size.width(), size.height(), false);
+#elif PLATFORM(CG)
+ size_t bufferSize = size.width() * size.height() * 4;
+ m_pixelData = adoptArrayPtr(new uint8_t[bufferSize]);
+ memset(m_pixelData.get(), 0, bufferSize);
+#endif
+}
+
+PlatformCanvas::AutoLocker::AutoLocker(PlatformCanvas* canvas)
+ : m_canvas(canvas)
+ , m_pixels(0)
+{
+#if USE(SKIA)
+ if (m_canvas->m_skiaCanvas) {
+ m_bitmap = &m_canvas->m_skiaCanvas->getDevice()->accessBitmap(false);
+ m_bitmap->lockPixels();
+
+ if (m_bitmap->config() == SkBitmap::kARGB_8888_Config)
+ m_pixels = static_cast<uint8_t*>(m_bitmap->getPixels());
+ } else
+ m_bitmap = 0;
+#elif PLATFORM(CG)
+ m_pixels = &canvas->m_pixelData[0];
+#endif
+}
+
+PlatformCanvas::AutoLocker::~AutoLocker()
+{
+#if USE(SKIA)
+ if (m_bitmap)
+ m_bitmap->unlockPixels();
+#endif
+}
+
+PlatformCanvas::Painter::Painter(PlatformCanvas* canvas)
+{
+#if USE(SKIA)
+ m_skiaContext = adoptPtr(new PlatformContextSkia(canvas->m_skiaCanvas.get()));
+
+ // This is needed to get text to show up correctly.
+ m_skiaContext->setDrawingToImageBuffer(true);
+
+ m_context = adoptPtr(new GraphicsContext(reinterpret_cast<PlatformGraphicsContext*>(m_skiaContext.get())));
+#elif PLATFORM(CG)
+
+ m_colorSpace = CGColorSpaceCreateDeviceRGB();
+ size_t rowBytes = canvas->size().width() * 4;
+ m_contextCG = CGBitmapContextCreate(canvas->m_pixelData.get(),
+ canvas->size().width(), canvas->size().height(), 8, rowBytes,
+ m_colorSpace.get(),
+ kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host);
+ CGContextTranslateCTM(m_contextCG.get(), 0, canvas->size().height());
+ CGContextScaleCTM(m_contextCG.get(), 1, -1);
+ m_context = adoptPtr(new GraphicsContext(m_contextCG.get()));
+#endif
+}
+
+PlatformCanvas::Painter::~Painter()
+{
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/chromium/PlatformCanvas.h b/Source/WebCore/platform/graphics/chromium/PlatformCanvas.h
new file mode 100644
index 0000000..262fdd0
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/PlatformCanvas.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2011 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS 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 APPLE OR ITS 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 PlatformCanvas_h
+#define PlatformCanvas_h
+
+#include "IntSize.h"
+#include <stdint.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/OwnPtr.h>
+
+#if PLATFORM(CG)
+#include <CoreGraphics/CGColorSpace.h>
+#include <CoreGraphics/CGContext.h>
+#include <wtf/OwnArrayPtr.h>
+#include <wtf/RetainPtr.h>
+#endif
+
+#if USE(SKIA)
+namespace skia { class PlatformCanvas; }
+class SkBitmap;
+#endif
+
+namespace WebCore {
+
+class GraphicsContext;
+
+#if USE(SKIA)
+class PlatformContextSkia;
+#endif
+
+// A 2D buffer of pixels with an associated GraphicsContext.
+class PlatformCanvas {
+ WTF_MAKE_NONCOPYABLE(PlatformCanvas);
+public:
+ PlatformCanvas();
+ ~PlatformCanvas();
+
+ // Scoped lock class to get temporary access to this canvas's pixels.
+ class AutoLocker {
+ WTF_MAKE_NONCOPYABLE(AutoLocker);
+ public:
+ explicit AutoLocker(PlatformCanvas*);
+ ~AutoLocker();
+
+ const uint8_t* pixels() const { return m_pixels; }
+ private:
+ PlatformCanvas* m_canvas;
+#if USE(SKIA)
+ const SkBitmap* m_bitmap;
+#endif
+ uint8_t* m_pixels;
+ };
+
+ // Scoped lock class to get temporary access to paint into this canvas.
+ class Painter {
+ WTF_MAKE_NONCOPYABLE(Painter);
+ public:
+ explicit Painter(PlatformCanvas*);
+ ~Painter();
+
+ GraphicsContext* context() const { return m_context.get(); }
+ private:
+ OwnPtr<GraphicsContext> m_context;
+#if USE(SKIA)
+ OwnPtr<PlatformContextSkia> m_skiaContext;
+#elif PLATFORM(CG)
+ RetainPtr<CGColorSpaceRef> m_colorSpace;
+ RetainPtr<CGContextRef> m_contextCG;
+#endif
+ };
+
+ void resize(const IntSize&);
+ IntSize size() const { return m_size; }
+
+private:
+#if USE(SKIA)
+ OwnPtr<skia::PlatformCanvas> m_skiaCanvas;
+#elif PLATFORM(CG)
+ OwnArrayPtr<uint8_t> m_pixelData;
+#endif
+ IntSize m_size;
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/WebCore/platform/graphics/chromium/PlatformImage.cpp b/Source/WebCore/platform/graphics/chromium/PlatformImage.cpp
new file mode 100644
index 0000000..62cf4f8
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/PlatformImage.cpp
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2011 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS 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 APPLE OR ITS 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 "PlatformImage.h"
+
+#if USE(SKIA)
+#include "NativeImageSkia.h"
+#include "PlatformContextSkia.h"
+#elif PLATFORM(CG)
+#include <CoreGraphics/CGBitmapContext.h>
+#include <CoreGraphics/CGContext.h>
+#include <CoreGraphics/CGImage.h>
+#include <wtf/RetainPtr.h>
+#else
+#error "Need to implement for your platform"
+#endif
+
+namespace WebCore {
+
+PlatformImage::PlatformImage()
+{
+}
+
+void PlatformImage::updateFromImage(NativeImagePtr nativeImage)
+{
+#if USE(SKIA)
+ // The layer contains an Image.
+ NativeImageSkia* skiaImage = static_cast<NativeImageSkia*>(nativeImage);
+ const SkBitmap* skiaBitmap = skiaImage;
+
+ IntSize bitmapSize(skiaBitmap->width(), skiaBitmap->height());
+ ASSERT(skiaBitmap);
+#elif PLATFORM(CG)
+ // NativeImagePtr is a CGImageRef on Mac OS X.
+ int width = CGImageGetWidth(nativeImage);
+ int height = CGImageGetHeight(nativeImage);
+ IntSize bitmapSize(width, height);
+#endif
+
+ size_t bufferSize = bitmapSize.width() * bitmapSize.height() * 4;
+ if (m_size != bitmapSize) {
+ m_pixelData = adoptArrayPtr(new uint8_t[bufferSize]);
+ memset(m_pixelData.get(), 0, bufferSize);
+ m_size = bitmapSize;
+ }
+
+#if USE(SKIA)
+ SkAutoLockPixels lock(*skiaBitmap);
+ // FIXME: do we need to support more image configurations?
+ ASSERT(skiaBitmap->config()== SkBitmap::kARGB_8888_Config);
+ skiaBitmap->copyPixelsTo(m_pixelData.get(), bufferSize);
+#elif PLATFORM(CG)
+ // FIXME: we should get rid of this temporary copy where possible.
+ int tempRowBytes = width * 4;
+ // Note we do not zero this vector since we are going to
+ // completely overwrite its contents with the image below.
+ // Try to reuse the color space from the image to preserve its colors.
+ // Some images use a color space (such as indexed) unsupported by the bitmap context.
+ RetainPtr<CGColorSpaceRef> colorSpaceReleaser;
+ CGColorSpaceRef colorSpace = CGImageGetColorSpace(nativeImage);
+ CGColorSpaceModel colorSpaceModel = CGColorSpaceGetModel(colorSpace);
+ switch (colorSpaceModel) {
+ case kCGColorSpaceModelMonochrome:
+ case kCGColorSpaceModelRGB:
+ case kCGColorSpaceModelCMYK:
+ case kCGColorSpaceModelLab:
+ case kCGColorSpaceModelDeviceN:
+ break;
+ default:
+ colorSpaceReleaser.adoptCF(CGColorSpaceCreateDeviceRGB());
+ colorSpace = colorSpaceReleaser.get();
+ break;
+ }
+ RetainPtr<CGContextRef> tempContext(AdoptCF, CGBitmapContextCreate(m_pixelData.get(),
+ width, height, 8, tempRowBytes,
+ colorSpace,
+ kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host));
+ CGContextSetBlendMode(tempContext.get(), kCGBlendModeCopy);
+ CGContextDrawImage(tempContext.get(),
+ CGRectMake(0, 0, static_cast<CGFloat>(width), static_cast<CGFloat>(height)),
+ nativeImage);
+#else
+#error "Need to implement for your platform."
+#endif
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/chromium/PlatformImage.h b/Source/WebCore/platform/graphics/chromium/PlatformImage.h
new file mode 100644
index 0000000..12f77b6
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/PlatformImage.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2011 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS 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 APPLE OR ITS 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 PlatformImage_h
+#define PlatformImage_h
+
+#include "ImageSource.h"
+#include "IntSize.h"
+#include <stdint.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/OwnArrayPtr.h>
+
+namespace WebCore {
+
+class PlatformImage {
+ WTF_MAKE_NONCOPYABLE(PlatformImage);
+public:
+ PlatformImage();
+
+ void updateFromImage(NativeImagePtr);
+ const uint8_t* pixels() const { return m_pixelData ? &m_pixelData[0] : 0; }
+ IntSize size() const { return m_size; }
+
+private:
+ OwnArrayPtr<uint8_t> m_pixelData;
+ IntSize m_size;
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.cpp
index 878c142..5d595ad 100644
--- a/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.cpp
@@ -29,64 +29,13 @@
#include "PluginLayerChromium.h"
+#include "cc/CCLayerImpl.h"
#include "GraphicsContext3D.h"
#include "LayerRendererChromium.h"
#include <GLES2/gl2.h>
namespace WebCore {
-PluginLayerChromium::SharedValues::SharedValues(GraphicsContext3D* context)
- : m_context(context)
- , m_shaderProgram(0)
- , m_shaderSamplerLocation(-1)
- , m_shaderMatrixLocation(-1)
- , m_shaderAlphaLocation(-1)
- , m_initialized(false)
-{
- char vertexShaderString[] =
- "attribute vec4 a_position; \n"
- "attribute vec2 a_texCoord; \n"
- "uniform mat4 matrix; \n"
- "varying vec2 v_texCoord; \n"
- "void main() \n"
- "{ \n"
- " gl_Position = matrix * a_position; \n"
- " v_texCoord = a_texCoord; \n"
- "} \n";
-
- char fragmentShaderString[] =
- "precision mediump float; \n"
- "varying vec2 v_texCoord; \n"
- "uniform sampler2D s_texture; \n"
- "uniform float alpha; \n"
- "void main() \n"
- "{ \n"
- " vec4 texColor = texture2D(s_texture, vec2(v_texCoord.x, v_texCoord.y)); \n"
- " gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha; \n"
- "} \n";
-
- m_shaderProgram = createShaderProgram(m_context, vertexShaderString, fragmentShaderString);
- if (!m_shaderProgram) {
- LOG_ERROR("PluginLayerChromium: Failed to create shader program");
- return;
- }
-
- m_shaderSamplerLocation = m_context->getUniformLocation(m_shaderProgram, "s_texture");
- m_shaderMatrixLocation = m_context->getUniformLocation(m_shaderProgram, "matrix");
- m_shaderAlphaLocation = m_context->getUniformLocation(m_shaderProgram, "alpha");
- ASSERT(m_shaderSamplerLocation != -1);
- ASSERT(m_shaderMatrixLocation != -1);
- ASSERT(m_shaderAlphaLocation != -1);
-
- m_initialized = true;
-}
-
-PluginLayerChromium::SharedValues::~SharedValues()
-{
- if (m_shaderProgram)
- GLC(m_context, m_context->deleteProgram(m_shaderProgram));
-}
-
PassRefPtr<PluginLayerChromium> PluginLayerChromium::create(GraphicsLayerChromium* owner)
{
return adoptRef(new PluginLayerChromium(owner));
@@ -109,8 +58,8 @@ void PluginLayerChromium::updateContentsIfDirty()
void PluginLayerChromium::draw()
{
ASSERT(layerRenderer());
- const PluginLayerChromium::SharedValues* sv = layerRenderer()->pluginLayerSharedValues();
- ASSERT(sv && sv->initialized());
+ const PluginLayerChromium::Program* program = layerRenderer()->pluginLayerProgram();
+ ASSERT(program && program->initialized());
GraphicsContext3D* context = layerRendererContext();
GLC(context, context->activeTexture(GL_TEXTURE0));
GLC(context, context->bindTexture(GL_TEXTURE_2D, m_textureId));
@@ -122,11 +71,12 @@ void PluginLayerChromium::draw()
GLC(context, context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
GLC(context, context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
- layerRenderer()->useShader(sv->shaderProgram());
- GLC(context, context->uniform1i(sv->shaderSamplerLocation(), 0));
- drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(),
- bounds().width(), bounds().height(), drawOpacity(),
- sv->shaderMatrixLocation(), sv->shaderAlphaLocation());
+ layerRenderer()->useShader(program->program());
+ GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0));
+ drawTexturedQuad(context, layerRenderer()->projectionMatrix(), ccLayerImpl()->drawTransform(),
+ bounds().width(), bounds().height(), ccLayerImpl()->drawOpacity(),
+ program->vertexShader().matrixLocation(),
+ program->fragmentShader().alphaLocation());
}
}
diff --git a/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.h b/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.h
index 853b328..8d66f5f 100644
--- a/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.h
@@ -37,31 +37,16 @@ namespace WebCore {
class PluginLayerChromium : public LayerChromium {
public:
static PassRefPtr<PluginLayerChromium> create(GraphicsLayerChromium* owner = 0);
- virtual bool drawsContent() { return true; }
+ virtual bool drawsContent() const { return true; }
virtual void updateContentsIfDirty();
virtual void draw();
void setTextureId(unsigned textureId);
- class SharedValues {
- public:
- SharedValues(GraphicsContext3D* context);
- ~SharedValues();
+ typedef ProgramBinding<VertexShaderPosTex, FragmentShaderRGBATexFlipAlpha> Program;
- unsigned shaderProgram() const { return m_shaderProgram; }
- int shaderSamplerLocation() const { return m_shaderSamplerLocation; }
- int shaderMatrixLocation() const { return m_shaderMatrixLocation; }
- int shaderAlphaLocation() const { return m_shaderAlphaLocation; }
- bool initialized() const { return m_initialized; }
-
- private:
- GraphicsContext3D* m_context;
- unsigned m_shaderProgram;
- int m_shaderSamplerLocation;
- int m_shaderMatrixLocation;
- int m_shaderAlphaLocation;
- bool m_initialized;
- };
+protected:
+ virtual const char* layerTypeAsString() const { return "PluginLayer"; }
private:
PluginLayerChromium(GraphicsLayerChromium* owner);
diff --git a/Source/WebCore/platform/graphics/chromium/ProgramBinding.cpp b/Source/WebCore/platform/graphics/chromium/ProgramBinding.cpp
new file mode 100644
index 0000000..6be00ef
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/ProgramBinding.cpp
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2011 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS 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 APPLE OR ITS 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(ACCELERATED_COMPOSITING)
+
+#include "ProgramBinding.h"
+
+#include "GeometryBinding.h"
+#include "GraphicsContext.h"
+#include "GraphicsContext3D.h"
+#include "LayerRendererChromium.h"
+
+namespace WebCore {
+
+ProgramBindingBase::ProgramBindingBase(GraphicsContext3D* context)
+ : m_context(context)
+ , m_program(0)
+ , m_initialized(false)
+{
+}
+
+ProgramBindingBase::~ProgramBindingBase()
+{
+ if (m_program)
+ GLC(m_context, m_context->deleteProgram(m_program));
+}
+
+bool ProgramBindingBase::init(const String& vertexShader, const String& fragmentShader)
+{
+ m_program = createShaderProgram(vertexShader, fragmentShader);
+ if (!m_program) {
+ LOG_ERROR("Failed to create shader program");
+ return false;
+ }
+ return true;
+}
+
+unsigned ProgramBindingBase::loadShader(unsigned type, const String& shaderSource)
+{
+ unsigned shader = m_context->createShader(type);
+ if (!shader)
+ return 0;
+ String sourceString(shaderSource);
+ GLC(m_context, m_context->shaderSource(shader, sourceString));
+ GLC(m_context, m_context->compileShader(shader));
+ int compiled = 0;
+ GLC(m_context, m_context->getShaderiv(shader, GraphicsContext3D::COMPILE_STATUS, &compiled));
+ if (!compiled) {
+ GLC(m_context, m_context->deleteShader(shader));
+ return 0;
+ }
+ return shader;
+}
+
+unsigned ProgramBindingBase::createShaderProgram(const String& vertexShaderSource, const String& fragmentShaderSource)
+{
+ unsigned vertexShader = loadShader(GraphicsContext3D::VERTEX_SHADER, vertexShaderSource);
+ if (!vertexShader) {
+ LOG_ERROR("Failed to create vertex shader");
+ return 0;
+ }
+
+ unsigned fragmentShader = loadShader(GraphicsContext3D::FRAGMENT_SHADER, fragmentShaderSource);
+ if (!fragmentShader) {
+ GLC(m_context, m_context->deleteShader(vertexShader));
+ LOG_ERROR("Failed to create fragment shader");
+ return 0;
+ }
+
+ unsigned programObject = m_context->createProgram();
+ if (!programObject) {
+ LOG_ERROR("Failed to create shader program");
+ return 0;
+ }
+
+ GLC(m_context, m_context->attachShader(programObject, vertexShader));
+ GLC(m_context, m_context->attachShader(programObject, fragmentShader));
+
+ // Bind the common attrib locations.
+ GLC(m_context, m_context->bindAttribLocation(programObject, GeometryBinding::positionAttribLocation(), "a_position"));
+ GLC(m_context, m_context->bindAttribLocation(programObject, GeometryBinding::texCoordAttribLocation(), "a_texCoord"));
+
+ GLC(m_context, m_context->linkProgram(programObject));
+ int linked = 0;
+ GLC(m_context, m_context->getProgramiv(programObject, GraphicsContext3D::LINK_STATUS, &linked));
+ if (!linked) {
+ LOG_ERROR("Failed to link shader program");
+ GLC(m_context, m_context->deleteProgram(programObject));
+ return 0;
+ }
+
+ GLC(m_context, m_context->deleteShader(vertexShader));
+ GLC(m_context, m_context->deleteShader(fragmentShader));
+ return programObject;
+}
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/chromium/ProgramBinding.h b/Source/WebCore/platform/graphics/chromium/ProgramBinding.h
new file mode 100644
index 0000000..c6bf605
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/ProgramBinding.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2011 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS 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 APPLE OR ITS 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 ProgramBinding_h
+#define ProgramBinding_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "PlatformString.h"
+
+namespace WebCore {
+
+class GraphicsContext3D;
+
+class ProgramBindingBase {
+public:
+ explicit ProgramBindingBase(GraphicsContext3D*);
+ ~ProgramBindingBase();
+
+ bool init(const String& vertexShader, const String& fragmentShader);
+
+ unsigned program() const { return m_program; }
+ bool initialized() const { return m_initialized; }
+
+protected:
+
+ unsigned loadShader(unsigned type, const String& shaderSource);
+ unsigned createShaderProgram(const String& vertexShaderSource, const String& fragmentShaderSource);
+
+ GraphicsContext3D* m_context;
+ unsigned m_program;
+ bool m_initialized;
+};
+
+template<class VertexShader, class FragmentShader>
+class ProgramBinding : public ProgramBindingBase {
+public:
+ explicit ProgramBinding(GraphicsContext3D* context)
+ : ProgramBindingBase(context)
+ {
+ if (!ProgramBindingBase::init(m_vertexShader.getShaderString(), m_fragmentShader.getShaderString()))
+ return;
+ if (!m_vertexShader.init(m_context, m_program))
+ return;
+ if (!m_fragmentShader.init(m_context, m_program))
+ return;
+ m_initialized = true;
+ }
+
+ const VertexShader& vertexShader() const { return m_vertexShader; }
+ const FragmentShader& fragmentShader() const { return m_fragmentShader; }
+
+private:
+
+ VertexShader m_vertexShader;
+ FragmentShader m_fragmentShader;
+};
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
+#endif
diff --git a/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp b/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp
index b3ce9d7..ca42d0b 100644
--- a/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp
@@ -29,98 +29,17 @@
#include "RenderSurfaceChromium.h"
+#include "cc/CCLayerImpl.h"
#include "GraphicsContext3D.h"
+#include "LayerChromium.h"
#include "LayerRendererChromium.h"
#include "LayerTexture.h"
+#include "TextStream.h"
+#include <wtf/text/CString.h>
namespace WebCore {
-RenderSurfaceChromium::SharedValues::SharedValues(GraphicsContext3D* context)
- : m_context(context)
- , m_shaderProgram(0)
- , m_maskShaderProgram(0)
- , m_shaderSamplerLocation(-1)
- , m_shaderMatrixLocation(-1)
- , m_shaderAlphaLocation(-1)
- , m_maskShaderSamplerLocation(-1)
- , m_maskShaderMaskSamplerLocation(-1)
- , m_maskShaderMatrixLocation(-1)
- , m_maskShaderAlphaLocation(-1)
- , m_initialized(false)
-{
- char vertexShaderString[] =
- "attribute vec4 a_position; \n"
- "attribute vec2 a_texCoord; \n"
- "uniform mat4 matrix; \n"
- "varying vec2 v_texCoord; \n"
- "void main() \n"
- "{ \n"
- " gl_Position = matrix * a_position; \n"
- " v_texCoord = a_texCoord; \n"
- "} \n";
- char fragmentShaderString[] =
- "precision mediump float; \n"
- "varying vec2 v_texCoord; \n"
- "uniform sampler2D s_texture; \n"
- "uniform float alpha; \n"
- "void main() \n"
- "{ \n"
- " vec4 texColor = texture2D(s_texture, v_texCoord); \n"
- " gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha; \n"
- "} \n";
- char fragmentShaderWithMaskString[] =
- "precision mediump float; \n"
- "varying vec2 v_texCoord; \n"
- "uniform sampler2D s_texture; \n"
- "uniform sampler2D s_mask; \n"
- "uniform float alpha; \n"
- "void main() \n"
- "{ \n"
- " vec4 texColor = texture2D(s_texture, v_texCoord); \n"
- " vec4 maskColor = texture2D(s_mask, v_texCoord); \n"
- " gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha * maskColor.w; \n"
- "} \n";
-
- m_shaderProgram = LayerChromium::createShaderProgram(m_context, vertexShaderString, fragmentShaderString);
- m_maskShaderProgram = LayerChromium::createShaderProgram(m_context, vertexShaderString, fragmentShaderWithMaskString);
- if (!m_shaderProgram || !m_maskShaderProgram) {
- LOG_ERROR("RenderSurfaceChromium: Failed to create shader program");
- return;
- }
-
- GLC(m_context, m_shaderSamplerLocation = m_context->getUniformLocation(m_shaderProgram, "s_texture"));
- GLC(m_context, m_shaderMatrixLocation = m_context->getUniformLocation(m_shaderProgram, "matrix"));
- GLC(m_context, m_shaderAlphaLocation = m_context->getUniformLocation(m_shaderProgram, "alpha"));
-
- GLC(m_context, m_maskShaderSamplerLocation = m_context->getUniformLocation(m_maskShaderProgram, "s_texture"));
- GLC(m_context, m_maskShaderMaskSamplerLocation = m_context->getUniformLocation(m_maskShaderProgram, "s_mask"));
- GLC(m_context, m_maskShaderMatrixLocation = m_context->getUniformLocation(m_maskShaderProgram, "matrix"));
- GLC(m_context, m_maskShaderAlphaLocation = m_context->getUniformLocation(m_maskShaderProgram, "alpha"));
-
- if (m_shaderSamplerLocation == -1 || m_shaderMatrixLocation == -1 || m_shaderAlphaLocation == -1
- || m_maskShaderSamplerLocation == -1 || m_maskShaderMaskSamplerLocation == -1 || m_maskShaderMatrixLocation == -1 || m_maskShaderAlphaLocation == -1) {
- LOG_ERROR("Failed to initialize render surface shaders.");
- return;
- }
-
- GLC(m_context, m_context->useProgram(m_shaderProgram));
- GLC(m_context, m_context->uniform1i(m_shaderSamplerLocation, 0));
- GLC(m_context, m_context->useProgram(m_maskShaderProgram));
- GLC(m_context, m_context->uniform1i(m_maskShaderSamplerLocation, 0));
- GLC(m_context, m_context->uniform1i(m_maskShaderMaskSamplerLocation, 1));
- GLC(m_context, m_context->useProgram(0));
- m_initialized = true;
-}
-
-RenderSurfaceChromium::SharedValues::~SharedValues()
-{
- if (m_shaderProgram)
- GLC(m_context, m_context->deleteProgram(m_shaderProgram));
- if (m_maskShaderProgram)
- GLC(m_context, m_context->deleteProgram(m_maskShaderProgram));
-}
-
-RenderSurfaceChromium::RenderSurfaceChromium(LayerChromium* owningLayer)
+RenderSurfaceChromium::RenderSurfaceChromium(CCLayerImpl* owningLayer)
: m_owningLayer(owningLayer)
, m_maskLayer(0)
, m_skipsDraw(false)
@@ -179,36 +98,39 @@ bool RenderSurfaceChromium::prepareContentsTexture()
return true;
}
-void RenderSurfaceChromium::drawSurface(LayerChromium* maskLayer, const TransformationMatrix& drawTransform)
+void RenderSurfaceChromium::drawSurface(CCLayerImpl* maskLayer, const TransformationMatrix& drawTransform)
{
GraphicsContext3D* context3D = layerRenderer()->context();
int shaderMatrixLocation = -1;
int shaderAlphaLocation = -1;
- const RenderSurfaceChromium::SharedValues* sv = layerRenderer()->renderSurfaceSharedValues();
- ASSERT(sv && sv->initialized());
+ const RenderSurfaceChromium::Program* program = layerRenderer()->renderSurfaceProgram();
+ const RenderSurfaceChromium::MaskProgram* maskProgram = layerRenderer()->renderSurfaceMaskProgram();
+ ASSERT(program && program->initialized());
bool useMask = false;
if (maskLayer && maskLayer->drawsContent()) {
- maskLayer->updateContentsIfDirty();
if (!maskLayer->bounds().isEmpty()) {
context3D->makeContextCurrent();
- layerRenderer()->useShader(sv->maskShaderProgram());
+ layerRenderer()->useShader(maskProgram->program());
GLC(context3D, context3D->activeTexture(GraphicsContext3D::TEXTURE0));
+ GLC(context3D, context3D->uniform1i(maskProgram->fragmentShader().samplerLocation(), 0));
m_contentsTexture->bindTexture();
GLC(context3D, context3D->activeTexture(GraphicsContext3D::TEXTURE1));
+ GLC(context3D, context3D->uniform1i(maskProgram->fragmentShader().maskSamplerLocation(), 1));
maskLayer->bindContentsTexture();
GLC(context3D, context3D->activeTexture(GraphicsContext3D::TEXTURE0));
- shaderMatrixLocation = sv->maskShaderMatrixLocation();
- shaderAlphaLocation = sv->maskShaderAlphaLocation();
+ shaderMatrixLocation = maskProgram->vertexShader().matrixLocation();
+ shaderAlphaLocation = maskProgram->fragmentShader().alphaLocation();
useMask = true;
}
}
if (!useMask) {
- layerRenderer()->useShader(sv->shaderProgram());
+ layerRenderer()->useShader(program->program());
m_contentsTexture->bindTexture();
- shaderMatrixLocation = sv->shaderMatrixLocation();
- shaderAlphaLocation = sv->shaderAlphaLocation();
+ GLC(context3D, context3D->uniform1i(program->fragmentShader().samplerLocation(), 0));
+ shaderMatrixLocation = program->vertexShader().matrixLocation();
+ shaderAlphaLocation = program->fragmentShader().alphaLocation();
}
LayerChromium::drawTexturedQuad(layerRenderer()->context(), layerRenderer()->projectionMatrix(), drawTransform,
@@ -231,7 +153,7 @@ void RenderSurfaceChromium::draw()
// both the layer and its reflection). The solution is to introduce yet another RenderSurface
// to draw the layer and its reflection in. For now we only apply a separate reflection
// mask if the contents don't have a mask of their own.
- LayerChromium* replicaMaskLayer = m_maskLayer;
+ CCLayerImpl* replicaMaskLayer = m_maskLayer;
if (!m_maskLayer && m_owningLayer->replicaLayer())
replicaMaskLayer = m_owningLayer->replicaLayer()->maskLayer();
@@ -244,5 +166,29 @@ void RenderSurfaceChromium::draw()
drawSurface(m_maskLayer, m_drawTransform);
}
+String RenderSurfaceChromium::name() const
+{
+#ifndef NDEBUG
+ return String::format("RenderSurface(id=%i,owner=%s)", m_owningLayer->debugID(), m_owningLayer->name().utf8().data());
+#else
+ return String::format("RenderSurface(owner=%s)", m_owningLayer->name().utf8().data());
+#endif
+}
+
+static void writeIndent(TextStream& ts, int indent)
+{
+ for (int i = 0; i != indent; ++i)
+ ts << " ";
+}
+
+void RenderSurfaceChromium::dumpSurface(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << name() << "\n";
+
+ writeIndent(ts, indent+1);
+ ts << "contentRect: (" << m_contentRect.x() << ", " << m_contentRect.y() << ", " << m_contentRect.width() << ", " << m_contentRect.height() << "\n";
+}
+
}
#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h b/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h
index b1f6a5c..6400c63 100644
--- a/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h
@@ -31,13 +31,15 @@
#include "FloatRect.h"
#include "IntRect.h"
+#include "ProgramBinding.h"
+#include "ShaderChromium.h"
#include "TextureManager.h"
#include "TransformationMatrix.h"
#include <wtf/Noncopyable.h>
namespace WebCore {
-class LayerChromium;
+class CCLayerImpl;
class LayerRendererChromium;
class LayerTexture;
@@ -45,13 +47,16 @@ class RenderSurfaceChromium {
WTF_MAKE_NONCOPYABLE(RenderSurfaceChromium);
friend class LayerRendererChromium;
public:
- explicit RenderSurfaceChromium(LayerChromium*);
+ explicit RenderSurfaceChromium(CCLayerImpl*);
~RenderSurfaceChromium();
bool prepareContentsTexture();
void cleanupResources();
void draw();
+ String name() const;
+ void dumpSurface(TextStream&, int indent) const;
+
FloatPoint contentRectCenter() const { return FloatRect(m_contentRect).center(); }
IntRect contentRect() const { return m_contentRect; }
@@ -60,56 +65,26 @@ public:
TransformationMatrix drawTransform() const { return m_drawTransform; }
- // Stores values that are shared between instances of this class that are
- // associated with the same LayerRendererChromium (and hence the same GL
- // context).
- class SharedValues {
- public:
- explicit SharedValues(GraphicsContext3D*);
- ~SharedValues();
-
- unsigned shaderProgram() const { return m_shaderProgram; }
- unsigned maskShaderProgram() const { return m_maskShaderProgram; }
- int shaderSamplerLocation() const { return m_shaderSamplerLocation; }
- int shaderMatrixLocation() const { return m_shaderMatrixLocation; }
- int shaderAlphaLocation() const { return m_shaderAlphaLocation; }
- int maskShaderSamplerLocation() const { return m_maskShaderSamplerLocation; }
- int maskShaderMaskSamplerLocation() const { return m_maskShaderMaskSamplerLocation; }
- int maskShaderMatrixLocation() const { return m_maskShaderMatrixLocation; }
- int maskShaderAlphaLocation() const { return m_maskShaderAlphaLocation; }
- bool initialized() const { return m_initialized; }
-
- private:
- GraphicsContext3D* m_context;
-
- unsigned m_shaderProgram;
- unsigned m_maskShaderProgram;
- int m_shaderSamplerLocation;
- int m_shaderMatrixLocation;
- int m_shaderAlphaLocation;
- int m_maskShaderSamplerLocation;
- int m_maskShaderMaskSamplerLocation;
- int m_maskShaderMatrixLocation;
- int m_maskShaderAlphaLocation;
- bool m_initialized;
- };
+ typedef ProgramBinding<VertexShaderPosTex, FragmentShaderRGBATexAlpha> Program;
+ typedef ProgramBinding<VertexShaderPosTex, FragmentShaderRGBATexAlphaMask> MaskProgram;
private:
LayerRendererChromium* layerRenderer();
- void drawSurface(LayerChromium* maskLayer, const TransformationMatrix& drawTransform);
+ void drawSurface(CCLayerImpl* maskLayer, const TransformationMatrix& drawTransform);
- LayerChromium* m_owningLayer;
- LayerChromium* m_maskLayer;
+ CCLayerImpl* m_owningLayer;
+ CCLayerImpl* m_maskLayer;
IntRect m_contentRect;
bool m_skipsDraw;
+
OwnPtr<LayerTexture> m_contentsTexture;
float m_drawOpacity;
TransformationMatrix m_drawTransform;
TransformationMatrix m_replicaDrawTransform;
TransformationMatrix m_originTransform;
IntRect m_scissorRect;
- Vector<LayerChromium*> m_layerList;
+ Vector<CCLayerImpl*> m_layerList;
};
}
diff --git a/Source/WebCore/platform/graphics/chromium/ShaderChromium.cpp b/Source/WebCore/platform/graphics/chromium/ShaderChromium.cpp
new file mode 100644
index 0000000..49b3462
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/ShaderChromium.cpp
@@ -0,0 +1,317 @@
+/*
+ * Copyright (C) 2011 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS 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 APPLE OR ITS 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(ACCELERATED_COMPOSITING)
+
+#include "ShaderChromium.h"
+
+#include "GraphicsContext.h"
+#include "GraphicsContext3D.h"
+
+#define SHADER0(Src) #Src
+#define SHADER(Src) SHADER0(Src)
+
+namespace WebCore {
+
+VertexShaderPosTex::VertexShaderPosTex()
+ : m_matrixLocation(-1)
+{
+}
+
+bool VertexShaderPosTex::init(GraphicsContext3D* context, unsigned program)
+{
+ m_matrixLocation = context->getUniformLocation(program, "matrix");
+ return m_matrixLocation != -1;
+}
+
+String VertexShaderPosTex::getShaderString() const
+{
+ return SHADER(
+ attribute vec4 a_position;
+ attribute vec2 a_texCoord;
+ uniform mat4 matrix;
+ varying vec2 v_texCoord;
+ void main()
+ {
+ gl_Position = matrix * a_position;
+ v_texCoord = a_texCoord;
+ }
+ );
+}
+
+VertexShaderPosTexYUVStretch::VertexShaderPosTexYUVStretch()
+ : m_matrixLocation(-1)
+ , m_yWidthScaleFactorLocation(-1)
+ , m_uvWidthScaleFactorLocation(-1)
+{
+}
+
+bool VertexShaderPosTexYUVStretch::init(GraphicsContext3D* context, unsigned program)
+{
+ m_matrixLocation = context->getUniformLocation(program, "matrix");
+ m_yWidthScaleFactorLocation = context->getUniformLocation(program, "y_widthScaleFactor");
+ m_uvWidthScaleFactorLocation = context->getUniformLocation(program, "uv_widthScaleFactor");
+ return m_matrixLocation != -1 && m_yWidthScaleFactorLocation != -1 && m_uvWidthScaleFactorLocation != -1;
+}
+
+String VertexShaderPosTexYUVStretch::getShaderString() const
+{
+ return SHADER(
+ precision mediump float;
+ attribute vec4 a_position;
+ attribute vec2 a_texCoord;
+ uniform mat4 matrix;
+ varying vec2 y_texCoord;
+ varying vec2 uv_texCoord;
+ uniform float y_widthScaleFactor;
+ uniform float uv_widthScaleFactor;
+ void main()
+ {
+ gl_Position = matrix * a_position;
+ y_texCoord = vec2(y_widthScaleFactor * a_texCoord.x, a_texCoord.y);
+ uv_texCoord = vec2(uv_widthScaleFactor * a_texCoord.x, a_texCoord.y);
+ }
+ );
+}
+
+VertexShaderPos::VertexShaderPos()
+ : m_matrixLocation(-1)
+{
+}
+
+bool VertexShaderPos::init(GraphicsContext3D* context, unsigned program)
+{
+ m_matrixLocation = context->getUniformLocation(program, "matrix");
+ return m_matrixLocation != -1;
+}
+
+String VertexShaderPos::getShaderString() const
+{
+ return SHADER(
+ attribute vec4 a_position;
+ uniform mat4 matrix;
+ void main()
+ {
+ gl_Position = matrix * a_position;
+ }
+ );
+}
+
+VertexShaderPosTexTransform::VertexShaderPosTexTransform()
+ : m_matrixLocation(-1)
+ , m_texTransformLocation(-1)
+{
+}
+
+bool VertexShaderPosTexTransform::init(GraphicsContext3D* context, unsigned program)
+{
+ m_matrixLocation = context->getUniformLocation(program, "matrix");
+ m_texTransformLocation = context->getUniformLocation(program, "texTransform");
+ return m_matrixLocation != -1 && m_texTransformLocation != -1;
+}
+
+String VertexShaderPosTexTransform::getShaderString() const
+{
+ return SHADER(
+ attribute vec4 a_position;
+ attribute vec2 a_texCoord;
+ uniform mat4 matrix;
+ uniform vec4 texTransform;
+ varying vec2 v_texCoord;
+ void main()
+ {
+ gl_Position = matrix * a_position;
+ v_texCoord = a_texCoord * texTransform.zw + texTransform.xy;
+ }
+ );
+}
+
+FragmentTexAlphaBinding::FragmentTexAlphaBinding()
+ : m_samplerLocation(-1)
+ , m_alphaLocation(-1)
+{
+}
+
+bool FragmentTexAlphaBinding::init(GraphicsContext3D* context, unsigned program)
+{
+ m_samplerLocation = context->getUniformLocation(program, "s_texture");
+ m_alphaLocation = context->getUniformLocation(program, "alpha");
+
+ return m_samplerLocation != -1 && m_alphaLocation != -1;
+}
+
+String FragmentShaderRGBATexFlipAlpha::getShaderString() const
+{
+ return SHADER(
+ precision mediump float;
+ varying vec2 v_texCoord;
+ uniform sampler2D s_texture;
+ uniform float alpha;
+ void main()
+ {
+ vec4 texColor = texture2D(s_texture, vec2(v_texCoord.x, 1.0 - v_texCoord.y));
+ gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha;
+ }
+ );
+}
+
+String FragmentShaderRGBATexAlpha::getShaderString() const
+{
+ return SHADER(
+ precision mediump float;
+ varying vec2 v_texCoord;
+ uniform sampler2D s_texture;
+ uniform float alpha;
+ void main()
+ {
+ vec4 texColor = texture2D(s_texture, v_texCoord);
+ gl_FragColor = texColor * alpha;
+ }
+ );
+}
+
+String FragmentShaderBGRATexAlpha::getShaderString() const
+{
+ return SHADER(
+ precision mediump float;
+ varying vec2 v_texCoord;
+ uniform sampler2D s_texture;
+ uniform float alpha;
+ void main()
+ {
+ vec4 texColor = texture2D(s_texture, v_texCoord);
+ gl_FragColor = vec4(texColor.z, texColor.y, texColor.x, texColor.w) * alpha;
+ }
+ );
+}
+
+FragmentShaderRGBATexAlphaMask::FragmentShaderRGBATexAlphaMask()
+ : m_samplerLocation(-1)
+ , m_maskSamplerLocation(-1)
+ , m_alphaLocation(-1)
+{
+}
+
+bool FragmentShaderRGBATexAlphaMask::init(GraphicsContext3D* context, unsigned program)
+{
+ m_samplerLocation = context->getUniformLocation(program, "s_texture");
+ m_maskSamplerLocation = context->getUniformLocation(program, "s_mask");
+ m_alphaLocation = context->getUniformLocation(program, "alpha");
+
+ return m_samplerLocation != -1 && m_maskSamplerLocation != -1 && m_alphaLocation != -1;
+}
+
+String FragmentShaderRGBATexAlphaMask::getShaderString() const
+{
+ return SHADER(
+ precision mediump float;
+ varying vec2 v_texCoord;
+ uniform sampler2D s_texture;
+ uniform sampler2D s_mask;
+ uniform float alpha;
+ void main()
+ {
+ vec4 texColor = texture2D(s_texture, v_texCoord);
+ vec4 maskColor = texture2D(s_mask, v_texCoord);
+ gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha * maskColor.w;
+ }
+ );
+}
+
+FragmentShaderYUVVideo::FragmentShaderYUVVideo()
+ : m_yTextureLocation(-1)
+ , m_uTextureLocation(-1)
+ , m_vTextureLocation(-1)
+ , m_alphaLocation(-1)
+ , m_ccMatrixLocation(-1)
+ , m_signAdjLocation(-1)
+{
+}
+
+bool FragmentShaderYUVVideo::init(GraphicsContext3D* context, unsigned program)
+{
+ m_yTextureLocation = context->getUniformLocation(program, "y_texture");
+ m_uTextureLocation = context->getUniformLocation(program, "u_texture");
+ m_vTextureLocation = context->getUniformLocation(program, "v_texture");
+ m_alphaLocation = context->getUniformLocation(program, "alpha");
+ m_ccMatrixLocation = context->getUniformLocation(program, "cc_matrix");
+ m_signAdjLocation = context->getUniformLocation(program, "adj");
+
+ return m_yTextureLocation != -1 && m_uTextureLocation != -1 && m_vTextureLocation != -1
+ && m_alphaLocation != -1 && m_ccMatrixLocation != -1 && m_signAdjLocation != -1;
+}
+
+String FragmentShaderYUVVideo::getShaderString() const
+{
+ return SHADER(
+ precision mediump float;
+ precision mediump int;
+ varying vec2 y_texCoord;
+ varying vec2 uv_texCoord;
+ uniform sampler2D y_texture;
+ uniform sampler2D u_texture;
+ uniform sampler2D v_texture;
+ uniform float alpha;
+ uniform float adj;
+ uniform mat3 cc_matrix;
+ void main()
+ {
+ float y = texture2D(y_texture, y_texCoord).x;
+ float u = texture2D(u_texture, uv_texCoord).x - adj;
+ float v = texture2D(v_texture, uv_texCoord).x - adj;
+ vec3 rgb = cc_matrix * vec3(y, u, v);
+ gl_FragColor = vec4(rgb, float(1)) * alpha;
+ }
+ );
+}
+
+FragmentShaderColor::FragmentShaderColor()
+ : m_colorLocation(-1)
+{
+}
+
+bool FragmentShaderColor::init(GraphicsContext3D* context, unsigned program)
+{
+ m_colorLocation = context->getUniformLocation(program, "color");
+ return m_colorLocation != -1;
+}
+
+String FragmentShaderColor::getShaderString() const
+{
+ return SHADER(
+ precision mediump float;
+ uniform vec4 color;
+ void main()
+ {
+ gl_FragColor = vec4(color.xyz * color.w, color.w);
+ }
+ );
+}
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/chromium/ShaderChromium.h b/Source/WebCore/platform/graphics/chromium/ShaderChromium.h
new file mode 100644
index 0000000..758c62b
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/ShaderChromium.h
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2011 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS 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 APPLE OR ITS 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 ShaderChromium_h
+#define ShaderChromium_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "PlatformString.h"
+
+#if USE(SKIA)
+#include "SkColorPriv.h"
+#endif
+
+namespace WebCore {
+
+class GraphicsContext3D;
+
+class VertexShaderPosTex {
+public:
+ VertexShaderPosTex();
+
+ bool init(GraphicsContext3D*, unsigned program);
+ String getShaderString() const;
+
+ int matrixLocation() const { return m_matrixLocation; }
+
+private:
+ int m_matrixLocation;
+};
+
+class VertexShaderPosTexYUVStretch {
+public:
+ VertexShaderPosTexYUVStretch();
+
+ bool init(GraphicsContext3D*, unsigned program);
+ String getShaderString() const;
+
+ int matrixLocation() const { return m_matrixLocation; }
+ int yWidthScaleFactorLocation() const { return m_yWidthScaleFactorLocation; }
+ int uvWidthScaleFactorLocation() const { return m_uvWidthScaleFactorLocation; }
+
+private:
+ int m_matrixLocation;
+ int m_yWidthScaleFactorLocation;
+ int m_uvWidthScaleFactorLocation;
+};
+
+class VertexShaderPos {
+public:
+ VertexShaderPos();
+
+ bool init(GraphicsContext3D*, unsigned program);
+ String getShaderString() const;
+
+ int matrixLocation() const { return m_matrixLocation; }
+
+private:
+ int m_matrixLocation;
+};
+
+class VertexShaderPosTexTransform {
+public:
+ VertexShaderPosTexTransform();
+
+ bool init(GraphicsContext3D*, unsigned program);
+ String getShaderString() const;
+
+ int matrixLocation() const { return m_matrixLocation; }
+ int texTransformLocation() const { return m_texTransformLocation; }
+
+private:
+ int m_matrixLocation;
+ int m_texTransformLocation;
+};
+
+class FragmentTexAlphaBinding {
+public:
+ FragmentTexAlphaBinding();
+
+ bool init(GraphicsContext3D*, unsigned program);
+ int alphaLocation() const { return m_alphaLocation; }
+ int samplerLocation() const { return m_samplerLocation; }
+
+private:
+ int m_samplerLocation;
+ int m_alphaLocation;
+};
+
+class FragmentShaderRGBATexFlipAlpha : public FragmentTexAlphaBinding {
+public:
+ String getShaderString() const;
+};
+
+class FragmentShaderRGBATexAlpha : public FragmentTexAlphaBinding {
+public:
+ String getShaderString() const;
+};
+
+class FragmentShaderBGRATexAlpha : public FragmentTexAlphaBinding {
+public:
+ String getShaderString() const;
+};
+
+class FragmentShaderRGBATexAlphaMask {
+public:
+ FragmentShaderRGBATexAlphaMask();
+ String getShaderString() const;
+
+ bool init(GraphicsContext3D*, unsigned program);
+ int alphaLocation() const { return m_alphaLocation; }
+ int samplerLocation() const { return m_samplerLocation; }
+ int maskSamplerLocation() const { return m_maskSamplerLocation; }
+
+private:
+ int m_samplerLocation;
+ int m_maskSamplerLocation;
+ int m_alphaLocation;
+};
+
+#if USE(SKIA) && SK_B32_SHIFT
+typedef FragmentShaderRGBATexAlpha FragmentShaderTexAlpha;
+#else
+typedef FragmentShaderBGRATexAlpha FragmentShaderTexAlpha;
+#endif
+
+class FragmentShaderYUVVideo {
+public:
+ FragmentShaderYUVVideo();
+ String getShaderString() const;
+
+ bool init(GraphicsContext3D*, unsigned program);
+
+ int yTextureLocation() const { return m_yTextureLocation; }
+ int uTextureLocation() const { return m_uTextureLocation; }
+ int vTextureLocation() const { return m_vTextureLocation; }
+ int alphaLocation() const { return m_alphaLocation; }
+ int ccMatrixLocation() const { return m_ccMatrixLocation; }
+ int signAdjLocation() const { return m_signAdjLocation; }
+
+private:
+ int m_yTextureLocation;
+ int m_uTextureLocation;
+ int m_vTextureLocation;
+ int m_alphaLocation;
+ int m_ccMatrixLocation;
+ int m_signAdjLocation;
+};
+
+class FragmentShaderColor {
+public:
+ FragmentShaderColor();
+ String getShaderString() const;
+
+ bool init(GraphicsContext3D*, unsigned program);
+ int colorLocation() const { return m_colorLocation; }
+
+private:
+ int m_colorLocation;
+};
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
+#endif
diff --git a/Source/WebCore/platform/graphics/chromium/TextureManager.cpp b/Source/WebCore/platform/graphics/chromium/TextureManager.cpp
index c4ad958..13cdb89 100644
--- a/Source/WebCore/platform/graphics/chromium/TextureManager.cpp
+++ b/Source/WebCore/platform/graphics/chromium/TextureManager.cpp
@@ -152,7 +152,7 @@ unsigned TextureManager::requestTexture(TextureToken token, IntSize size, unsign
if (memoryRequiredBytes > m_memoryLimitBytes || !reduceMemoryToLimit(m_memoryLimitBytes - memoryRequiredBytes))
return 0;
- unsigned textureId = m_context->createTexture();
+ unsigned textureId;
GLC(m_context.get(), textureId = m_context->createTexture());
GLC(m_context.get(), m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId));
// Do basic linear filtering on resize.
diff --git a/Source/WebCore/platform/graphics/chromium/VideoFrameChromium.h b/Source/WebCore/platform/graphics/chromium/VideoFrameChromium.h
index e176b0c..ab669d1 100644
--- a/Source/WebCore/platform/graphics/chromium/VideoFrameChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/VideoFrameChromium.h
@@ -69,12 +69,15 @@ public:
virtual SurfaceType surfaceType() const = 0;
virtual Format format() const = 0;
virtual unsigned width() const = 0;
+ virtual unsigned width(unsigned plane) const = 0;
virtual unsigned height() const = 0;
+ virtual unsigned height(unsigned plane) const = 0;
virtual unsigned planes() const = 0;
virtual int stride(unsigned plane) const = 0;
virtual const void* data(unsigned plane) const = 0;
virtual unsigned texture(unsigned plane) const = 0;
virtual const IntSize requiredTextureSize(unsigned plane) const = 0;
+ virtual bool hasPaddingBytes(unsigned plane) const = 0;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp
index 41cd180..5d7a6e7 100644
--- a/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp
@@ -33,6 +33,7 @@
#if USE(ACCELERATED_COMPOSITING)
#include "VideoLayerChromium.h"
+#include "cc/CCLayerImpl.h"
#include "Extensions3DChromium.h"
#include "GraphicsContext3D.h"
#include "LayerRendererChromium.h"
@@ -51,125 +52,6 @@ const float VideoLayerChromium::yuv2RGB[9] = {
1.403f, -.714f, 0.f,
};
-VideoLayerChromium::SharedValues::SharedValues(GraphicsContext3D* context)
- : m_context(context)
- , m_yuvShaderProgram(0)
- , m_rgbaShaderProgram(0)
- , m_yuvShaderMatrixLocation(0)
- , m_yuvWidthScaleFactorLocation(0)
- , m_rgbaShaderMatrixLocation(0)
- , m_rgbaWidthScaleFactorLocation(0)
- , m_ccMatrixLocation(0)
- , m_signAdjLocation(0)
- , m_yTextureLocation(0)
- , m_uTextureLocation(0)
- , m_vTextureLocation(0)
- , m_rgbaTextureLocation(0)
- , m_yuvAlphaLocation(0)
- , m_rgbaAlphaLocation(0)
- , m_initialized(false)
-{
- // Frame textures are allocated based on stride width, not visible frame
- // width, such that there is a guarantee that the frame rows line up
- // properly and are not shifted by (stride - width) pixels. To hide the
- // "padding" pixels between the edge of the visible frame width and the end
- // of the stride, we give the shader a widthScaleFactor (<=1.0) of how much
- // of the width of the texture should be shown when drawing the texture onto
- // the vertices.
- char vertexShaderString[] =
- "precision mediump float; \n"
- "attribute vec4 a_position; \n"
- "attribute vec2 a_texCoord; \n"
- "uniform mat4 matrix; \n"
- "varying vec2 v_texCoord; \n"
- "uniform float widthScaleFactor; \n"
- "void main() \n"
- "{ \n"
- " gl_Position = matrix * a_position; \n"
- " v_texCoord = vec2(widthScaleFactor * a_texCoord.x, a_texCoord.y); \n"
- "} \n";
-
- char yuvFragmentShaderString[] =
- "precision mediump float; \n"
- "precision mediump int; \n"
- "varying vec2 v_texCoord; \n"
- "uniform sampler2D y_texture; \n"
- "uniform sampler2D u_texture; \n"
- "uniform sampler2D v_texture; \n"
- "uniform float alpha; \n"
- "uniform float adj; \n"
- "uniform mat3 cc_matrix; \n"
- "void main() \n"
- "{ \n"
- " float y = texture2D(y_texture, v_texCoord).x; \n"
- " float u = texture2D(u_texture, v_texCoord).x - adj; \n"
- " float v = texture2D(v_texture, v_texCoord).x - adj; \n"
- " vec3 rgb = cc_matrix * vec3(y, u, v); \n"
- " gl_FragColor = vec4(rgb, float(1)) * alpha; \n"
- "} \n";
-
- char rgbaFragmentShaderString[] =
- "precision mediump float; \n"
- "varying vec2 v_texCoord; \n"
- "uniform sampler2D rgba_texture; \n"
- "uniform float alpha; \n"
- "void main() \n"
- "{ \n"
- " vec4 texColor = texture2D(rgba_texture, vec2(v_texCoord.x, float(1) - v_texCoord.y)); \n"
- " gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha; \n"
- "} \n";
-
- m_rgbaShaderProgram = createShaderProgram(m_context, vertexShaderString, rgbaFragmentShaderString);
- if (!m_rgbaShaderProgram) {
- LOG_ERROR("VideoLayerChromium: Failed to create rgba shader program");
- return;
- }
-
- m_yuvShaderProgram = createShaderProgram(m_context, vertexShaderString, yuvFragmentShaderString);
- if (!m_yuvShaderProgram) {
- LOG_ERROR("VideoLayerChromium: Failed to create yuv shader program");
- return;
- }
-
- m_yuvShaderMatrixLocation = m_context->getUniformLocation(m_yuvShaderProgram, "matrix");
- m_yuvWidthScaleFactorLocation = m_context->getUniformLocation(m_yuvShaderProgram, "widthScaleFactor");
- m_yTextureLocation = m_context->getUniformLocation(m_yuvShaderProgram, "y_texture");
- m_uTextureLocation = m_context->getUniformLocation(m_yuvShaderProgram, "u_texture");
- m_vTextureLocation = m_context->getUniformLocation(m_yuvShaderProgram, "v_texture");
- m_ccMatrixLocation = m_context->getUniformLocation(m_yuvShaderProgram, "cc_matrix");
- m_signAdjLocation = m_context->getUniformLocation(m_yuvShaderProgram, "adj");
- m_yuvAlphaLocation = m_context->getUniformLocation(m_yuvShaderProgram, "alpha");
-
- ASSERT(m_yuvShaderMatrixLocation != -1);
- ASSERT(m_yuvWidthScaleFactorLocation != -1);
- ASSERT(m_yTextureLocation != -1);
- ASSERT(m_uTextureLocation != -1);
- ASSERT(m_vTextureLocation != -1);
- ASSERT(m_ccMatrixLocation != -1);
- ASSERT(m_signAdjLocation != -1);
- ASSERT(m_yuvAlphaLocation != -1);
-
- m_rgbaShaderMatrixLocation = m_context->getUniformLocation(m_rgbaShaderProgram, "matrix");
- m_rgbaTextureLocation = m_context->getUniformLocation(m_rgbaShaderProgram, "rgba_texture");
- m_rgbaWidthScaleFactorLocation = m_context->getUniformLocation(m_rgbaShaderProgram, "widthScaleFactor");
- m_rgbaAlphaLocation = m_context->getUniformLocation(m_rgbaShaderProgram, "alpha");
-
- ASSERT(m_rgbaShaderMatrixLocation != -1);
- ASSERT(m_rgbaTextureLocation != -1);
- ASSERT(m_rgbaWidthScaleFactorLocation != -1);
- ASSERT(m_rgbaAlphaLocation != -1);
-
- m_initialized = true;
-}
-
-VideoLayerChromium::SharedValues::~SharedValues()
-{
- if (m_yuvShaderProgram)
- GLC(m_context, m_context->deleteProgram(m_yuvShaderProgram));
- if (m_rgbaShaderProgram)
- GLC(m_context, m_context->deleteProgram(m_rgbaShaderProgram));
-}
-
PassRefPtr<VideoLayerChromium> VideoLayerChromium::create(GraphicsLayerChromium* owner,
VideoFrameProvider* provider)
{
@@ -297,9 +179,27 @@ bool VideoLayerChromium::allocateTexturesIfNeeded(GraphicsContext3D* context, Vi
if (!planeTextureSize.isZero() && planeTextureSize != m_textureSizes[plane]) {
allocateTexture(context, m_textures[plane], planeTextureSize, textureFormat);
m_textureSizes[plane] = planeTextureSize;
- m_frameSizes[plane] = IntSize(frame->width(), frame->height());
+ int frameWidth = frame->width(plane);
+ int frameHeight = frame->height(plane);
+ // When there are dead pixels at the edge of the texture, decrease
+ // the frame width by 1 to prevent the rightmost pixels from
+ // interpolating with the dead pixels.
+ if (frame->hasPaddingBytes(plane))
+ --frameWidth;
+ m_frameSizes[plane] = IntSize(frameWidth, frameHeight);
}
}
+
+ // In YV12, every 2x2 square of Y values corresponds to one U and
+ // one V value. If we decrease the width of the UV plane, we must decrease the
+ // width of the Y texture by 2 for proper alignment. This must happen
+ // always, even if Y's texture does not have padding bytes.
+ if (frame->format() == VideoFrameChromium::YV12) {
+ int yPlaneOriginalWidth = frame->width(VideoFrameChromium::yPlane);
+ if (frame->hasPaddingBytes(VideoFrameChromium::uPlane))
+ m_frameSizes[VideoFrameChromium::yPlane].setWidth(yPlaneOriginalWidth - 2);
+ }
+
return true;
}
@@ -318,9 +218,10 @@ void VideoLayerChromium::updateTexture(GraphicsContext3D* context, unsigned text
memcpy(mem, data, dimensions.width() * dimensions.height());
GLC(context, static_cast<Extensions3DChromium*>(context->getExtensions())->unmapTexSubImage2DCHROMIUM(mem));
} else {
- // FIXME: We should have some sort of code to handle the case when
- // mapTexSubImage2D fails.
- m_skipsDraw = true;
+ // If mapTexSubImage2DCHROMIUM fails, then do the slower texSubImage2D
+ // upload. This does twice the copies as mapTexSubImage2DCHROMIUM, one
+ // in the command buffer and another to the texture.
+ GLC(context, context->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, 0, 0, dimensions.width(), dimensions.height(), format, GraphicsContext3D::UNSIGNED_BYTE, data));
}
}
@@ -330,16 +231,18 @@ void VideoLayerChromium::draw()
return;
ASSERT(layerRenderer());
- const VideoLayerChromium::SharedValues* sv = layerRenderer()->videoLayerSharedValues();
- ASSERT(sv && sv->initialized());
+ const RGBAProgram* rgbaProgram = layerRenderer()->videoLayerRGBAProgram();
+ ASSERT(rgbaProgram && rgbaProgram->initialized());
+ const YUVProgram* yuvProgram = layerRenderer()->videoLayerYUVProgram();
+ ASSERT(yuvProgram && yuvProgram->initialized());
switch (m_frameFormat) {
case VideoFrameChromium::YV12:
case VideoFrameChromium::YV16:
- drawYUV(sv);
+ drawYUV(yuvProgram);
break;
case VideoFrameChromium::RGBA:
- drawRGBA(sv);
+ drawRGBA(rgbaProgram);
break;
default:
// FIXME: Implement other paths.
@@ -359,7 +262,7 @@ void VideoLayerChromium::releaseCurrentFrame()
resetFrameParameters();
}
-void VideoLayerChromium::drawYUV(const SharedValues* sv)
+void VideoLayerChromium::drawYUV(const VideoLayerChromium::YUVProgram* program)
{
GraphicsContext3D* context = layerRendererContext();
GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE1));
@@ -369,49 +272,57 @@ void VideoLayerChromium::drawYUV(const SharedValues* sv)
GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE3));
GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textures[VideoFrameChromium::vPlane]));
- layerRenderer()->useShader(sv->yuvShaderProgram());
- unsigned frameWidth = m_frameSizes[VideoFrameChromium::yPlane].width();
- unsigned textureWidth = m_textureSizes[VideoFrameChromium::yPlane].width();
- float widthScaleFactor = static_cast<float>(frameWidth) / textureWidth;
- GLC(context, context->uniform1f(sv->yuvWidthScaleFactorLocation(), widthScaleFactor));
+ layerRenderer()->useShader(program->program());
+ unsigned yFrameWidth = m_frameSizes[VideoFrameChromium::yPlane].width();
+ unsigned yTextureWidth = m_textureSizes[VideoFrameChromium::yPlane].width();
+ // Arbitrarily take the u sizes because u and v dimensions are identical.
+ unsigned uvFrameWidth = m_frameSizes[VideoFrameChromium::uPlane].width();
+ unsigned uvTextureWidth = m_textureSizes[VideoFrameChromium::uPlane].width();
+
+ float yWidthScaleFactor = static_cast<float>(yFrameWidth) / yTextureWidth;
+ float uvWidthScaleFactor = static_cast<float>(uvFrameWidth) / uvTextureWidth;
+ GLC(context, context->uniform1f(program->vertexShader().yWidthScaleFactorLocation(), yWidthScaleFactor));
+ GLC(context, context->uniform1f(program->vertexShader().uvWidthScaleFactorLocation(), uvWidthScaleFactor));
- GLC(context, context->uniform1i(sv->yTextureLocation(), 1));
- GLC(context, context->uniform1i(sv->uTextureLocation(), 2));
- GLC(context, context->uniform1i(sv->vTextureLocation(), 3));
+ GLC(context, context->uniform1i(program->fragmentShader().yTextureLocation(), 1));
+ GLC(context, context->uniform1i(program->fragmentShader().uTextureLocation(), 2));
+ GLC(context, context->uniform1i(program->fragmentShader().vTextureLocation(), 3));
// This value of 0.5 maps to 128. It is used in the YUV to RGB conversion
// formula to turn unsigned u and v values to signed u and v values.
// This is loaded as a uniform because certain drivers have problems
// reading literal float values.
- GLC(context, context->uniform1f(sv->signAdjLocation(), 0.5));
+ GLC(context, context->uniform1f(program->fragmentShader().signAdjLocation(), 0.5));
- GLC(context, context->uniformMatrix3fv(sv->ccMatrixLocation(), 0, const_cast<float*>(yuv2RGB), 1));
+ GLC(context, context->uniformMatrix3fv(program->fragmentShader().ccMatrixLocation(), 0, const_cast<float*>(yuv2RGB), 1));
- drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(),
- bounds().width(), bounds().height(), drawOpacity(),
- sv->yuvShaderMatrixLocation(), sv->yuvAlphaLocation());
+ drawTexturedQuad(context, layerRenderer()->projectionMatrix(), ccLayerImpl()->drawTransform(),
+ bounds().width(), bounds().height(), ccLayerImpl()->drawOpacity(),
+ program->vertexShader().matrixLocation(),
+ program->fragmentShader().alphaLocation());
// Reset active texture back to texture 0.
GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
}
-void VideoLayerChromium::drawRGBA(const SharedValues* sv)
+void VideoLayerChromium::drawRGBA(const VideoLayerChromium::RGBAProgram* program)
{
GraphicsContext3D* context = layerRendererContext();
GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textures[VideoFrameChromium::rgbPlane]));
- layerRenderer()->useShader(sv->rgbaShaderProgram());
+ layerRenderer()->useShader(program->program());
unsigned frameWidth = m_frameSizes[VideoFrameChromium::rgbPlane].width();
unsigned textureWidth = m_textureSizes[VideoFrameChromium::rgbPlane].width();
float widthScaleFactor = static_cast<float>(frameWidth) / textureWidth;
- GLC(context, context->uniform1f(sv->rgbaWidthScaleFactorLocation(), widthScaleFactor));
+ GLC(context, context->uniform4f(program->vertexShader().texTransformLocation(), 0, 0, widthScaleFactor, 1));
- GLC(context, context->uniform1i(sv->rgbaTextureLocation(), 0));
+ GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0));
- drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(),
- bounds().width(), bounds().height(), drawOpacity(),
- sv->rgbaShaderMatrixLocation(), sv->rgbaAlphaLocation());
+ drawTexturedQuad(context, layerRenderer()->projectionMatrix(), ccLayerImpl()->drawTransform(),
+ bounds().width(), bounds().height(), ccLayerImpl()->drawOpacity(),
+ program->vertexShader().matrixLocation(),
+ program->fragmentShader().alphaLocation());
}
void VideoLayerChromium::resetFrameParameters()
diff --git a/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.h b/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.h
index ac3bca9..2170e13 100644
--- a/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.h
@@ -46,53 +46,19 @@ public:
VideoFrameProvider* = 0);
virtual ~VideoLayerChromium();
virtual void updateContentsIfDirty();
- virtual bool drawsContent() { return true; }
+ virtual bool drawsContent() const { return true; }
virtual void draw();
// This function is called by VideoFrameProvider. When this method is called
// putCurrentFrame() must be called to return the frame currently held.
void releaseCurrentFrame();
- class SharedValues {
- public:
- explicit SharedValues(GraphicsContext3D*);
- ~SharedValues();
- unsigned yuvShaderProgram() const { return m_yuvShaderProgram; }
- unsigned rgbaShaderProgram() const { return m_rgbaShaderProgram; }
- int yuvShaderMatrixLocation() const { return m_yuvShaderMatrixLocation; }
- int rgbaShaderMatrixLocation() const { return m_rgbaShaderMatrixLocation; }
- int yuvWidthScaleFactorLocation() const { return m_yuvWidthScaleFactorLocation; }
- int rgbaWidthScaleFactorLocation() const { return m_rgbaWidthScaleFactorLocation; }
- int yTextureLocation() const { return m_yTextureLocation; }
- int uTextureLocation() const { return m_uTextureLocation; }
- int vTextureLocation() const { return m_vTextureLocation; }
- int yuvAlphaLocation() const { return m_yuvAlphaLocation; }
- int rgbaAlphaLocation() const { return m_rgbaAlphaLocation; }
- int rgbaTextureLocation() const { return m_rgbaTextureLocation; }
- int ccMatrixLocation() const { return m_ccMatrixLocation; }
- int signAdjLocation() const { return m_signAdjLocation; }
- bool initialized() const { return m_initialized; }
- private:
- GraphicsContext3D* m_context;
- unsigned m_yuvShaderProgram;
- unsigned m_rgbaShaderProgram;
- int m_yuvShaderMatrixLocation;
- int m_yuvWidthScaleFactorLocation;
- int m_rgbaShaderMatrixLocation;
- int m_rgbaWidthScaleFactorLocation;
- int m_ccMatrixLocation;
- int m_signAdjLocation;
- int m_yTextureLocation;
- int m_uTextureLocation;
- int m_vTextureLocation;
- int m_rgbaTextureLocation;
- int m_yuvAlphaLocation;
- int m_rgbaAlphaLocation;
- bool m_initialized;
- };
+ typedef ProgramBinding<VertexShaderPosTexTransform, FragmentShaderRGBATexFlipAlpha> RGBAProgram;
+ typedef ProgramBinding<VertexShaderPosTexYUVStretch, FragmentShaderYUVVideo> YUVProgram;
protected:
virtual void cleanupResources();
+ virtual const char* layerTypeAsString() const { return "VideoLayer"; }
private:
VideoLayerChromium(GraphicsLayerChromium* owner, VideoFrameProvider*);
@@ -103,8 +69,8 @@ private:
void updateRGBAContents(GraphicsContext3D*, const VideoFrameChromium*);
void allocateTexture(GraphicsContext3D*, unsigned textureId, const IntSize& dimensions, unsigned textureFormat);
void updateTexture(GraphicsContext3D*, unsigned textureId, const IntSize& dimensions, unsigned textureFormat, const void* data);
- void drawYUV(const SharedValues*);
- void drawRGBA(const SharedValues*);
+ void drawYUV(const YUVProgram*);
+ void drawRGBA(const RGBAProgram*);
void resetFrameParameters();
void saveCurrentFrame(VideoFrameChromium*);
diff --git a/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp
index 5b34bb9..e83d045 100644
--- a/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp
@@ -82,6 +82,7 @@ void WebGLLayerChromium::setContext(const GraphicsContext3D* context)
if (textureId != m_textureId)
m_textureChanged = true;
m_textureId = textureId;
+ m_premultipliedAlpha = m_context->getContextAttributes().premultipliedAlpha;
}
}
diff --git a/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.h b/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.h
index c67cc2c..70be876 100644
--- a/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.h
@@ -44,11 +44,14 @@ class GraphicsContext3D;
class WebGLLayerChromium : public CanvasLayerChromium {
public:
static PassRefPtr<WebGLLayerChromium> create(GraphicsLayerChromium* owner = 0);
- virtual bool drawsContent() { return m_context; }
+ virtual bool drawsContent() const { return m_context; }
virtual void updateContentsIfDirty();
void setContext(const GraphicsContext3D* context);
+protected:
+ virtual const char* layerTypeAsString() const { return "WebGLLayer"; }
+
private:
explicit WebGLLayerChromium(GraphicsLayerChromium* owner);
GraphicsContext3D* m_context;
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp
new file mode 100644
index 0000000..604ef61
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2011 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:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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(ACCELERATED_COMPOSITING)
+#include "CCHeadsUpDisplay.h"
+
+#include "CurrentTime.h"
+#include "Font.h"
+#include "FontDescription.h"
+#include "GraphicsContext3D.h"
+#include "LayerChromium.h"
+#include "LayerTexture.h"
+#include "TextRun.h"
+#include "TextStream.h"
+#include "TextureManager.h"
+#include <wtf/text/CString.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+using namespace std;
+
+CCHeadsUpDisplay::CCHeadsUpDisplay(LayerRendererChromium* owner)
+ : m_currentFrameNumber(0)
+ , m_layerRenderer(owner)
+ , m_showFPSCounter(false)
+ , m_showPlatformLayerTree(false)
+{
+ m_presentTimeHistoryInSec[0] = currentTime();
+ m_presentTimeHistoryInSec[1] = m_presentTimeHistoryInSec[0];
+}
+
+CCHeadsUpDisplay::~CCHeadsUpDisplay()
+{
+}
+
+void CCHeadsUpDisplay::draw()
+{
+ GraphicsContext3D* context = m_layerRenderer->context();
+ if (!m_hudTexture)
+ m_hudTexture = LayerTexture::create(context, m_layerRenderer->textureManager());
+
+ // Use a fullscreen texture only if we need to...
+ IntSize hudSize;
+ if (m_showPlatformLayerTree) {
+ hudSize.setWidth(min(2048, m_layerRenderer->visibleRectSize().width()));
+ hudSize.setHeight(min(2048, m_layerRenderer->visibleRectSize().height()));
+ } else {
+ hudSize.setWidth(512);
+ hudSize.setHeight(128);
+ }
+
+ m_hudTexture->reserve(hudSize, GraphicsContext3D::RGBA);
+
+ // Render pixels into the texture.
+ PlatformCanvas canvas;
+ canvas.resize(hudSize);
+ {
+ PlatformCanvas::Painter painter(&canvas);
+ drawHudContents(painter.context(), hudSize);
+ }
+
+ // Upload to GL.
+ {
+ PlatformCanvas::AutoLocker locker(&canvas);
+
+ m_hudTexture->bindTexture();
+ GLC(context.get(), context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, canvas.size().width(), canvas.size().height(), 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, locker.pixels()));
+ }
+
+ // Draw the HUD onto the default render surface.
+ const ContentLayerChromium::Program* program = m_layerRenderer->contentLayerProgram();
+ ASSERT(program && program->initialized());
+ GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
+ m_hudTexture->bindTexture();
+ m_layerRenderer->useShader(program->program());
+ GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0));
+
+ TransformationMatrix matrix;
+ matrix.translate3d(hudSize.width() * 0.5, hudSize.height() * 0.5, 0);
+ LayerChromium::drawTexturedQuad(context, m_layerRenderer->projectionMatrix(),
+ matrix, hudSize.width(), hudSize.height(),
+ 1.0f, program->vertexShader().matrixLocation(),
+ program->fragmentShader().alphaLocation());
+
+ m_hudTexture->unreserve();
+}
+
+void CCHeadsUpDisplay::drawHudContents(GraphicsContext* ctx, const IntSize& hudSize)
+{
+ FontDescription mediumFontDesc;
+ mediumFontDesc.setGenericFamily(FontDescription::MonospaceFamily);
+ mediumFontDesc.setComputedSize(12);
+ Font mediumFont(mediumFontDesc, 0, 0);
+ mediumFont.update(0);
+
+ FontDescription smallFontDesc;
+ smallFontDesc.setGenericFamily(FontDescription::MonospaceFamily);
+ smallFontDesc.setComputedSize(10);
+ Font smallFont(smallFontDesc, 0, 0);
+ smallFont.update(0);
+
+ // We haven't finished rendering yet, so we don't now the "current" present time.
+ // So, consider the *last two* present times and use those as our present time.
+ double secForLastFrame = m_presentTimeHistoryInSec[(m_currentFrameNumber - 1) % 2] - m_presentTimeHistoryInSec[m_currentFrameNumber % 2];
+
+ int y = 14;
+
+ if (m_showPlatformLayerTree) {
+ ctx->setFillColor(Color(0, 0, 0, 192), ColorSpaceDeviceRGB);
+ ctx->fillRect(FloatRect(0, 0, hudSize.width(), hudSize.height()));
+ }
+
+ // Draw fps.
+ String topLine = "";
+ if (secForLastFrame > 0 && m_showFPSCounter) {
+ double fps = 1.0 / secForLastFrame;
+ topLine += String::format("FPS: %3.1f", fps);
+ }
+ if (topLine.length()) {
+ ctx->setFillColor(Color(0, 0, 0, 255), ColorSpaceDeviceRGB);
+ TextRun run(topLine);
+ ctx->fillRect(FloatRect(2, 2, mediumFont.width(run) + 2.0f, 15));
+ ctx->setFillColor(Color(255, 0, 0), ColorSpaceDeviceRGB);
+ ctx->drawText(mediumFont, run, IntPoint(3, y));
+ y = 26;
+ }
+
+ // Draw layer tree, if enabled.
+ if (m_showPlatformLayerTree) {
+ ctx->setFillColor(Color(255, 0, 0), ColorSpaceDeviceRGB);
+ Vector<String> lines;
+ m_layerRenderer->layerTreeAsText().split('\n', lines);
+ for (size_t i = 0; i < lines.size(); ++i) {
+ ctx->drawText(smallFont, TextRun(lines[i]), IntPoint(2, y));
+ y += 12;
+ }
+ }
+}
+
+void CCHeadsUpDisplay::onPresent()
+{
+ m_presentTimeHistoryInSec[m_currentFrameNumber % 2] = currentTime();
+ m_currentFrameNumber += 1;
+}
+
+}
+
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.h b/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.h
new file mode 100644
index 0000000..dbac22a
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2011 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:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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 CCHeadsUpDisplay_h
+#define CCHeadsUpDisplay_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "LayerRendererChromium.h"
+
+namespace WebCore {
+
+class GeometryBinding;
+class GraphicsContext3D;
+
+// Class that handles drawing of composited render layers using GL.
+class CCHeadsUpDisplay {
+ WTF_MAKE_NONCOPYABLE(CCHeadsUpDisplay);
+public:
+ static PassOwnPtr<CCHeadsUpDisplay> create(LayerRendererChromium* owner)
+ {
+ return adoptPtr(new CCHeadsUpDisplay(owner));
+ }
+
+ ~CCHeadsUpDisplay();
+
+ void onPresent();
+
+ void setShowFPSCounter(bool enable) { m_showFPSCounter = enable; }
+ bool showFPSCounter() const { return m_showFPSCounter; }
+
+ void setShowPlatformLayerTree(bool enable) { m_showPlatformLayerTree = enable; }
+ bool showPlatformLayerTree() const { return m_showPlatformLayerTree; }
+
+ bool enabled() const { return true || m_showPlatformLayerTree || m_showFPSCounter; }
+ void draw();
+
+private:
+ explicit CCHeadsUpDisplay(LayerRendererChromium* owner);
+ void drawHudContents(GraphicsContext*, const IntSize& hudSize);
+
+ int m_currentFrameNumber;
+
+ OwnPtr<LayerTexture> m_hudTexture;
+
+ LayerRendererChromium* m_layerRenderer;
+
+ double m_presentTimeHistoryInSec[2];
+
+ bool m_showFPSCounter;
+ bool m_showPlatformLayerTree;
+};
+
+}
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
+#endif
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp
new file mode 100644
index 0000000..a0ad0fb
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2011 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS 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 APPLE OR ITS 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(ACCELERATED_COMPOSITING)
+
+#include "cc/CCLayerImpl.h"
+
+#include "GraphicsContext3D.h"
+#include "LayerChromium.h" // FIXME: temporary and bad
+#include "LayerRendererChromium.h"
+#include "RenderSurfaceChromium.h"
+#include <wtf/text/WTFString.h>
+
+namespace {
+void toGLMatrix(float* flattened, const WebCore::TransformationMatrix& m)
+{
+ flattened[0] = m.m11();
+ flattened[1] = m.m12();
+ flattened[2] = m.m13();
+ flattened[3] = m.m14();
+ flattened[4] = m.m21();
+ flattened[5] = m.m22();
+ flattened[6] = m.m23();
+ flattened[7] = m.m24();
+ flattened[8] = m.m31();
+ flattened[9] = m.m32();
+ flattened[10] = m.m33();
+ flattened[11] = m.m34();
+ flattened[12] = m.m41();
+ flattened[13] = m.m42();
+ flattened[14] = m.m43();
+ flattened[15] = m.m44();
+}
+}
+
+
+namespace WebCore {
+
+CCLayerImpl::CCLayerImpl(LayerChromium* owner)
+ : m_owner(owner)
+#ifndef NDEBUG
+ , m_debugID(owner->debugID())
+#endif
+ , m_targetRenderSurface(0)
+ , m_drawDepth(0)
+ , m_drawOpacity(0)
+ , m_doubleSided(true)
+ , m_debugBorderColor(0, 0, 0, 0)
+ , m_debugBorderWidth(0)
+ , m_renderSurface(0)
+ , m_layerRenderer(0)
+{
+}
+
+CCLayerImpl::~CCLayerImpl()
+{
+}
+
+// These are pseudo-structural hacks until we get real tree syncing up in this piece.
+CCLayerImpl* CCLayerImpl::superlayer() const
+{
+ return m_owner->superlayer() ? m_owner->superlayer()->ccLayerImpl() : 0;
+}
+
+CCLayerImpl* CCLayerImpl::maskLayer() const
+{
+ return m_owner->maskLayer() ? m_owner->maskLayer()->ccLayerImpl() : 0;
+}
+
+CCLayerImpl* CCLayerImpl::replicaLayer() const
+{
+ return m_owner->replicaLayer() ? m_owner->replicaLayer()->ccLayerImpl() : 0;
+}
+
+void CCLayerImpl::setLayerRenderer(LayerRendererChromium* renderer)
+{
+ m_layerRenderer = renderer;
+}
+
+RenderSurfaceChromium* CCLayerImpl::createRenderSurface()
+{
+ m_renderSurface = new RenderSurfaceChromium(this);
+ return m_renderSurface.get();
+}
+
+// These belong on CCLayerImpl, but should be subclased by each type and not defer to the LayerChromium subtypes.
+bool CCLayerImpl::drawsContent() const
+{
+ return m_owner->drawsContent();
+}
+
+void CCLayerImpl::draw()
+{
+ return m_owner->draw();
+}
+
+void CCLayerImpl::unreserveContentsTexture()
+{
+ m_owner->unreserveContentsTexture();
+}
+
+void CCLayerImpl::bindContentsTexture()
+{
+ m_owner->bindContentsTexture();
+}
+
+void CCLayerImpl::cleanupResources()
+{
+ if (renderSurface())
+ renderSurface()->cleanupResources();
+}
+
+const IntRect CCLayerImpl::getDrawRect() const
+{
+ // Form the matrix used by the shader to map the corners of the layer's
+ // bounds into the view space.
+ FloatRect layerRect(-0.5 * bounds().width(), -0.5 * bounds().height(), bounds().width(), bounds().height());
+ IntRect mappedRect = enclosingIntRect(drawTransform().mapRect(layerRect));
+ return mappedRect;
+}
+
+void CCLayerImpl::drawDebugBorder()
+{
+ static float glMatrix[16];
+ if (!debugBorderColor().alpha())
+ return;
+
+ ASSERT(layerRenderer());
+ const LayerChromium::BorderProgram* program = layerRenderer()->borderProgram();
+ ASSERT(program && program->initialized());
+ layerRenderer()->useShader(program->program());
+ TransformationMatrix renderMatrix = drawTransform();
+ renderMatrix.scale3d(bounds().width(), bounds().height(), 1);
+ toGLMatrix(&glMatrix[0], layerRenderer()->projectionMatrix() * renderMatrix);
+ GraphicsContext3D* context = layerRenderer()->context();
+ GLC(context, context->uniformMatrix4fv(program->vertexShader().matrixLocation(), false, &glMatrix[0], 1));
+
+ GLC(context, context->uniform4f(program->fragmentShader().colorLocation(), debugBorderColor().red() / 255.0, debugBorderColor().green() / 255.0, debugBorderColor().blue() / 255.0, 1));
+
+ GLC(context, context->lineWidth(debugBorderWidth()));
+
+ // The indices for the line are stored in the same array as the triangle indices.
+ GLC(context, context->drawElements(GraphicsContext3D::LINE_LOOP, 4, GraphicsContext3D::UNSIGNED_SHORT, 6 * sizeof(unsigned short)));
+}
+
+static void writeIndent(TextStream& ts, int indent)
+{
+ for (int i = 0; i != indent; ++i)
+ ts << " ";
+}
+
+void CCLayerImpl::dumpLayerProperties(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "bounds: " << bounds().width() << ", " << bounds().height() << "\n";
+
+ if (m_targetRenderSurface) {
+ writeIndent(ts, indent);
+ ts << "targetRenderSurface: " << m_targetRenderSurface->name() << "\n";
+ }
+
+ writeIndent(ts, indent);
+ ts << "drawTransform: ";
+ ts << m_drawTransform.m11() << ", " << m_drawTransform.m12() << ", " << m_drawTransform.m13() << ", " << m_drawTransform.m14() << ", ";
+ ts << m_drawTransform.m21() << ", " << m_drawTransform.m22() << ", " << m_drawTransform.m23() << ", " << m_drawTransform.m24() << ", ";
+ ts << m_drawTransform.m31() << ", " << m_drawTransform.m32() << ", " << m_drawTransform.m33() << ", " << m_drawTransform.m34() << ", ";
+ ts << m_drawTransform.m41() << ", " << m_drawTransform.m42() << ", " << m_drawTransform.m43() << ", " << m_drawTransform.m44() << "\n";
+}
+
+}
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h
new file mode 100644
index 0000000..6892976
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2011 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS 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 APPLE OR ITS 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 CCLayerImpl_h
+#define CCLayerImpl_h
+
+#include "Color.h"
+#include "FloatRect.h"
+#include "IntRect.h"
+#include "TextStream.h"
+#include "TransformationMatrix.h"
+#include <wtf/OwnPtr.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class LayerChromium;
+class LayerRendererChromium;
+class RenderSurfaceChromium;
+
+class CCLayerImpl : public RefCounted<CCLayerImpl> {
+public:
+ static PassRefPtr<CCLayerImpl> create(LayerChromium* owner)
+ {
+ return adoptRef(new CCLayerImpl(owner));
+ }
+ // When this class gets subclasses, remember to add 'virtual' here.
+ ~CCLayerImpl();
+
+#ifndef NDEBUG
+ int debugID() const { return m_debugID; }
+#endif
+
+ CCLayerImpl* superlayer() const;
+ CCLayerImpl* maskLayer() const;
+ CCLayerImpl* replicaLayer() const;
+
+ void draw();
+ bool drawsContent() const;
+ void unreserveContentsTexture();
+ void bindContentsTexture();
+
+ void cleanupResources();
+
+ void setName(const String& name) { m_name = name; }
+ const String& name() const { return m_name; }
+
+ // Debug layer border - visual effect only, do not change geometry/clipping/etc.
+ void setDebugBorderColor(Color c) { m_debugBorderColor = c; }
+ Color debugBorderColor() const { return m_debugBorderColor; }
+ void setDebugBorderWidth(float width) { m_debugBorderWidth = width; }
+ float debugBorderWidth() const { return m_debugBorderWidth; }
+
+ void drawDebugBorder();
+
+ void setLayerRenderer(LayerRendererChromium*);
+ LayerRendererChromium* layerRenderer() const { return m_layerRenderer.get(); }
+
+ RenderSurfaceChromium* createRenderSurface();
+
+ RenderSurfaceChromium* renderSurface() const { return m_renderSurface.get(); }
+ void clearRenderSurface() { m_renderSurface.clear(); }
+ float drawDepth() const { return m_drawDepth; }
+ void setDrawDepth(float depth) { m_drawDepth = depth; }
+ float drawOpacity() const { return m_drawOpacity; }
+ void setDrawOpacity(float opacity) { m_drawOpacity = opacity; }
+ const IntRect& scissorRect() const { return m_scissorRect; }
+ void setScissorRect(const IntRect& rect) { m_scissorRect = rect; }
+ RenderSurfaceChromium* targetRenderSurface() const { return m_targetRenderSurface; }
+ void setTargetRenderSurface(RenderSurfaceChromium* surface) { m_targetRenderSurface = surface; }
+
+ bool doubleSided() const { return m_doubleSided; }
+ void setDoubleSided(bool doubleSided) { m_doubleSided = doubleSided; }
+ const IntSize& bounds() const { return m_bounds; }
+ void setBounds(const IntSize& bounds) { m_bounds = bounds; }
+
+ // Returns the rect containtaining this layer in the current view's coordinate system.
+ const IntRect getDrawRect() const;
+
+ const TransformationMatrix& drawTransform() const { return m_drawTransform; }
+ void setDrawTransform(const TransformationMatrix& matrix) { m_drawTransform = matrix; }
+ const IntRect& drawableContentRect() const { return m_drawableContentRect; }
+ void setDrawableContentRect(const IntRect& rect) { m_drawableContentRect = rect; }
+
+ virtual void dumpLayerProperties(TextStream&, int indent) const;
+
+private:
+ // For now, CCLayers are owned directly by a LayerChromium.
+ LayerChromium* m_owner;
+ explicit CCLayerImpl(LayerChromium*);
+
+ // Debugging.
+#ifndef NDEBUG
+ int m_debugID;
+#endif
+
+ String m_name;
+
+ // Render surface this layer draws into. This is a surface that can belong
+ // either to this layer (if m_targetRenderSurface == m_renderSurface) or
+ // to an ancestor of this layer. The target render surface determines the
+ // coordinate system the layer's transforms are relative to.
+ RenderSurfaceChromium* m_targetRenderSurface;
+
+ // The global depth value of the center of the layer. This value is used
+ // to sort layers from back to front.
+ float m_drawDepth;
+ float m_drawOpacity;
+
+ // Whether the "back" of this layer should draw.
+ bool m_doubleSided;
+
+ // Debug borders.
+ Color m_debugBorderColor;
+ float m_debugBorderWidth;
+
+ TransformationMatrix m_drawTransform;
+
+ IntSize m_bounds;
+
+ // The scissor rectangle that should be used when this layer is drawn.
+ // Inherited by the parent layer and further restricted if this layer masks
+ // to bounds.
+ IntRect m_scissorRect;
+
+ // Render surface associated with this layer. The layer and its descendants
+ // will render to this surface.
+ OwnPtr<RenderSurfaceChromium> m_renderSurface;
+
+ // Hierarchical bounding rect containing the layer and its descendants.
+ IntRect m_drawableContentRect;
+
+ // Points to the layer renderer that updates and draws this layer.
+ RefPtr<LayerRendererChromium> m_layerRenderer;
+};
+
+}
+
+#endif // CCLayerImpl_h
+