https://bugs.webkit.org/show_bug.cgi?id=72672
Patch by David Reveman <reveman@chromium.org> on 2012-01-21
Reviewed by Adam Barth.
Source/WebCore:
Use a new set of textures for each commit when incremental
texture updates are enabled.
This patch is tested by the following unit test:
- CCLayerTreeHostTestAtomicCommit.runMultiThread
* platform/graphics/chromium/ManagedTexture.cpp:
(WebCore::ManagedTexture::ManagedTexture):
(WebCore::ManagedTexture::steal):
* platform/graphics/chromium/ManagedTexture.h:
* platform/graphics/chromium/TiledLayerChromium.cpp:
(WebCore::TiledLayerChromium::prepareToUpdateTiles):
* platform/graphics/chromium/cc/CCLayerTreeHost.cpp:
(WebCore::CCLayerTreeHost::initialize):
(WebCore::CCLayerTreeHost::commitComplete):
(WebCore::CCLayerTreeHost::deleteTextureAfterCommit):
* platform/graphics/chromium/cc/CCLayerTreeHost.h:
(WebCore::CCSettings::CCSettings):
* platform/graphics/chromium/cc/CCProxy.h:
* platform/graphics/chromium/cc/CCSingleThreadProxy.h:
(WebCore::CCSingleThreadProxy::partialTextureUpdateCapability):
* platform/graphics/chromium/cc/CCThreadProxy.cpp:
(WebCore::CCThreadProxy::scheduledActionUpdateMoreResources):
(WebCore::CCThreadProxy::partialTextureUpdateCapability):
* platform/graphics/chromium/cc/CCThreadProxy.h:
Source/WebKit/chromium:
Add CCLayerTreeHostTestAtomicCommit test that verifies atomicity
of commits.
* tests/CCLayerTreeHostTest.cpp:
(WTF::CompositorFakeWebGraphicsContext3DWithTextureTracking::create):
(WTF::CompositorFakeWebGraphicsContext3DWithTextureTracking::createTexture):
(WTF::CompositorFakeWebGraphicsContext3DWithTextureTracking::deleteTexture):
(WTF::CompositorFakeWebGraphicsContext3DWithTextureTracking::bindTexture):
(WTF::CompositorFakeWebGraphicsContext3DWithTextureTracking::numTextures):
(WTF::CompositorFakeWebGraphicsContext3DWithTextureTracking::texture):
(WTF::CompositorFakeWebGraphicsContext3DWithTextureTracking::resetTextures):
(WTF::CompositorFakeWebGraphicsContext3DWithTextureTracking::numUsedTextures):
(WTF::CompositorFakeWebGraphicsContext3DWithTextureTracking::usedTexture):
(WTF::CompositorFakeWebGraphicsContext3DWithTextureTracking::resetUsedTextures):
(WTF::CompositorFakeWebGraphicsContext3DWithTextureTracking::CompositorFakeWebGraphicsContext3DWithTextureTracking):
(WTF::MockLayerTreeHostClient::createLayerTreeHostContext3D):
(WTF::MockContentLayerDelegate::drawsContent):
(WTF::MockContentLayerDelegate::paintContents):
(WTF::MockContentLayerDelegate::notifySyncRequired):
(WTF::CCLayerTreeHostTestAtomicCommit::CCLayerTreeHostTestAtomicCommit):
(WTF::CCLayerTreeHostTestAtomicCommit::beginTest):
(WTF::CCLayerTreeHostTestAtomicCommit::commitCompleteOnCCThread):
(WTF::CCLayerTreeHostTestAtomicCommit::drawLayersOnCCThread):
(WTF::CCLayerTreeHostTestAtomicCommit::layout):
(WTF::CCLayerTreeHostTestAtomicCommit::afterTest):
(WTF::TEST_F):
* tests/CompositorFakeWebGraphicsContext3D.h:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@105583
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2012-01-21 David Reveman <reveman@chromium.org>
+
+ [Chromium] Incremental texture updates are not atomic.
+ https://bugs.webkit.org/show_bug.cgi?id=72672
+
+ Reviewed by Adam Barth.
+
+ Use a new set of textures for each commit when incremental
+ texture updates are enabled.
+
+ This patch is tested by the following unit test:
+ - CCLayerTreeHostTestAtomicCommit.runMultiThread
+
+ * platform/graphics/chromium/ManagedTexture.cpp:
+ (WebCore::ManagedTexture::ManagedTexture):
+ (WebCore::ManagedTexture::steal):
+ * platform/graphics/chromium/ManagedTexture.h:
+ * platform/graphics/chromium/TiledLayerChromium.cpp:
+ (WebCore::TiledLayerChromium::prepareToUpdateTiles):
+ * platform/graphics/chromium/cc/CCLayerTreeHost.cpp:
+ (WebCore::CCLayerTreeHost::initialize):
+ (WebCore::CCLayerTreeHost::commitComplete):
+ (WebCore::CCLayerTreeHost::deleteTextureAfterCommit):
+ * platform/graphics/chromium/cc/CCLayerTreeHost.h:
+ (WebCore::CCSettings::CCSettings):
+ * platform/graphics/chromium/cc/CCProxy.h:
+ * platform/graphics/chromium/cc/CCSingleThreadProxy.h:
+ (WebCore::CCSingleThreadProxy::partialTextureUpdateCapability):
+ * platform/graphics/chromium/cc/CCThreadProxy.cpp:
+ (WebCore::CCThreadProxy::scheduledActionUpdateMoreResources):
+ (WebCore::CCThreadProxy::partialTextureUpdateCapability):
+ * platform/graphics/chromium/cc/CCThreadProxy.h:
+
2012-01-21 Pablo Flouret <pablof@motorola.com>
Add .url attribute alongside .URL in EventSource and WebSocket to comply with the specs but not break existing usage.
{
}
+ManagedTexture::ManagedTexture(TextureManager* manager, TextureToken token, IntSize size, unsigned format, unsigned textureId)
+ : m_textureManager(manager)
+ , m_token(token)
+ , m_size(size)
+ , m_format(format)
+ , m_textureId(textureId)
+{
+}
+
ManagedTexture::~ManagedTexture()
{
if (m_token)
context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, m_textureId, 0);
}
+PassOwnPtr<ManagedTexture> ManagedTexture::steal()
+{
+ OwnPtr<ManagedTexture> texture = adoptPtr(new ManagedTexture(m_textureManager, m_token, m_size, m_format, m_textureId));
+ m_token = 0;
+ m_size = IntSize();
+ m_format = 0;
+ m_textureId = 0;
+ return texture.release();
+}
+
+
}
#endif // USE(ACCELERATED_COMPOSITING)
unsigned format() const { return m_format; }
unsigned textureId() const { return m_textureId; }
+ // Steal token and textureId by instantiates a new texture using existing
+ // member variables.
+ PassOwnPtr<ManagedTexture> steal();
+
private:
explicit ManagedTexture(TextureManager*);
+ ManagedTexture(TextureManager*, TextureToken, IntSize, unsigned format, unsigned textureId);
TextureManager* m_textureManager;
TextureToken m_token;
if (!tile)
tile = createTile(i, j);
+ // Do post commit deletion of current texture when partial texture
+ // updates are not used.
+ if (tile->isDirty() && layerTreeHost() && !layerTreeHost()->settings().partialTextureUpdates)
+ layerTreeHost()->deleteTextureAfterCommit(tile->managedTexture()->steal());
+
if (!tile->managedTexture()->isValid(m_tiler->tileSize(), m_textureFormat))
tile->m_dirtyRect = m_tiler->tileRect(tile);
// Update m_settings based on capabilities that we got back from the renderer.
m_settings.acceleratePainting = m_proxy->layerRendererCapabilities().usingAcceleratedPainting;
+ // Update m_settings based on partial update capability.
+ m_settings.partialTextureUpdates = m_settings.partialTextureUpdates && m_proxy->partialTextureUpdateCapability();
+
m_contentsTextureManager = TextureManager::create(TextureManager::highLimitBytes(viewportSize()),
TextureManager::reclaimLimitBytes(viewportSize()),
m_proxy->layerRendererCapabilities().maxTextureSize);
void CCLayerTreeHost::commitComplete()
{
+ m_deleteTextureAfterCommitList.clear();
clearPendingUpdate();
m_contentsTextureManager->unprotectAllTextures();
}
}
}
+void CCLayerTreeHost::deleteTextureAfterCommit(PassOwnPtr<ManagedTexture> texture)
+{
+ m_deleteTextureAfterCommitList.append(texture);
+}
+
}
, showPlatformLayerTree(false)
, refreshRate(0)
, perTilePainting(false)
- , partialSwapEnabled(false) { }
+ , partialSwapEnabled(false)
+ , partialTextureUpdates(true) { }
bool acceleratePainting;
bool compositeOffscreen;
double refreshRate;
bool perTilePainting;
bool partialSwapEnabled;
+ bool partialTextureUpdates;
};
// Provides information on an Impl's rendering capabilities back to the CCLayerTreeHost
void startRateLimiter(GraphicsContext3D*);
void stopRateLimiter(GraphicsContext3D*);
+ void deleteTextureAfterCommit(PassOwnPtr<ManagedTexture>);
+
protected:
CCLayerTreeHost(CCLayerTreeHostClient*, const CCSettings&);
bool initialize();
private:
typedef Vector<RefPtr<LayerChromium> > LayerList;
+ typedef Vector<OwnPtr<ManagedTexture> > TextureList;
enum PaintType { PaintVisible, PaintIdle };
static void paintContentsIfDirty(LayerChromium*, PaintType);
float m_pageScale;
float m_minPageScale, m_maxPageScale;
bool m_triggerIdlePaints;
+
+ TextureList m_deleteTextureAfterCommitList;
};
}
virtual void start() = 0; // Must be called before using the proxy.
virtual void stop() = 0; // Must be called before deleting the proxy.
+ // Whether sub-regions of textures can be updated or if complete texture
+ // updates are required.
+ virtual bool partialTextureUpdateCapability() const = 0;
+
// Debug hooks
#ifndef NDEBUG
static bool isMainThread();
virtual void setVisible(bool);
virtual void start();
virtual void stop();
+ virtual bool partialTextureUpdateCapability() const { return true; }
// CCLayerTreeHostImplClient implementation
virtual void onSwapBuffersCompleteOnImplThread() { ASSERT_NOT_REACHED(); }
using namespace WTF;
+namespace {
+
+static const size_t textureUpdatesPerFrame = 0;
+
+} // anonymous namespace
+
namespace WebCore {
PassOwnPtr<CCProxy> CCThreadProxy::create(CCLayerTreeHost* layerTreeHost)
{
TRACE_EVENT("CCThreadProxy::scheduledActionUpdateMoreResources", this, 0);
ASSERT(m_currentTextureUpdaterOnImplThread);
- static const int UpdatesPerFrame = 99999;
- m_currentTextureUpdaterOnImplThread->update(m_layerTreeHostImpl->context(), UpdatesPerFrame);
+ m_currentTextureUpdaterOnImplThread->update(m_layerTreeHostImpl->context(), textureUpdatesPerFrame > 0 ? textureUpdatesPerFrame : 99999);
}
void CCThreadProxy::scheduledActionCommit()
completion->signal();
}
+bool CCThreadProxy::partialTextureUpdateCapability() const
+{
+ return !textureUpdatesPerFrame;
+}
+
} // namespace WebCore
virtual void setVisible(bool);
virtual void start();
virtual void stop();
+ virtual bool partialTextureUpdateCapability() const;
// CCLayerTreeHostImplClient implementation
virtual void onSwapBuffersCompleteOnImplThread();
+2012-01-21 David Reveman <reveman@chromium.org>
+
+ [Chromium] Incremental texture updates are not atomic.
+ https://bugs.webkit.org/show_bug.cgi?id=72672
+
+ Reviewed by Adam Barth.
+
+ Add CCLayerTreeHostTestAtomicCommit test that verifies atomicity
+ of commits.
+
+ * tests/CCLayerTreeHostTest.cpp:
+ (WTF::CompositorFakeWebGraphicsContext3DWithTextureTracking::create):
+ (WTF::CompositorFakeWebGraphicsContext3DWithTextureTracking::createTexture):
+ (WTF::CompositorFakeWebGraphicsContext3DWithTextureTracking::deleteTexture):
+ (WTF::CompositorFakeWebGraphicsContext3DWithTextureTracking::bindTexture):
+ (WTF::CompositorFakeWebGraphicsContext3DWithTextureTracking::numTextures):
+ (WTF::CompositorFakeWebGraphicsContext3DWithTextureTracking::texture):
+ (WTF::CompositorFakeWebGraphicsContext3DWithTextureTracking::resetTextures):
+ (WTF::CompositorFakeWebGraphicsContext3DWithTextureTracking::numUsedTextures):
+ (WTF::CompositorFakeWebGraphicsContext3DWithTextureTracking::usedTexture):
+ (WTF::CompositorFakeWebGraphicsContext3DWithTextureTracking::resetUsedTextures):
+ (WTF::CompositorFakeWebGraphicsContext3DWithTextureTracking::CompositorFakeWebGraphicsContext3DWithTextureTracking):
+ (WTF::MockLayerTreeHostClient::createLayerTreeHostContext3D):
+ (WTF::MockContentLayerDelegate::drawsContent):
+ (WTF::MockContentLayerDelegate::paintContents):
+ (WTF::MockContentLayerDelegate::notifySyncRequired):
+ (WTF::CCLayerTreeHostTestAtomicCommit::CCLayerTreeHostTestAtomicCommit):
+ (WTF::CCLayerTreeHostTestAtomicCommit::beginTest):
+ (WTF::CCLayerTreeHostTestAtomicCommit::commitCompleteOnCCThread):
+ (WTF::CCLayerTreeHostTestAtomicCommit::drawLayersOnCCThread):
+ (WTF::CCLayerTreeHostTestAtomicCommit::layout):
+ (WTF::CCLayerTreeHostTestAtomicCommit::afterTest):
+ (WTF::TEST_F):
+ * tests/CompositorFakeWebGraphicsContext3D.h:
+
2012-01-21 Sheriff Bot <webkit.review.bot@gmail.com>
Unreviewed, rolling out r105564.
#include "cc/CCLayerTreeHost.h"
-#include "CompositorFakeGraphicsContext3D.h"
+#include "CompositorFakeWebGraphicsContext3D.h"
#include "ContentLayerChromium.h"
-#include "FakeWebGraphicsContext3D.h"
+#include "GraphicsContext3DPrivate.h"
#include "LayerChromium.h"
#include "TextureManager.h"
#include "WebCompositor.h"
#include "cc/CCThreadTask.h"
#include "platform/WebKitPlatformSupport.h"
#include "platform/WebThread.h"
+#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <webkit/support/webkit_support.h>
#include <wtf/MainThread.h>
TestHooks* m_testHooks;
};
+class CompositorFakeWebGraphicsContext3DWithTextureTracking : public CompositorFakeWebGraphicsContext3D {
+public:
+ static PassOwnPtr<CompositorFakeWebGraphicsContext3DWithTextureTracking> create(Attributes attrs)
+ {
+ return adoptPtr(new CompositorFakeWebGraphicsContext3DWithTextureTracking(attrs));
+ }
+
+ virtual WebGLId createTexture()
+ {
+ WebGLId texture = m_textures.size() + 1;
+ m_textures.append(texture);
+ return texture;
+ }
+
+ virtual void deleteTexture(WebGLId texture)
+ {
+ for (size_t i = 0; i < m_textures.size(); i++) {
+ if (m_textures[i] == texture) {
+ m_textures.remove(i);
+ break;
+ }
+ }
+ }
+
+ virtual void bindTexture(WGC3Denum /* target */, WebGLId texture)
+ {
+ m_usedTextures.add(texture);
+ }
+
+ int numTextures() const { return static_cast<int>(m_textures.size()); }
+ int texture(int i) const { return m_textures[i]; }
+ void resetTextures() { m_textures.clear(); }
+
+ int numUsedTextures() const { return static_cast<int>(m_usedTextures.size()); }
+ bool usedTexture(int texture) const { return m_usedTextures.find(texture) != m_usedTextures.end(); }
+ void resetUsedTextures() { m_usedTextures.clear(); }
+
+private:
+ explicit CompositorFakeWebGraphicsContext3DWithTextureTracking(Attributes attrs) : CompositorFakeWebGraphicsContext3D(attrs)
+ {
+ }
+
+ Vector<WebGLId> m_textures;
+ HashSet<WebGLId> m_usedTextures;
+};
+
// Implementation of CCLayerTreeHost callback interface.
class MockLayerTreeHostClient : public CCLayerTreeHostClient {
public:
virtual PassRefPtr<GraphicsContext3D> createLayerTreeHostContext3D()
{
- return createCompositorMockGraphicsContext3D(GraphicsContext3D::Attributes());
+ GraphicsContext3D::Attributes attrs;
+ WebGraphicsContext3D::Attributes webAttrs;
+ webAttrs.alpha = attrs.alpha;
+
+ OwnPtr<WebGraphicsContext3D> webContext = CompositorFakeWebGraphicsContext3DWithTextureTracking::create(webAttrs);
+ return GraphicsContext3DPrivate::createGraphicsContextFromWebContext(
+ webContext.release(), attrs, 0,
+ GraphicsContext3D::RenderDirectlyToHostWindow,
+ GraphicsContext3DPrivate::ForUseOnAnotherThread);
}
virtual void didCommitAndDrawFrame()
runTest(false);
}
+class MockContentLayerDelegate : public ContentLayerDelegate {
+public:
+ bool drawsContent() const { return true; }
+ MOCK_CONST_METHOD0(preserves3D, bool());
+ void paintContents(GraphicsContext&, const IntRect&) { }
+ void notifySyncRequired() { }
+};
+
+// Verify atomicity of commits and reuse of textures.
+class CCLayerTreeHostTestAtomicCommit : public CCLayerTreeHostTest {
+public:
+ CCLayerTreeHostTestAtomicCommit()
+ : m_updateCheckLayer(ContentLayerChromiumWithUpdateTracking::create(&m_delegate))
+ , m_numCommits(0)
+ {
+ // Make sure partial texture updates are turned off.
+ m_settings.partialTextureUpdates = false;
+ }
+
+ virtual void beginTest()
+ {
+ m_layerTreeHost->setRootLayer(m_updateCheckLayer);
+ m_layerTreeHost->setViewportSize(IntSize(10, 10));
+
+ postSetNeedsCommitToMainThread();
+ postSetNeedsRedrawToMainThread();
+ }
+
+ virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl* impl)
+ {
+ CompositorFakeWebGraphicsContext3DWithTextureTracking* context = static_cast<CompositorFakeWebGraphicsContext3DWithTextureTracking*>(GraphicsContext3DPrivate::extractWebGraphicsContext3D(impl->context()));
+
+ switch (impl->frameNumber()) {
+ case 0:
+ // Number of textures should be one.
+ EXPECT_EQ(1, context->numTextures());
+ // Number of textures used for commit should be one.
+ EXPECT_EQ(1, context->numUsedTextures());
+ // Verify used texture is correct.
+ EXPECT_TRUE(context->usedTexture(context->texture(0)));
+
+ context->resetUsedTextures();
+ break;
+ case 1:
+ // Number of textures should be two as the first texture
+ // is used by impl thread and cannot by used for update.
+ EXPECT_EQ(2, context->numTextures());
+ // Number of textures used for commit should still be one.
+ EXPECT_EQ(1, context->numUsedTextures());
+ // First texture should not have been used.
+ EXPECT_FALSE(context->usedTexture(context->texture(0)));
+ // New texture should have been used.
+ EXPECT_TRUE(context->usedTexture(context->texture(1)));
+
+ context->resetUsedTextures();
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+ }
+
+ virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl)
+ {
+ CompositorFakeWebGraphicsContext3DWithTextureTracking* context = static_cast<CompositorFakeWebGraphicsContext3DWithTextureTracking*>(GraphicsContext3DPrivate::extractWebGraphicsContext3D(impl->context()));
+
+ // Number of textures used for draw should always be one.
+ EXPECT_EQ(1, context->numUsedTextures());
+
+ if (impl->frameNumber() < 2) {
+ context->resetUsedTextures();
+ postSetNeedsAnimateAndCommitToMainThread();
+ postSetNeedsRedrawToMainThread();
+ } else
+ endTest();
+ }
+
+ virtual void layout()
+ {
+ m_updateCheckLayer->setNeedsDisplay();
+ }
+
+ virtual void afterTest()
+ {
+ }
+
+private:
+ MockContentLayerDelegate m_delegate;
+ RefPtr<ContentLayerChromiumWithUpdateTracking> m_updateCheckLayer;
+ int m_numCommits;
+};
+
+TEST_F(CCLayerTreeHostTestAtomicCommit, runMultiThread)
+{
+ runTest(true);
+}
+
} // namespace
virtual void getShaderiv(WebGLId, WGC3Denum, WGC3Dint* value) { *value = 1; }
virtual void getProgramiv(WebGLId, WGC3Denum, WGC3Dint* value) { *value = 1; }
-private:
+protected:
explicit CompositorFakeWebGraphicsContext3D(Attributes attrs)
{
m_attrs = attrs;