Diff
Modified: trunk/Source/WebCore/ChangeLog (108092 => 108093)
--- trunk/Source/WebCore/ChangeLog 2012-02-17 18:19:18 UTC (rev 108092)
+++ trunk/Source/WebCore/ChangeLog 2012-02-17 18:27:32 UTC (rev 108093)
@@ -1,3 +1,66 @@
+2012-02-17 Tim Dresser <[email protected]>
+
+ [chromium] Refactor video drawing to be more data driven
+ https://bugs.webkit.org/show_bug.cgi?id=76720
+
+ Reviewed by James Robinson.
+
+ CCVideoLayerImpl no longer handles drawing itself, but produces a list of CCVideoDrawQuads.
+ These quads are then drawn by LayerRendererChromium.
+
+ CCLayerImpl::willDraw(LayerRendererChromium*) is called directly before appendQuads.
+ CCLayerImpl::didDraw() is called directly after all drawing has been completed.
+ CCLayerImpl::draw has been removed.
+
+ willDraw and didDraw are used to handle interaction with the VideoFrameProvider
+ in CCVideoLayerImpl. willDraw gets a frame from the VideoFrameProvider, and
+ didDraw returns it.
+
+ A unit test has been added: CCLayerTreeHostImplTest.didDrawCalledOnAllLayers.
+ This test ensures that CCLayerImpl::didDraw() is called on all layers,
+ including layers on different render surfaces.
+
+ As this was a refactor, no other tests were added.
+
+ * platform/graphics/chromium/LayerRendererChromium.cpp:
+ (WebCore::LayerRendererChromium::drawYUV):
+ (WebCore):
+ (WebCore::LayerRendererChromium::drawSingleTextureVideoQuad):
+ (WebCore::LayerRendererChromium::drawRGBA):
+ (WebCore::LayerRendererChromium::drawNativeTexture):
+ (WebCore::LayerRendererChromium::copyFrameToTextures):
+ (WebCore::LayerRendererChromium::copyPlaneToTexture):
+ (WebCore::LayerRendererChromium::drawVideoQuad):
+ * platform/graphics/chromium/LayerRendererChromium.h:
+ (LayerRendererChromium):
+ * platform/graphics/chromium/cc/CCLayerImpl.cpp:
+ * platform/graphics/chromium/cc/CCLayerImpl.h:
+ (WebCore::CCLayerImpl::didDraw):
+ (CCLayerImpl):
+ * platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp:
+ (WebCore::CCLayerTreeHostImpl::calculateRenderPasses):
+ (WebCore::CCLayerTreeHostImpl::drawLayers):
+ * platform/graphics/chromium/cc/CCLayerTreeHostImpl.h:
+ (CCLayerTreeHostImpl):
+ * platform/graphics/chromium/cc/CCVideoDrawQuad.cpp:
+ (WebCore::CCVideoDrawQuad::create):
+ (WebCore::CCVideoDrawQuad::CCVideoDrawQuad):
+ * platform/graphics/chromium/cc/CCVideoDrawQuad.h:
+ (CCVideoDrawQuad):
+ (WebCore::CCVideoDrawQuad::textures):
+ (WebCore::CCVideoDrawQuad::frame):
+ (WebCore::CCVideoDrawQuad::format):
+ * platform/graphics/chromium/cc/CCVideoLayerImpl.cpp:
+ (WebCore::CCVideoLayerImpl::willDraw):
+ (WebCore::CCVideoLayerImpl::appendQuads):
+ (WebCore::CCVideoLayerImpl::didDraw):
+ (WebCore::CCVideoLayerImpl::computeVisibleSize):
+ * platform/graphics/chromium/cc/CCVideoLayerImpl.h:
+ (CCVideoLayerImpl):
+ (WebCore::CCVideoLayerImpl::providerMutex):
+ (WebCore::CCVideoLayerImpl::provider):
+ (Texture):
+
2012-02-17 Stephen Chenney <[email protected]>
Crash at WebCore::SVGUseElement::expandSymbolElementsInShadowTree
Modified: trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp (108092 => 108093)
--- trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp 2012-02-17 18:19:18 UTC (rev 108092)
+++ trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp 2012-02-17 18:27:32 UTC (rev 108093)
@@ -694,10 +694,139 @@
GLC(m_context.get(), m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA));
}
+void LayerRendererChromium::drawYUV(const CCVideoDrawQuad* quad)
+{
+ const CCVideoLayerImpl::YUVProgram* program = videoLayerYUVProgram();
+ ASSERT(program && program->initialized());
+
+ const CCVideoLayerImpl::Texture& yTexture = quad->textures()[VideoFrameChromium::yPlane];
+ const CCVideoLayerImpl::Texture& uTexture = quad->textures()[VideoFrameChromium::uPlane];
+ const CCVideoLayerImpl::Texture& vTexture = quad->textures()[VideoFrameChromium::vPlane];
+
+ GLC(context(), context()->activeTexture(GraphicsContext3D::TEXTURE1));
+ GLC(context(), context()->bindTexture(GraphicsContext3D::TEXTURE_2D, yTexture.m_texture->textureId()));
+ GLC(context(), context()->activeTexture(GraphicsContext3D::TEXTURE2));
+ GLC(context(), context()->bindTexture(GraphicsContext3D::TEXTURE_2D, uTexture.m_texture->textureId()));
+ GLC(context(), context()->activeTexture(GraphicsContext3D::TEXTURE3));
+ GLC(context(), context()->bindTexture(GraphicsContext3D::TEXTURE_2D, vTexture.m_texture->textureId()));
+
+ GLC(context(), context()->useProgram(program->program()));
+
+ float yWidthScaleFactor = static_cast<float>(yTexture.m_visibleSize.width()) / yTexture.m_texture->size().width();
+ // Arbitrarily take the u sizes because u and v dimensions are identical.
+ float uvWidthScaleFactor = static_cast<float>(uTexture.m_visibleSize.width()) / uTexture.m_texture->size().width();
+ GLC(context(), context()->uniform1f(program->vertexShader().yWidthScaleFactorLocation(), yWidthScaleFactor));
+ GLC(context(), context()->uniform1f(program->vertexShader().uvWidthScaleFactorLocation(), uvWidthScaleFactor));
+
+ GLC(context(), context()->uniform1i(program->fragmentShader().yTextureLocation(), 1));
+ GLC(context(), context()->uniform1i(program->fragmentShader().uTextureLocation(), 2));
+ GLC(context(), context()->uniform1i(program->fragmentShader().vTextureLocation(), 3));
+
+ GLC(context(), context()->uniformMatrix3fv(program->fragmentShader().ccMatrixLocation(), 0, const_cast<float*>(CCVideoLayerImpl::yuv2RGB), 1));
+ GLC(context(), context()->uniform3fv(program->fragmentShader().yuvAdjLocation(), const_cast<float*>(CCVideoLayerImpl::yuvAdjust), 1));
+
+ const IntSize& bounds = quad->quadRect().size();
+ drawTexturedQuad(quad->layerTransform(), bounds.width(), bounds.height(), quad->opacity(), FloatQuad(),
+ program->vertexShader().matrixLocation(),
+ program->fragmentShader().alphaLocation(),
+ -1);
+
+ // Reset active texture back to texture 0.
+ GLC(context(), context()->activeTexture(GraphicsContext3D::TEXTURE0));
+}
+
+template<class Program>
+void LayerRendererChromium::drawSingleTextureVideoQuad(const CCVideoDrawQuad* quad, Program* program, float widthScaleFactor, Platform3DObject textureId)
+{
+ ASSERT(program && program->initialized());
+
+ GLC(context(), context()->activeTexture(GraphicsContext3D::TEXTURE0));
+ GLC(context(), context()->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId));
+
+ GLC(context(), context()->useProgram(program->program()));
+ GLC(context(), context()->uniform4f(program->vertexShader().texTransformLocation(), 0, 0, widthScaleFactor, 1));
+ GLC(context(), context()->uniform1i(program->fragmentShader().samplerLocation(), 0));
+
+ const IntSize& bounds = quad->quadRect().size();
+ drawTexturedQuad(quad->layerTransform(), bounds.width(), bounds.height(), quad->opacity(), sharedGeometryQuad(),
+ program->vertexShader().matrixLocation(),
+ program->fragmentShader().alphaLocation(),
+ -1);
+}
+
+void LayerRendererChromium::drawRGBA(const CCVideoDrawQuad* quad)
+{
+ const CCVideoLayerImpl::RGBAProgram* program = videoLayerRGBAProgram();
+ const CCVideoLayerImpl::Texture& texture = quad->textures()[VideoFrameChromium::rgbPlane];
+ float widthScaleFactor = static_cast<float>(texture.m_visibleSize.width()) / texture.m_texture->size().width();
+ drawSingleTextureVideoQuad(quad, program, widthScaleFactor, texture.m_texture->textureId());
+}
+
+void LayerRendererChromium::drawNativeTexture(const CCVideoDrawQuad* quad)
+{
+ const CCVideoLayerImpl::NativeTextureProgram* program = videoLayerNativeTextureProgram();
+ drawSingleTextureVideoQuad(quad, program, 1, quad->frame()->textureId());
+}
+
+bool LayerRendererChromium::copyFrameToTextures(const CCVideoDrawQuad* quad)
+{
+ const VideoFrameChromium* frame = quad->frame();
+
+ for (unsigned plane = 0; plane < frame->planes(); ++plane) {
+ ASSERT(quad->frame()->requiredTextureSize(plane) == quad->textures()[plane].m_texture->size());
+ copyPlaneToTexture(quad, frame->data(plane), plane);
+ }
+ for (unsigned plane = frame->planes(); plane < CCVideoLayerImpl::MaxPlanes; ++plane) {
+ CCVideoLayerImpl::Texture* texture = &quad->textures()[plane];
+ texture->m_texture.clear();
+ texture->m_visibleSize = IntSize();
+ }
+ return true;
+}
+
+void LayerRendererChromium::copyPlaneToTexture(const CCVideoDrawQuad* quad, const void* plane, int index)
+{
+ CCVideoLayerImpl::Texture& texture = quad->textures()[index];
+ TextureAllocator* allocator = renderSurfaceTextureAllocator();
+ texture.m_texture->bindTexture(context(), allocator);
+ GC3Denum format = texture.m_texture->format();
+ IntSize dimensions = texture.m_texture->size();
+
+ void* mem = static_cast<Extensions3DChromium*>(context()->getExtensions())->mapTexSubImage2DCHROMIUM(GraphicsContext3D::TEXTURE_2D, 0, 0, 0, dimensions.width(), dimensions.height(), format, GraphicsContext3D::UNSIGNED_BYTE, Extensions3DChromium::WRITE_ONLY);
+ if (mem) {
+ memcpy(mem, plane, dimensions.width() * dimensions.height());
+ GLC(context(), static_cast<Extensions3DChromium*>(context()->getExtensions())->unmapTexSubImage2DCHROMIUM(mem));
+ } else {
+ // 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, plane));
+ }
+}
+
void LayerRendererChromium::drawVideoQuad(const CCVideoDrawQuad* quad)
{
- CCLayerImpl* layer = quad->layer();
- layer->draw(this);
+ ASSERT(CCProxy::isImplThread());
+
+ if (!quad->frame())
+ return;
+
+ if (!copyFrameToTextures(quad))
+ return;
+
+ switch (quad->format()) {
+ case GraphicsContext3D::LUMINANCE:
+ drawYUV(quad);
+ break;
+ case GraphicsContext3D::RGBA:
+ drawRGBA(quad);
+ break;
+ case GraphicsContext3D::TEXTURE_2D:
+ drawNativeTexture(quad);
+ break;
+ default:
+ CRASH(); // Someone updated convertVFCFormatToGC3DFormat above but update this!
+ }
}
struct PluginProgramBinding {
Modified: trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h (108092 => 108093)
--- trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h 2012-02-17 18:19:18 UTC (rev 108092)
+++ trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h 2012-02-17 18:27:32 UTC (rev 108093)
@@ -168,6 +168,13 @@
void drawPluginQuad(const CCPluginDrawQuad*);
ManagedTexture* getOffscreenLayerTexture();
+ void copyPlaneToTexture(const CCVideoDrawQuad*, const void* plane, int index);
+ bool copyFrameToTextures(const CCVideoDrawQuad*);
+ template<class Program> void drawSingleTextureVideoQuad(const CCVideoDrawQuad*, Program*, float widthScaleFactor, Platform3DObject textureId);
+ void drawNativeTexture(const CCVideoDrawQuad*);
+ void drawRGBA(const CCVideoDrawQuad*);
+ void drawYUV(const CCVideoDrawQuad*);
+
void copyOffscreenTextureToDisplay();
void setDrawViewportRect(const IntRect&, bool flipY);
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp (108092 => 108093)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp 2012-02-17 18:19:18 UTC (rev 108092)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp 2012-02-17 18:27:32 UTC (rev 108093)
@@ -115,11 +115,6 @@
return false;
}
-void CCLayerImpl::draw(LayerRendererChromium*)
-{
- ASSERT_NOT_REACHED();
-}
-
PassOwnPtr<CCSharedQuadState> CCLayerImpl::createSharedQuadState() const
{
IntRect layerClipRect;
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h (108092 => 108093)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h 2012-02-17 18:19:18 UTC (rev 108092)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h 2012-02-17 18:27:32 UTC (rev 108093)
@@ -75,9 +75,9 @@
PassOwnPtr<CCSharedQuadState> createSharedQuadState() const;
virtual void willDraw(LayerRendererChromium*) { }
virtual void appendQuads(CCQuadList&, const CCSharedQuadState*);
+ virtual void didDraw() { }
void appendDebugBorderQuad(CCQuadList&, const CCSharedQuadState*) const;
- virtual void draw(LayerRendererChromium*);
void unreserveContentsTexture();
virtual void bindContentsTexture(LayerRendererChromium*);
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp (108092 => 108093)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp 2012-02-17 18:19:18 UTC (rev 108092)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp 2012-02-17 18:27:32 UTC (rev 108093)
@@ -31,6 +31,7 @@
#include "LayerRendererChromium.h"
#include "TraceEvent.h"
#include "cc/CCDamageTracker.h"
+#include "cc/CCLayerIterator.h"
#include "cc/CCLayerTreeHost.h"
#include "cc/CCLayerTreeHostCommon.h"
#include "cc/CCPageScaleAnimation.h"
@@ -187,9 +188,8 @@
return surfaceDamageRect;
}
-void CCLayerTreeHostImpl::calculateRenderPasses(CCRenderPassList& passes)
+void CCLayerTreeHostImpl::calculateRenderPasses(CCRenderPassList& passes, CCLayerList& renderSurfaceLayerList)
{
- CCLayerList renderSurfaceLayerList;
renderSurfaceLayerList.append(rootLayer());
if (!rootLayer()->renderSurface())
@@ -263,13 +263,23 @@
return;
CCRenderPassList passes;
- calculateRenderPasses(passes);
+ CCLayerList renderSurfaceLayerList;
+ calculateRenderPasses(passes, renderSurfaceLayerList);
optimizeRenderPasses(passes);
m_layerRenderer->beginDrawingFrame();
for (size_t i = 0; i < passes.size(); ++i)
m_layerRenderer->drawRenderPass(passes[i].get());
+
+ typedef CCLayerIterator<CCLayerImpl, CCRenderSurface, CCLayerIteratorActions::BackToFront> CCLayerIteratorType;
+
+ CCLayerIteratorType end = CCLayerIteratorType::end(&renderSurfaceLayerList);
+ for (CCLayerIteratorType it = CCLayerIteratorType::begin(&renderSurfaceLayerList); it != end; ++it) {
+ if (it.representsItself())
+ it->didDraw();
+ }
+
m_layerRenderer->finishDrawingFrame();
++m_frameNumber;
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h (108092 => 108093)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h 2012-02-17 18:19:18 UTC (rev 108092)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h 2012-02-17 18:27:32 UTC (rev 108093)
@@ -133,7 +133,7 @@
void adjustScrollsForPageScaleChange(float);
void updateMaxScrollPosition();
void trackDamageForAllSurfaces(CCLayerImpl* rootDrawLayer, const CCLayerList& renderSurfaceLayerList);
- void calculateRenderPasses(CCRenderPassList&);
+ void calculateRenderPasses(CCRenderPassList&, CCLayerList& renderSurfaceLayerList);
void optimizeRenderPasses(CCRenderPassList&);
IntSize contentSize() const;
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCVideoDrawQuad.cpp (108092 => 108093)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCVideoDrawQuad.cpp 2012-02-17 18:19:18 UTC (rev 108092)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCVideoDrawQuad.cpp 2012-02-17 18:27:32 UTC (rev 108093)
@@ -29,16 +29,17 @@
namespace WebCore {
-PassOwnPtr<CCVideoDrawQuad> CCVideoDrawQuad::create(const CCSharedQuadState* sharedQuadState, const IntRect& quadRect, CCLayerImpl* layer)
+PassOwnPtr<CCVideoDrawQuad> CCVideoDrawQuad::create(const CCSharedQuadState* sharedQuadState, const IntRect& quadRect, CCVideoLayerImpl::Texture* textures, VideoFrameChromium* frame, GC3Denum format)
{
- return adoptPtr(new CCVideoDrawQuad(sharedQuadState, quadRect, layer));
+ return adoptPtr(new CCVideoDrawQuad(sharedQuadState, quadRect, textures, frame, format));
}
-CCVideoDrawQuad::CCVideoDrawQuad(const CCSharedQuadState* sharedQuadState, const IntRect& quadRect, CCLayerImpl* layer)
+CCVideoDrawQuad::CCVideoDrawQuad(const CCSharedQuadState* sharedQuadState, const IntRect& quadRect, CCVideoLayerImpl::Texture* textures, VideoFrameChromium* frame, GC3Denum format)
: CCDrawQuad(sharedQuadState, CCDrawQuad::VideoContent, quadRect)
- , m_layer(layer)
+ , m_textures(textures)
+ , m_frame(frame)
+ , m_format(format)
{
- ASSERT(m_layer);
}
}
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCVideoDrawQuad.h (108092 => 108093)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCVideoDrawQuad.h 2012-02-17 18:19:18 UTC (rev 108092)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCVideoDrawQuad.h 2012-02-17 18:27:32 UTC (rev 108093)
@@ -26,23 +26,28 @@
#ifndef CCVideoDrawQuad_h
#define CCVideoDrawQuad_h
+#include "GraphicsTypes3D.h"
#include "cc/CCDrawQuad.h"
+#include "cc/CCVideoLayerImpl.h"
#include <wtf/PassOwnPtr.h>
namespace WebCore {
-class CCLayerImpl;
class CCVideoDrawQuad : public CCDrawQuad {
WTF_MAKE_NONCOPYABLE(CCVideoDrawQuad);
public:
- static PassOwnPtr<CCVideoDrawQuad> create(const CCSharedQuadState*, const IntRect&, CCLayerImpl*);
+ static PassOwnPtr<CCVideoDrawQuad> create(const CCSharedQuadState*, const IntRect&, CCVideoLayerImpl::Texture* textures, VideoFrameChromium*, GC3Denum format);
- CCLayerImpl* layer() const { return m_layer; }
+ CCVideoLayerImpl::Texture* textures() const { return m_textures; }
+ VideoFrameChromium* frame() const { return m_frame; }
+ GC3Denum format() const { return m_format; }
private:
- CCVideoDrawQuad(const CCSharedQuadState*, const IntRect&, CCLayerImpl*);
+ CCVideoDrawQuad(const CCSharedQuadState*, const IntRect&, CCVideoLayerImpl::Texture* textures, VideoFrameChromium*, GC3Denum format);
- CCLayerImpl* m_layer;
+ CCVideoLayerImpl::Texture* m_textures;
+ VideoFrameChromium* m_frame;
+ GC3Denum m_format;
};
}
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.cpp (108092 => 108093)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.cpp 2012-02-17 18:19:18 UTC (rev 108092)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.cpp 2012-02-17 18:27:32 UTC (rev 108093)
@@ -112,7 +112,7 @@
return GraphicsContext3D::INVALID_VALUE;
}
-void CCVideoLayerImpl::draw(LayerRendererChromium* layerRenderer)
+void CCVideoLayerImpl::willDraw(LayerRendererChromium* layerRenderer)
{
ASSERT(CCProxy::isImplThread());
@@ -121,92 +121,46 @@
if (!m_provider)
return;
- VideoFrameChromium* frame = m_provider->getCurrentFrame();
- if (!frame)
- return;
- GC3Denum format = convertVFCFormatToGC3DFormat(frame->format());
+ m_frame = m_provider->getCurrentFrame();
- if (format == GraphicsContext3D::INVALID_VALUE) {
- m_provider->putCurrentFrame(frame);
+ if (!m_frame)
return;
- }
- if (!copyFrameToTextures(frame, format, layerRenderer)) {
- m_provider->putCurrentFrame(frame);
+ m_format = convertVFCFormatToGC3DFormat(m_frame->format());
+
+ if (m_format == GraphicsContext3D::INVALID_VALUE) {
+ m_provider->putCurrentFrame(m_frame);
+ m_frame = 0;
return;
}
- switch (format) {
- case GraphicsContext3D::LUMINANCE:
- drawYUV(layerRenderer);
- break;
- case GraphicsContext3D::RGBA:
- drawRGBA(layerRenderer);
- break;
- case GraphicsContext3D::TEXTURE_2D:
- drawNativeTexture(layerRenderer);
- break;
- default:
- CRASH(); // Someone updated convertVFCFormatToGC3DFormat above but update this!
+ if (!reserveTextures(m_frame, m_format, layerRenderer)) {
+ m_provider->putCurrentFrame(m_frame);
+ m_frame = 0;
}
-
- for (unsigned plane = 0; plane < frame->planes(); ++plane)
- m_textures[plane].m_texture->unreserve();
- m_provider->putCurrentFrame(frame);
}
void CCVideoLayerImpl::appendQuads(CCQuadList& quadList, const CCSharedQuadState* sharedQuadState)
{
IntRect quadRect(IntPoint(), bounds());
- quadList.append(CCVideoDrawQuad::create(sharedQuadState, quadRect, this));
+ quadList.append(CCVideoDrawQuad::create(sharedQuadState, quadRect, m_textures, m_frame, m_format));
}
-bool CCVideoLayerImpl::copyFrameToTextures(const VideoFrameChromium* frame, GC3Denum format, LayerRendererChromium* layerRenderer)
+void CCVideoLayerImpl::didDraw()
{
- if (frame->format() == VideoFrameChromium::NativeTexture) {
- m_nativeTextureId = frame->textureId();
- m_nativeTextureSize = IntSize(frame->width(), frame->height());
- return true;
- }
+ ASSERT(CCProxy::isImplThread());
- if (!reserveTextures(frame, format, layerRenderer))
- return false;
+ MutexLocker locker(m_providerMutex);
- for (unsigned plane = 0; plane < frame->planes(); ++plane) {
- ASSERT(frame->requiredTextureSize(plane) == m_textures[plane].m_texture->size());
- copyPlaneToTexture(layerRenderer, frame->data(plane), plane);
- }
- for (unsigned plane = frame->planes(); plane < MaxPlanes; ++plane) {
- Texture& texture = m_textures[plane];
- texture.m_texture.clear();
- texture.m_visibleSize = IntSize();
- }
- m_planes = frame->planes();
- return true;
-}
+ if (!m_provider || !m_frame)
+ return;
-void CCVideoLayerImpl::copyPlaneToTexture(LayerRendererChromium* layerRenderer, const void* plane, int index)
-{
- Texture& texture = m_textures[index];
- GraphicsContext3D* context = layerRenderer->context();
- TextureAllocator* allocator = layerRenderer->renderSurfaceTextureAllocator();
- texture.m_texture->bindTexture(context, allocator);
- GC3Denum format = texture.m_texture->format();
- IntSize dimensions = texture.m_texture->size();
-
- void* mem = static_cast<Extensions3DChromium*>(context->getExtensions())->mapTexSubImage2DCHROMIUM(GraphicsContext3D::TEXTURE_2D, 0, 0, 0, dimensions.width(), dimensions.height(), format, GraphicsContext3D::UNSIGNED_BYTE, Extensions3DChromium::WRITE_ONLY);
- if (mem) {
- memcpy(mem, plane, dimensions.width() * dimensions.height());
- GLC(context, static_cast<Extensions3DChromium*>(context->getExtensions())->unmapTexSubImage2DCHROMIUM(mem));
- } else {
- // 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, plane));
- }
+ for (unsigned plane = 0; plane < m_frame->planes(); ++plane)
+ m_textures[plane].m_texture->unreserve();
+ m_provider->putCurrentFrame(m_frame);
}
-static IntSize computeVisibleSize(const VideoFrameChromium* frame, unsigned plane)
+IntSize CCVideoLayerImpl::computeVisibleSize(const VideoFrameChromium* frame, unsigned plane)
{
int visibleWidth = frame->width(plane);
int visibleHeight = frame->height(plane);
@@ -259,81 +213,6 @@
return true;
}
-void CCVideoLayerImpl::drawYUV(LayerRendererChromium* layerRenderer) const
-{
- const YUVProgram* program = layerRenderer->videoLayerYUVProgram();
- ASSERT(program && program->initialized());
-
- GraphicsContext3D* context = layerRenderer->context();
- const Texture& yTexture = m_textures[VideoFrameChromium::yPlane];
- const Texture& uTexture = m_textures[VideoFrameChromium::uPlane];
- const Texture& vTexture = m_textures[VideoFrameChromium::vPlane];
-
- GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE1));
- GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, yTexture.m_texture->textureId()));
- GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE2));
- GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, uTexture.m_texture->textureId()));
- GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE3));
- GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, vTexture.m_texture->textureId()));
-
- GLC(context, context->useProgram(program->program()));
-
- float yWidthScaleFactor = static_cast<float>(yTexture.m_visibleSize.width()) / yTexture.m_texture->size().width();
- // Arbitrarily take the u sizes because u and v dimensions are identical.
- float uvWidthScaleFactor = static_cast<float>(uTexture.m_visibleSize.width()) / uTexture.m_texture->size().width();
- GLC(context, context->uniform1f(program->vertexShader().yWidthScaleFactorLocation(), yWidthScaleFactor));
- GLC(context, context->uniform1f(program->vertexShader().uvWidthScaleFactorLocation(), uvWidthScaleFactor));
-
- GLC(context, context->uniform1i(program->fragmentShader().yTextureLocation(), 1));
- GLC(context, context->uniform1i(program->fragmentShader().uTextureLocation(), 2));
- GLC(context, context->uniform1i(program->fragmentShader().vTextureLocation(), 3));
-
- GLC(context, context->uniformMatrix3fv(program->fragmentShader().ccMatrixLocation(), 0, const_cast<float*>(yuv2RGB), 1));
- GLC(context, context->uniform3fv(program->fragmentShader().yuvAdjLocation(), const_cast<float*>(yuvAdjust), 1));
-
- layerRenderer->drawTexturedQuad(drawTransform(), bounds().width(), bounds().height(), drawOpacity(), FloatQuad(),
- program->vertexShader().matrixLocation(),
- program->fragmentShader().alphaLocation(),
- -1);
-
- // Reset active texture back to texture 0.
- GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
-}
-
-template<class Program>
-void CCVideoLayerImpl::drawCommon(LayerRendererChromium* layerRenderer, Program* program, float widthScaleFactor, Platform3DObject textureId) const
-{
- ASSERT(program && program->initialized());
-
- GraphicsContext3D* context = layerRenderer->context();
-
- GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
- GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId));
-
- GLC(context, context->useProgram(program->program()));
- GLC(context, context->uniform4f(program->vertexShader().texTransformLocation(), 0, 0, widthScaleFactor, 1));
- GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0));
-
- layerRenderer->drawTexturedQuad(drawTransform(), bounds().width(), bounds().height(), drawOpacity(), layerRenderer->sharedGeometryQuad(),
- program->vertexShader().matrixLocation(),
- program->fragmentShader().alphaLocation(),
- -1);
-}
-
-void CCVideoLayerImpl::drawRGBA(LayerRendererChromium* layerRenderer) const
-{
- const RGBAProgram* program = layerRenderer->videoLayerRGBAProgram();
- const Texture& texture = m_textures[VideoFrameChromium::rgbPlane];
- float widthScaleFactor = static_cast<float>(texture.m_visibleSize.width()) / texture.m_texture->size().width();
- drawCommon(layerRenderer, program, widthScaleFactor, texture.m_texture->textureId());
-}
-
-void CCVideoLayerImpl::drawNativeTexture(LayerRendererChromium* layerRenderer) const
-{
- const NativeTextureProgram* program = layerRenderer->videoLayerNativeTextureProgram();
- drawCommon(layerRenderer, program, 1, m_nativeTextureId);
-}
-
void CCVideoLayerImpl::dumpLayerProperties(TextStream& ts, int indent) const
{
writeIndent(ts, indent);
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.h (108092 => 108093)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.h 2012-02-17 18:19:18 UTC (rev 108092)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.h 2012-02-17 18:27:32 UTC (rev 108093)
@@ -46,48 +46,46 @@
}
virtual ~CCVideoLayerImpl();
+ virtual void willDraw(LayerRendererChromium*);
virtual void appendQuads(CCQuadList&, const CCSharedQuadState*);
+ virtual void didDraw();
typedef ProgramBinding<VertexShaderPosTexTransform, FragmentShaderRGBATexFlipAlpha> RGBAProgram;
typedef ProgramBinding<VertexShaderPosTexYUVStretch, FragmentShaderYUVVideo> YUVProgram;
typedef ProgramBinding<VertexShaderPosTexTransform, FragmentShaderRGBATexFlipAlpha> NativeTextureProgram;
- virtual void draw(LayerRendererChromium*);
-
virtual void dumpLayerProperties(TextStream&, int indent) const;
+ Mutex& providerMutex() { return m_providerMutex; }
+ VideoFrameProvider* provider() const { return m_provider; }
+
// VideoFrameProvider::Client implementation (callable on any thread).
virtual void stopUsingProvider();
+ static const float yuv2RGB[9];
+ static const float yuvAdjust[3];
+
+ struct Texture {
+ OwnPtr<ManagedTexture> m_texture;
+ IntSize m_visibleSize;
+ };
+ enum { MaxPlanes = 3 };
+
private:
explicit CCVideoLayerImpl(int, VideoFrameProvider*);
+ static IntSize computeVisibleSize(const VideoFrameChromium*, unsigned plane);
virtual const char* layerTypeAsString() const { return "VideoLayer"; }
- bool copyFrameToTextures(const VideoFrameChromium*, GC3Denum format, LayerRendererChromium*);
- void copyPlaneToTexture(LayerRendererChromium*, const void* plane, int index);
bool reserveTextures(const VideoFrameChromium*, GC3Denum format, LayerRendererChromium*);
- void drawYUV(LayerRendererChromium*) const;
- void drawRGBA(LayerRendererChromium*) const;
- void drawNativeTexture(LayerRendererChromium*) const;
- template<class Program> void drawCommon(LayerRendererChromium*, Program*, float widthScaleFactor, Platform3DObject textureId) const;
Mutex m_providerMutex; // Guards m_provider below.
VideoFrameProvider* m_provider;
- static const float yuv2RGB[9];
- static const float yuvAdjust[3];
-
- struct Texture {
- OwnPtr<ManagedTexture> m_texture;
- IntSize m_visibleSize;
- };
- enum { MaxPlanes = 3 };
Texture m_textures[MaxPlanes];
- int m_planes;
- Platform3DObject m_nativeTextureId;
- IntSize m_nativeTextureSize;
+ VideoFrameChromium* m_frame;
+ GC3Denum m_format;
};
}
Modified: trunk/Source/WebKit/chromium/ChangeLog (108092 => 108093)
--- trunk/Source/WebKit/chromium/ChangeLog 2012-02-17 18:19:18 UTC (rev 108092)
+++ trunk/Source/WebKit/chromium/ChangeLog 2012-02-17 18:27:32 UTC (rev 108093)
@@ -1,3 +1,23 @@
+2012-02-17 Tim Dresser <[email protected]>
+
+ [chromium] Refactor video drawing to be more data driven
+ https://bugs.webkit.org/show_bug.cgi?id=76720
+
+ Reviewed by James Robinson.
+
+ CCLayerTreeHostImplTest.didDrawCalledOnAllLayers ensures that
+ CCLayerImpl::didDraw() is called on all layers, including layers
+ on different render surfaces.
+
+ * tests/CCLayerTreeHostImplTest.cpp:
+ (DidDrawCheckLayer):
+ (WebKit::DidDrawCheckLayer::create):
+ (WebKit::DidDrawCheckLayer::didDraw):
+ (WebKit::DidDrawCheckLayer::didDrawCalled):
+ (WebKit::DidDrawCheckLayer::DidDrawCheckLayer):
+ (WebKit):
+ (WebKit::TEST_F):
+
2012-02-17 Ilya Tikhonovsky <[email protected]>
Unreviewed, rolling out r108071.
Modified: trunk/Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp (108092 => 108093)
--- trunk/Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp 2012-02-17 18:19:18 UTC (rev 108092)
+++ trunk/Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp 2012-02-17 18:27:32 UTC (rev 108093)
@@ -276,6 +276,63 @@
}
}
+class DidDrawCheckLayer : public CCLayerImpl {
+public:
+ static PassRefPtr<DidDrawCheckLayer> create(int id) { return adoptRef(new DidDrawCheckLayer(id)); }
+
+ virtual void didDraw()
+ {
+ m_didDrawCalled = true;
+ }
+
+ bool didDrawCalled() const { return m_didDrawCalled; }
+
+private:
+ explicit DidDrawCheckLayer(int id)
+ : CCLayerImpl(id)
+ , m_didDrawCalled(false)
+ {
+ setAnchorPoint(FloatPoint(0, 0));
+ setBounds(IntSize(10, 10));
+ setDrawsContent(true);
+ }
+
+ bool m_didDrawCalled;
+};
+
+TEST_F(CCLayerTreeHostImplTest, didDrawCalledOnAllLayers)
+{
+ GraphicsContext3D::Attributes attrs;
+ RefPtr<GraphicsContext3D> context = GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(new FakeWebGraphicsContext3D()), attrs, 0, GraphicsContext3D::RenderDirectlyToHostWindow, GraphicsContext3DPrivate::ForUseOnThisThread);
+ m_hostImpl->initializeLayerRenderer(context);
+ m_hostImpl->setViewportSize(IntSize(10, 10));
+
+ RefPtr<DidDrawCheckLayer> root = DidDrawCheckLayer::create(0);
+ m_hostImpl->setRootLayer(root);
+
+ RefPtr<DidDrawCheckLayer> layer1 = DidDrawCheckLayer::create(1);
+ root->addChild(layer1);
+
+ RefPtr<DidDrawCheckLayer> layer2 = DidDrawCheckLayer::create(2);
+ layer1->addChild(layer2);
+
+ layer1->setOpacity(0.3);
+ layer1->setPreserves3D(false);
+
+ EXPECT_FALSE(root->didDrawCalled());
+ EXPECT_FALSE(layer1->didDrawCalled());
+ EXPECT_FALSE(layer2->didDrawCalled());
+
+ m_hostImpl->drawLayers();
+
+ EXPECT_TRUE(root->didDrawCalled());
+ EXPECT_TRUE(layer1->didDrawCalled());
+ EXPECT_TRUE(layer2->didDrawCalled());
+
+ EXPECT_NE(root->renderSurface(), layer1->renderSurface());
+ EXPECT_TRUE(!!layer1->renderSurface());
+}
+
class BlendStateTrackerContext: public FakeWebGraphicsContext3D {
public:
BlendStateTrackerContext() : m_blend(false) { }
@@ -507,7 +564,6 @@
class FakeDrawableCCLayerImpl: public CCLayerImpl {
public:
explicit FakeDrawableCCLayerImpl(int id) : CCLayerImpl(id) { }
- virtual void draw(LayerRendererChromium* renderer) { }
};
// Only reshape when we know we are going to draw. Otherwise, the reshape