Enable webkit_compositor_unittests
These are unit tests of the webkit compositor bindings that bind the WebKit Platform Web*Layer* family of APIs to cc. They currently depend on some test utilities in cc. Also updates snapshot to WebKit r127194 BUG= Review URL: https://chromiumcodereview.appspot.com/10909020 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@154307 0039d316-1c4b-4281-b951-d872f2087c98
This commit is contained in:
cc
CCLayerTreeHostImpl.cppCCLayerTreeHostImplTest.cppCCLayerTreeHostTest.cppCCScheduler.cppCCScheduler.hCCSchedulerTest.cppCCTextureUpdateController.cppCCTextureUpdateController.hCCTextureUpdateControllerTest.cppCCThreadProxy.cppCCThreadProxy.hcc_tests.gypcopyfiles.py
test
webkit/compositor
LayerChromiumTest.cppTextureCopierTest.cppTextureLayerChromiumTest.cppThrottledTextureUploaderTest.cppTiledLayerChromiumTest.cppTreeSynchronizerTest.cppWebAnimationTest.cppWebLayerTest.cppWebLayerTreeViewTest.cppWebTransformOperationsTest.cppWebTransformationMatrixTest.cppcompositor.gypcompositor_tests.gypcopyfiles.py
test
@ -749,6 +749,8 @@ void CCLayerTreeHostImpl::setDeviceScaleFactor(float deviceScaleFactor)
|
||||
if (deviceScaleFactor == m_deviceScaleFactor)
|
||||
return;
|
||||
m_deviceScaleFactor = deviceScaleFactor;
|
||||
|
||||
updateMaxScrollPosition();
|
||||
}
|
||||
|
||||
|
||||
|
@ -380,6 +380,24 @@ TEST_F(CCLayerTreeHostImplTest, nonFastScrollableRegionWithOffset)
|
||||
EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(10, 10), CCInputHandlerClient::Wheel), CCInputHandlerClient::ScrollOnMainThread);
|
||||
}
|
||||
|
||||
TEST_F(CCLayerTreeHostImplTest, maxScrollPositionChangedByDeviceScaleFactor)
|
||||
{
|
||||
setupScrollAndContentsLayers(IntSize(100, 100));
|
||||
|
||||
float deviceScaleFactor = 2;
|
||||
IntSize layoutViewport(25, 25);
|
||||
IntSize deviceViewport(layoutViewport);
|
||||
deviceViewport.scale(deviceScaleFactor);
|
||||
m_hostImpl->setViewportSize(layoutViewport, deviceViewport);
|
||||
m_hostImpl->setDeviceScaleFactor(deviceScaleFactor);
|
||||
EXPECT_EQ(m_hostImpl->rootLayer()->maxScrollPosition(), IntSize(25, 25));
|
||||
|
||||
deviceScaleFactor = 1;
|
||||
m_hostImpl->setViewportSize(layoutViewport, layoutViewport);
|
||||
m_hostImpl->setDeviceScaleFactor(deviceScaleFactor);
|
||||
EXPECT_EQ(m_hostImpl->rootLayer()->maxScrollPosition(), IntSize(75, 75));
|
||||
}
|
||||
|
||||
TEST_F(CCLayerTreeHostImplTest, pinchGesture)
|
||||
{
|
||||
setupScrollAndContentsLayers(IntSize(100, 100));
|
||||
|
@ -497,6 +497,63 @@ TEST_F(CCLayerTreeHostTestAbortFrameWhenInvisible, runMultiThread)
|
||||
runTest(true);
|
||||
}
|
||||
|
||||
// Makes sure that setNedsAnimate does not cause the commitRequested() state to be set.
|
||||
class CCLayerTreeHostTestSetNeedsAnimateShouldNotSetCommitRequested : public CCLayerTreeHostTest {
|
||||
public:
|
||||
CCLayerTreeHostTestSetNeedsAnimateShouldNotSetCommitRequested()
|
||||
: m_numCommits(0)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void beginTest() OVERRIDE
|
||||
{
|
||||
// The tests start up with a commit pending because we give them a root layer.
|
||||
// We need to wait for the commit to happen before doing anything.
|
||||
EXPECT_TRUE(m_layerTreeHost->commitRequested());
|
||||
}
|
||||
|
||||
virtual void animate(double monotonicTime) OVERRIDE
|
||||
{
|
||||
// We skip the first commit becasue its the commit that populates the
|
||||
// impl thread with a tree.
|
||||
if (!m_numCommits)
|
||||
return;
|
||||
|
||||
m_layerTreeHost->setNeedsAnimate();
|
||||
// Right now, commitRequested is going to be true, because during
|
||||
// beginFrame, we force commitRequested to true to prevent requests from
|
||||
// hitting the impl thread. But, when the next didCommit happens, we should
|
||||
// verify that commitRequested has gone back to false.
|
||||
}
|
||||
virtual void didCommit() OVERRIDE
|
||||
{
|
||||
if (!m_numCommits) {
|
||||
EXPECT_FALSE(m_layerTreeHost->commitRequested());
|
||||
m_layerTreeHost->setNeedsAnimate();
|
||||
EXPECT_FALSE(m_layerTreeHost->commitRequested());
|
||||
m_numCommits++;
|
||||
}
|
||||
|
||||
// Verifies that the setNeedsAnimate we made in ::animate did not
|
||||
// trigger commitRequested.
|
||||
EXPECT_FALSE(m_layerTreeHost->commitRequested());
|
||||
endTest();
|
||||
}
|
||||
|
||||
virtual void afterTest() OVERRIDE
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
int m_numCommits;
|
||||
};
|
||||
|
||||
TEST_F(CCLayerTreeHostTestSetNeedsAnimateShouldNotSetCommitRequested, runMultiThread)
|
||||
{
|
||||
runTest(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Trigger a frame with setNeedsCommit. Then, inside the resulting animate
|
||||
// callback, requet another frame using setNeedsAnimate. End the test when
|
||||
@ -891,7 +948,7 @@ private:
|
||||
int m_scrolls;
|
||||
};
|
||||
|
||||
TEST_F(CCLayerTreeHostTestScrollSimple, DISABLED_runMultiThread)
|
||||
TEST_F(CCLayerTreeHostTestScrollSimple, runMultiThread)
|
||||
{
|
||||
runTest(true);
|
||||
}
|
||||
@ -2218,8 +2275,7 @@ private:
|
||||
RefPtr<LayerChromium> m_rootScrollLayer;
|
||||
};
|
||||
|
||||
// https://bugs.webkit.org/show_bug.cgi?id=95358
|
||||
TEST_F(CCLayerTreeHostTestScrollChildLayer, DISABLED_runMultiThread)
|
||||
TEST_F(CCLayerTreeHostTestScrollChildLayer, runMultiThread)
|
||||
{
|
||||
runTest(true);
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ namespace WebCore {
|
||||
CCScheduler::CCScheduler(CCSchedulerClient* client, PassOwnPtr<CCFrameRateController> frameRateController)
|
||||
: m_client(client)
|
||||
, m_frameRateController(frameRateController)
|
||||
, m_hasMoreResourceUpdates(false)
|
||||
, m_updateMoreResourcesPending(false)
|
||||
{
|
||||
ASSERT(m_client);
|
||||
@ -68,10 +67,9 @@ void CCScheduler::setMainThreadNeedsLayerTextures()
|
||||
processScheduledActions();
|
||||
}
|
||||
|
||||
void CCScheduler::beginFrameComplete(bool hasResourceUpdates)
|
||||
void CCScheduler::beginFrameComplete()
|
||||
{
|
||||
TRACE_EVENT0("cc", "CCScheduler::beginFrameComplete");
|
||||
m_hasMoreResourceUpdates = hasResourceUpdates;
|
||||
m_stateMachine.beginFrameComplete();
|
||||
processScheduledActions();
|
||||
}
|
||||
@ -118,8 +116,7 @@ void CCScheduler::vsyncTick()
|
||||
{
|
||||
if (m_updateMoreResourcesPending) {
|
||||
m_updateMoreResourcesPending = false;
|
||||
ASSERT(m_hasMoreResourceUpdates);
|
||||
m_stateMachine.beginUpdateMoreResourcesComplete(true);
|
||||
m_stateMachine.beginUpdateMoreResourcesComplete(m_client->hasMoreResourceUpdates());
|
||||
}
|
||||
TRACE_EVENT0("cc", "CCScheduler::vsyncTick");
|
||||
|
||||
@ -128,17 +125,6 @@ void CCScheduler::vsyncTick()
|
||||
m_stateMachine.didLeaveVSync();
|
||||
}
|
||||
|
||||
void CCScheduler::updateResourcesComplete()
|
||||
{
|
||||
TRACE_EVENT0("cc", "CCScheduler::updateResourcesComplete");
|
||||
if (m_updateMoreResourcesPending) {
|
||||
m_updateMoreResourcesPending = false;
|
||||
m_stateMachine.beginUpdateMoreResourcesComplete(false);
|
||||
}
|
||||
m_hasMoreResourceUpdates = false;
|
||||
processScheduledActions();
|
||||
}
|
||||
|
||||
CCSchedulerStateMachine::Action CCScheduler::nextAction()
|
||||
{
|
||||
m_stateMachine.setCanDraw(m_client->canDraw());
|
||||
@ -168,7 +154,7 @@ void CCScheduler::processScheduledActions()
|
||||
m_client->scheduledActionBeginFrame();
|
||||
break;
|
||||
case CCSchedulerStateMachine::ACTION_BEGIN_UPDATE_MORE_RESOURCES:
|
||||
if (m_hasMoreResourceUpdates) {
|
||||
if (m_client->hasMoreResourceUpdates()) {
|
||||
m_client->scheduledActionUpdateMoreResources(m_frameRateController->nextTickTimeIfActivated());
|
||||
m_updateMoreResourcesPending = true;
|
||||
} else
|
||||
|
@ -33,6 +33,7 @@ struct CCScheduledActionDrawAndSwapResult {
|
||||
class CCSchedulerClient {
|
||||
public:
|
||||
virtual bool canDraw() = 0;
|
||||
virtual bool hasMoreResourceUpdates() const = 0;
|
||||
|
||||
virtual void scheduledActionBeginFrame() = 0;
|
||||
virtual CCScheduledActionDrawAndSwapResult scheduledActionDrawAndSwapIfPossible() = 0;
|
||||
@ -72,7 +73,7 @@ public:
|
||||
// Like setNeedsRedraw(), but ensures the draw will definitely happen even if we are not visible.
|
||||
void setNeedsForcedRedraw();
|
||||
|
||||
void beginFrameComplete(bool hasResourceUpdates);
|
||||
void beginFrameComplete();
|
||||
void beginFrameAborted();
|
||||
|
||||
void setMaxFramesPending(int);
|
||||
@ -89,8 +90,6 @@ public:
|
||||
// CCFrameRateControllerClient implementation
|
||||
virtual void vsyncTick() OVERRIDE;
|
||||
|
||||
void updateResourcesComplete();
|
||||
|
||||
private:
|
||||
CCScheduler(CCSchedulerClient*, PassOwnPtr<CCFrameRateController>);
|
||||
|
||||
@ -100,7 +99,6 @@ private:
|
||||
CCSchedulerClient* m_client;
|
||||
OwnPtr<CCFrameRateController> m_frameRateController;
|
||||
CCSchedulerStateMachine m_stateMachine;
|
||||
bool m_hasMoreResourceUpdates;
|
||||
bool m_updateMoreResourcesPending;
|
||||
};
|
||||
|
||||
|
@ -23,12 +23,14 @@ public:
|
||||
void reset()
|
||||
{
|
||||
m_actions.clear();
|
||||
m_hasMoreResourceUpdates = false;
|
||||
m_canDraw = true;
|
||||
m_drawWillHappen = true;
|
||||
m_swapWillHappenIfDrawHappens = true;
|
||||
m_numDraws = 0;
|
||||
}
|
||||
|
||||
void setHasMoreResourceUpdates(bool b) { m_hasMoreResourceUpdates = b; }
|
||||
void setCanDraw(bool b) { m_canDraw = b; }
|
||||
|
||||
int numDraws() const { return m_numDraws; }
|
||||
@ -44,6 +46,7 @@ public:
|
||||
}
|
||||
|
||||
virtual bool canDraw() OVERRIDE { return m_canDraw; }
|
||||
virtual bool hasMoreResourceUpdates() const OVERRIDE { return m_hasMoreResourceUpdates; }
|
||||
virtual void scheduledActionBeginFrame() OVERRIDE { m_actions.push_back("scheduledActionBeginFrame"); }
|
||||
virtual CCScheduledActionDrawAndSwapResult scheduledActionDrawAndSwapIfPossible() OVERRIDE
|
||||
{
|
||||
@ -90,9 +93,9 @@ TEST(CCSchedulerTest, RequestCommit)
|
||||
EXPECT_FALSE(timeSource->active());
|
||||
client.reset();
|
||||
|
||||
// Since, hasResourceUpdates is false,
|
||||
// Since, hasMoreResourceUpdates is set to false,
|
||||
// beginFrameComplete should commit
|
||||
scheduler->beginFrameComplete(false);
|
||||
scheduler->beginFrameComplete();
|
||||
EXPECT_EQ(1, client.numActions());
|
||||
EXPECT_STREQ("scheduledActionCommit", client.action(0));
|
||||
EXPECT_TRUE(timeSource->active());
|
||||
@ -126,9 +129,9 @@ TEST(CCSchedulerTest, RequestCommitAfterBeginFrame)
|
||||
// Now setNeedsCommit again. Calling here means we need a second frame.
|
||||
scheduler->setNeedsCommit();
|
||||
|
||||
// Since, hasResourceUpdates is false, and another commit is
|
||||
// Since, hasMoreResourceUpdates is set to false, and another commit is
|
||||
// needed, beginFrameComplete should commit, then begin another frame.
|
||||
scheduler->beginFrameComplete(false);
|
||||
scheduler->beginFrameComplete();
|
||||
EXPECT_EQ(1, client.numActions());
|
||||
EXPECT_STREQ("scheduledActionCommit", client.action(0));
|
||||
client.reset();
|
||||
@ -161,7 +164,7 @@ TEST(CCSchedulerTest, TextureAcquisitionCollision)
|
||||
EXPECT_FALSE(timeSource->active());
|
||||
|
||||
// Trigger the commit
|
||||
scheduler->beginFrameComplete(false);
|
||||
scheduler->beginFrameComplete();
|
||||
EXPECT_TRUE(timeSource->active());
|
||||
client.reset();
|
||||
|
||||
@ -189,7 +192,7 @@ TEST(CCSchedulerTest, VisibilitySwitchWithTextureAcquisition)
|
||||
scheduler->setVisible(true);
|
||||
|
||||
scheduler->setNeedsCommit();
|
||||
scheduler->beginFrameComplete(false);
|
||||
scheduler->beginFrameComplete();
|
||||
scheduler->setMainThreadNeedsLayerTextures();
|
||||
client.reset();
|
||||
// Verify that pending texture acquisition fires when visibility
|
||||
@ -358,7 +361,7 @@ TEST(CCSchedulerTest, RequestCommitInsideDraw)
|
||||
EXPECT_FALSE(timeSource->active());
|
||||
EXPECT_EQ(1, client.numDraws());
|
||||
EXPECT_TRUE(scheduler->commitPending());
|
||||
scheduler->beginFrameComplete(false);
|
||||
scheduler->beginFrameComplete();
|
||||
|
||||
timeSource->tick();
|
||||
EXPECT_EQ(2, client.numDraws());
|
||||
|
@ -92,9 +92,8 @@ void CCTextureUpdateController::updateTextures(CCResourceProvider* resourceProvi
|
||||
copier->flush();
|
||||
}
|
||||
|
||||
CCTextureUpdateController::CCTextureUpdateController(CCTextureUpdateControllerClient* client, CCThread* thread, PassOwnPtr<CCTextureUpdateQueue> queue, CCResourceProvider* resourceProvider, TextureCopier* copier, TextureUploader* uploader)
|
||||
: m_client(client)
|
||||
, m_timer(adoptPtr(new CCTimer(thread, this)))
|
||||
CCTextureUpdateController::CCTextureUpdateController(CCThread* thread, PassOwnPtr<CCTextureUpdateQueue> queue, CCResourceProvider* resourceProvider, TextureCopier* copier, TextureUploader* uploader)
|
||||
: m_timer(adoptPtr(new CCTimer(thread, this)))
|
||||
, m_queue(queue)
|
||||
, m_resourceProvider(resourceProvider)
|
||||
, m_copier(copier)
|
||||
@ -108,40 +107,34 @@ CCTextureUpdateController::~CCTextureUpdateController()
|
||||
{
|
||||
}
|
||||
|
||||
bool CCTextureUpdateController::hasMoreUpdates() const
|
||||
{
|
||||
return m_queue->hasMoreUpdates();
|
||||
}
|
||||
|
||||
void CCTextureUpdateController::updateMoreTextures(double monotonicTimeLimit)
|
||||
{
|
||||
ASSERT(monotonicTimeLimit >= m_monotonicTimeLimit);
|
||||
m_monotonicTimeLimit = monotonicTimeLimit;
|
||||
|
||||
// Update already in progress.
|
||||
if (m_timer->isActive())
|
||||
if (!m_queue->hasMoreUpdates())
|
||||
return;
|
||||
|
||||
// Call updateMoreTexturesNow() directly unless it's the first update
|
||||
// attempt. This ensures that we empty the update queue in a finite
|
||||
// amount of time.
|
||||
if (m_firstUpdateAttempt) {
|
||||
// Post a 0-delay task when no updates were left. When it runs,
|
||||
// updateTexturesCompleted() will be called.
|
||||
if (!updateMoreTexturesIfEnoughTimeRemaining())
|
||||
m_timer->startOneShot(0);
|
||||
|
||||
updateMoreTexturesIfEnoughTimeRemaining();
|
||||
m_firstUpdateAttempt = false;
|
||||
} else
|
||||
updateMoreTexturesNow();
|
||||
}
|
||||
|
||||
void CCTextureUpdateController::discardUploads()
|
||||
{
|
||||
// CCTextureUpdateControllerClient::updateTexturesCompleted will be
|
||||
// called when all remaining texture copies are done.
|
||||
m_queue->clearUploads();
|
||||
}
|
||||
|
||||
void CCTextureUpdateController::onTimerFired()
|
||||
{
|
||||
if (!updateMoreTexturesIfEnoughTimeRemaining())
|
||||
m_client->updateTexturesCompleted();
|
||||
if (!m_queue->hasMoreUpdates())
|
||||
return;
|
||||
|
||||
updateMoreTexturesIfEnoughTimeRemaining();
|
||||
}
|
||||
|
||||
double CCTextureUpdateController::monotonicTimeNow() const
|
||||
@ -159,16 +152,11 @@ size_t CCTextureUpdateController::updateMoreTexturesSize() const
|
||||
return textureUpdatesPerTick;
|
||||
}
|
||||
|
||||
bool CCTextureUpdateController::updateMoreTexturesIfEnoughTimeRemaining()
|
||||
void CCTextureUpdateController::updateMoreTexturesIfEnoughTimeRemaining()
|
||||
{
|
||||
if (!m_queue->hasMoreUpdates())
|
||||
return false;
|
||||
|
||||
bool hasTimeRemaining = monotonicTimeNow() < m_monotonicTimeLimit - updateMoreTexturesTime();
|
||||
if (hasTimeRemaining)
|
||||
updateMoreTexturesNow();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CCTextureUpdateController::updateMoreTexturesNow()
|
||||
|
@ -15,31 +15,21 @@ namespace WebCore {
|
||||
class TextureCopier;
|
||||
class TextureUploader;
|
||||
|
||||
class CCTextureUpdateControllerClient {
|
||||
public:
|
||||
virtual void updateTexturesCompleted() = 0;
|
||||
|
||||
protected:
|
||||
virtual ~CCTextureUpdateControllerClient() { }
|
||||
};
|
||||
|
||||
class CCTextureUpdateController : public CCTimerClient {
|
||||
WTF_MAKE_NONCOPYABLE(CCTextureUpdateController);
|
||||
public:
|
||||
static PassOwnPtr<CCTextureUpdateController> create(CCTextureUpdateControllerClient* client, CCThread* thread, PassOwnPtr<CCTextureUpdateQueue> queue, CCResourceProvider* resourceProvider, TextureCopier* copier, TextureUploader* uploader)
|
||||
static PassOwnPtr<CCTextureUpdateController> create(CCThread* thread, PassOwnPtr<CCTextureUpdateQueue> queue, CCResourceProvider* resourceProvider, TextureCopier* copier, TextureUploader* uploader)
|
||||
{
|
||||
return adoptPtr(new CCTextureUpdateController(client, thread, queue, resourceProvider, copier, uploader));
|
||||
return adoptPtr(new CCTextureUpdateController(thread, queue, resourceProvider, copier, uploader));
|
||||
}
|
||||
static size_t maxPartialTextureUpdates();
|
||||
static void updateTextures(CCResourceProvider*, TextureCopier*, TextureUploader*, CCTextureUpdateQueue*, size_t count);
|
||||
|
||||
virtual ~CCTextureUpdateController();
|
||||
|
||||
bool hasMoreUpdates() const;
|
||||
void updateMoreTextures(double monotonicTimeLimit);
|
||||
|
||||
// Discard all remaining uploads.
|
||||
void discardUploads();
|
||||
|
||||
// CCTimerClient implementation.
|
||||
virtual void onTimerFired() OVERRIDE;
|
||||
|
||||
@ -49,13 +39,11 @@ public:
|
||||
virtual size_t updateMoreTexturesSize() const;
|
||||
|
||||
protected:
|
||||
CCTextureUpdateController(CCTextureUpdateControllerClient*, CCThread*, PassOwnPtr<CCTextureUpdateQueue>, CCResourceProvider*, TextureCopier*, TextureUploader*);
|
||||
CCTextureUpdateController(CCThread*, PassOwnPtr<CCTextureUpdateQueue>, CCResourceProvider*, TextureCopier*, TextureUploader*);
|
||||
|
||||
// This returns true when there were textures left to update.
|
||||
bool updateMoreTexturesIfEnoughTimeRemaining();
|
||||
void updateMoreTexturesIfEnoughTimeRemaining();
|
||||
void updateMoreTexturesNow();
|
||||
|
||||
CCTextureUpdateControllerClient* m_client;
|
||||
OwnPtr<CCTimer> m_timer;
|
||||
OwnPtr<CCTextureUpdateQueue> m_queue;
|
||||
bool m_contentsTexturesPurged;
|
||||
|
@ -521,23 +521,11 @@ TEST_F(CCTextureUpdateControllerTest, TripleUpdateFinalUpdateAllPartial)
|
||||
EXPECT_EQ(kFullUploads + kPartialUploads, m_numTotalUploads);
|
||||
}
|
||||
|
||||
class FakeCCTextureUpdateControllerClient : public WebCore::CCTextureUpdateControllerClient {
|
||||
public:
|
||||
FakeCCTextureUpdateControllerClient() { reset(); }
|
||||
void reset() { m_completedCalled = false; }
|
||||
bool completedCalled() const { return m_completedCalled; }
|
||||
|
||||
virtual void updateTexturesCompleted() OVERRIDE { m_completedCalled = true; }
|
||||
|
||||
protected:
|
||||
bool m_completedCalled;
|
||||
};
|
||||
|
||||
class FakeCCTextureUpdateController : public WebCore::CCTextureUpdateController {
|
||||
public:
|
||||
static PassOwnPtr<FakeCCTextureUpdateController> create(WebCore::CCTextureUpdateControllerClient* client, WebCore::CCThread* thread, PassOwnPtr<CCTextureUpdateQueue> queue, CCResourceProvider* resourceProvider, TextureCopier* copier, TextureUploader* uploader)
|
||||
static PassOwnPtr<FakeCCTextureUpdateController> create(WebCore::CCThread* thread, PassOwnPtr<CCTextureUpdateQueue> queue, CCResourceProvider* resourceProvider, TextureCopier* copier, TextureUploader* uploader)
|
||||
{
|
||||
return adoptPtr(new FakeCCTextureUpdateController(client, thread, queue, resourceProvider, copier, uploader));
|
||||
return adoptPtr(new FakeCCTextureUpdateController(thread, queue, resourceProvider, copier, uploader));
|
||||
}
|
||||
|
||||
void setMonotonicTimeNow(double time) { m_monotonicTimeNow = time; }
|
||||
@ -548,8 +536,8 @@ public:
|
||||
virtual size_t updateMoreTexturesSize() const OVERRIDE { return m_updateMoreTexturesSize; }
|
||||
|
||||
protected:
|
||||
FakeCCTextureUpdateController(WebCore::CCTextureUpdateControllerClient* client, WebCore::CCThread* thread, PassOwnPtr<CCTextureUpdateQueue> queue, CCResourceProvider* resourceProvider, TextureCopier* copier, TextureUploader* uploader)
|
||||
: WebCore::CCTextureUpdateController(client, thread, queue, resourceProvider, copier, uploader)
|
||||
FakeCCTextureUpdateController(WebCore::CCThread* thread, PassOwnPtr<CCTextureUpdateQueue> queue, CCResourceProvider* resourceProvider, TextureCopier* copier, TextureUploader* uploader)
|
||||
: WebCore::CCTextureUpdateController(thread, queue, resourceProvider, copier, uploader)
|
||||
, m_monotonicTimeNow(0)
|
||||
, m_updateMoreTexturesTime(0)
|
||||
, m_updateMoreTexturesSize(0) { }
|
||||
@ -559,17 +547,8 @@ protected:
|
||||
size_t m_updateMoreTexturesSize;
|
||||
};
|
||||
|
||||
static void runPendingTasks(FakeCCThread* thread, FakeCCTextureUpdateController* controller)
|
||||
{
|
||||
while (thread->hasPendingTask()) {
|
||||
controller->setMonotonicTimeNow(controller->monotonicTimeNow() + thread->pendingDelayMs() / 1000.0);
|
||||
thread->runPendingTask();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(CCTextureUpdateControllerTest, UpdateMoreTextures)
|
||||
{
|
||||
FakeCCTextureUpdateControllerClient client;
|
||||
FakeCCThread thread;
|
||||
|
||||
setMaxUploadCountPerUpdate(1);
|
||||
@ -577,34 +556,39 @@ TEST_F(CCTextureUpdateControllerTest, UpdateMoreTextures)
|
||||
appendPartialUploadsToUpdateQueue(0);
|
||||
|
||||
DebugScopedSetImplThread implThread;
|
||||
OwnPtr<FakeCCTextureUpdateController> controller(FakeCCTextureUpdateController::create(&client, &thread, m_queue.release(), m_resourceProvider.get(), &m_copier, &m_uploader));
|
||||
OwnPtr<FakeCCTextureUpdateController> controller(FakeCCTextureUpdateController::create(&thread, m_queue.release(), m_resourceProvider.get(), &m_copier, &m_uploader));
|
||||
|
||||
controller->setMonotonicTimeNow(0);
|
||||
controller->setUpdateMoreTexturesTime(0.1);
|
||||
controller->setUpdateMoreTexturesSize(1);
|
||||
// Not enough time for any updates.
|
||||
controller->updateMoreTextures(0.09);
|
||||
runPendingTasks(&thread, controller.get());
|
||||
EXPECT_FALSE(thread.hasPendingTask());
|
||||
EXPECT_EQ(0, m_numBeginUploads);
|
||||
EXPECT_EQ(0, m_numEndUploads);
|
||||
|
||||
thread.reset();
|
||||
controller->setMonotonicTimeNow(0);
|
||||
controller->setUpdateMoreTexturesTime(0.1);
|
||||
controller->setUpdateMoreTexturesSize(1);
|
||||
// Only enough time for 1 update.
|
||||
controller->updateMoreTextures(0.12);
|
||||
runPendingTasks(&thread, controller.get());
|
||||
EXPECT_TRUE(thread.hasPendingTask());
|
||||
controller->setMonotonicTimeNow(thread.pendingDelayMs() / 1000.0);
|
||||
thread.runPendingTask();
|
||||
EXPECT_EQ(1, m_numBeginUploads);
|
||||
EXPECT_EQ(1, m_numEndUploads);
|
||||
EXPECT_EQ(1, m_numTotalUploads);
|
||||
|
||||
thread.reset();
|
||||
controller->setMonotonicTimeNow(0);
|
||||
controller->setUpdateMoreTexturesTime(0.1);
|
||||
controller->setUpdateMoreTexturesSize(1);
|
||||
// Enough time for 2 updates.
|
||||
controller->updateMoreTextures(0.22);
|
||||
runPendingTasks(&thread, controller.get());
|
||||
EXPECT_TRUE(client.completedCalled());
|
||||
EXPECT_TRUE(thread.hasPendingTask());
|
||||
controller->setMonotonicTimeNow(controller->monotonicTimeNow() + thread.pendingDelayMs() / 1000.0);
|
||||
thread.runPendingTask();
|
||||
EXPECT_EQ(3, m_numBeginUploads);
|
||||
EXPECT_EQ(3, m_numEndUploads);
|
||||
EXPECT_EQ(3, m_numTotalUploads);
|
||||
@ -612,7 +596,6 @@ TEST_F(CCTextureUpdateControllerTest, UpdateMoreTextures)
|
||||
|
||||
TEST_F(CCTextureUpdateControllerTest, NoMoreUpdates)
|
||||
{
|
||||
FakeCCTextureUpdateControllerClient client;
|
||||
FakeCCThread thread;
|
||||
|
||||
setMaxUploadCountPerUpdate(1);
|
||||
@ -620,26 +603,30 @@ TEST_F(CCTextureUpdateControllerTest, NoMoreUpdates)
|
||||
appendPartialUploadsToUpdateQueue(0);
|
||||
|
||||
DebugScopedSetImplThread implThread;
|
||||
OwnPtr<FakeCCTextureUpdateController> controller(FakeCCTextureUpdateController::create(&client, &thread, m_queue.release(), m_resourceProvider.get(), &m_copier, &m_uploader));
|
||||
OwnPtr<FakeCCTextureUpdateController> controller(FakeCCTextureUpdateController::create(&thread, m_queue.release(), m_resourceProvider.get(), &m_copier, &m_uploader));
|
||||
|
||||
controller->setMonotonicTimeNow(0);
|
||||
controller->setUpdateMoreTexturesTime(0.1);
|
||||
controller->setUpdateMoreTexturesSize(1);
|
||||
// Enough time for 3 updates but only 2 necessary.
|
||||
controller->updateMoreTextures(0.31);
|
||||
runPendingTasks(&thread, controller.get());
|
||||
EXPECT_TRUE(client.completedCalled());
|
||||
EXPECT_TRUE(thread.hasPendingTask());
|
||||
controller->setMonotonicTimeNow(controller->monotonicTimeNow() + thread.pendingDelayMs() / 1000.0);
|
||||
thread.runPendingTask();
|
||||
EXPECT_TRUE(thread.hasPendingTask());
|
||||
controller->setMonotonicTimeNow(controller->monotonicTimeNow() + thread.pendingDelayMs() / 1000.0);
|
||||
thread.runPendingTask();
|
||||
EXPECT_EQ(2, m_numBeginUploads);
|
||||
EXPECT_EQ(2, m_numEndUploads);
|
||||
EXPECT_EQ(2, m_numTotalUploads);
|
||||
|
||||
thread.reset();
|
||||
controller->setMonotonicTimeNow(0);
|
||||
controller->setUpdateMoreTexturesTime(0.1);
|
||||
controller->setUpdateMoreTexturesSize(1);
|
||||
// Enough time for updates but no more updates left.
|
||||
controller->updateMoreTextures(0.31);
|
||||
runPendingTasks(&thread, controller.get());
|
||||
EXPECT_TRUE(client.completedCalled());
|
||||
EXPECT_FALSE(thread.hasPendingTask());
|
||||
EXPECT_EQ(2, m_numBeginUploads);
|
||||
EXPECT_EQ(2, m_numEndUploads);
|
||||
EXPECT_EQ(2, m_numTotalUploads);
|
||||
@ -647,7 +634,6 @@ TEST_F(CCTextureUpdateControllerTest, NoMoreUpdates)
|
||||
|
||||
TEST_F(CCTextureUpdateControllerTest, UpdatesCompleteInFiniteTime)
|
||||
{
|
||||
FakeCCTextureUpdateControllerClient client;
|
||||
FakeCCThread thread;
|
||||
|
||||
setMaxUploadCountPerUpdate(1);
|
||||
@ -655,22 +641,25 @@ TEST_F(CCTextureUpdateControllerTest, UpdatesCompleteInFiniteTime)
|
||||
appendPartialUploadsToUpdateQueue(0);
|
||||
|
||||
DebugScopedSetImplThread implThread;
|
||||
OwnPtr<FakeCCTextureUpdateController> controller(FakeCCTextureUpdateController::create(&client, &thread, m_queue.release(), m_resourceProvider.get(), &m_copier, &m_uploader));
|
||||
OwnPtr<FakeCCTextureUpdateController> controller(FakeCCTextureUpdateController::create(&thread, m_queue.release(), m_resourceProvider.get(), &m_copier, &m_uploader));
|
||||
|
||||
controller->setMonotonicTimeNow(0);
|
||||
controller->setUpdateMoreTexturesTime(0.5);
|
||||
controller->setUpdateMoreTexturesSize(1);
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
if (client.completedCalled())
|
||||
if (!controller->hasMoreUpdates())
|
||||
break;
|
||||
|
||||
// Not enough time for any updates.
|
||||
controller->updateMoreTextures(0.4);
|
||||
runPendingTasks(&thread, controller.get());
|
||||
|
||||
if (thread.hasPendingTask()) {
|
||||
controller->setMonotonicTimeNow(controller->monotonicTimeNow() + thread.pendingDelayMs() / 1000.0);
|
||||
thread.runPendingTask();
|
||||
}
|
||||
}
|
||||
|
||||
EXPECT_TRUE(client.completedCalled());
|
||||
EXPECT_EQ(2, m_numBeginUploads);
|
||||
EXPECT_EQ(2, m_numEndUploads);
|
||||
EXPECT_EQ(2, m_numTotalUploads);
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "CCLayerTreeHost.h"
|
||||
#include "CCScheduler.h"
|
||||
#include "CCScopedThreadProxy.h"
|
||||
#include "CCTextureUpdateController.h"
|
||||
#include "CCThreadTask.h"
|
||||
#include "TraceEvent.h"
|
||||
#include <public/WebSharedGraphicsContext3D.h>
|
||||
@ -47,6 +48,7 @@ PassOwnPtr<CCProxy> CCThreadProxy::create(CCLayerTreeHost* layerTreeHost)
|
||||
CCThreadProxy::CCThreadProxy(CCLayerTreeHost* layerTreeHost)
|
||||
: m_animateRequested(false)
|
||||
, m_commitRequested(false)
|
||||
, m_commitRequestSentToImplThread(false)
|
||||
, m_forcedCommitRequested(false)
|
||||
, m_layerTreeHost(layerTreeHost)
|
||||
, m_compositorIdentifier(-1)
|
||||
@ -275,7 +277,11 @@ void CCThreadProxy::setNeedsAnimate()
|
||||
|
||||
TRACE_EVENT0("cc", "CCThreadProxy::setNeedsAnimate");
|
||||
m_animateRequested = true;
|
||||
setNeedsCommit();
|
||||
|
||||
if (m_commitRequestSentToImplThread)
|
||||
return;
|
||||
m_commitRequestSentToImplThread = true;
|
||||
CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::setNeedsCommitOnImplThread));
|
||||
}
|
||||
|
||||
void CCThreadProxy::setNeedsCommit()
|
||||
@ -283,9 +289,12 @@ void CCThreadProxy::setNeedsCommit()
|
||||
ASSERT(isMainThread());
|
||||
if (m_commitRequested)
|
||||
return;
|
||||
|
||||
TRACE_EVENT0("cc", "CCThreadProxy::setNeedsCommit");
|
||||
m_commitRequested = true;
|
||||
|
||||
if (m_commitRequestSentToImplThread)
|
||||
return;
|
||||
m_commitRequestSentToImplThread = true;
|
||||
CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::setNeedsCommitOnImplThread));
|
||||
}
|
||||
|
||||
@ -293,8 +302,7 @@ void CCThreadProxy::didLoseContextOnImplThread()
|
||||
{
|
||||
ASSERT(isImplThread());
|
||||
TRACE_EVENT0("cc", "CCThreadProxy::didLoseContextOnImplThread");
|
||||
if (m_currentTextureUpdateControllerOnImplThread)
|
||||
m_currentTextureUpdateControllerOnImplThread->discardUploads();
|
||||
m_currentTextureUpdateControllerOnImplThread.clear();
|
||||
m_schedulerOnImplThread->didLoseContext();
|
||||
}
|
||||
|
||||
@ -468,6 +476,7 @@ void CCThreadProxy::beginFrame()
|
||||
// the paint, m_commitRequested will be set to false to allow new commit
|
||||
// requests to be scheduled.
|
||||
m_commitRequested = true;
|
||||
m_commitRequestSentToImplThread = true;
|
||||
|
||||
// On the other hand, the animationRequested flag needs to be cleared
|
||||
// here so that any animation requests generated by the apply or animate
|
||||
@ -480,6 +489,7 @@ void CCThreadProxy::beginFrame()
|
||||
|
||||
if (!m_inCompositeAndReadback && !m_layerTreeHost->visible()) {
|
||||
m_commitRequested = false;
|
||||
m_commitRequestSentToImplThread = false;
|
||||
m_forcedCommitRequested = false;
|
||||
|
||||
TRACE_EVENT0("cc", "EarlyOut_NotVisible");
|
||||
@ -496,6 +506,7 @@ void CCThreadProxy::beginFrame()
|
||||
// layout when painted will trigger another setNeedsCommit inside
|
||||
// updateLayers.
|
||||
m_commitRequested = false;
|
||||
m_commitRequestSentToImplThread = false;
|
||||
m_forcedCommitRequested = false;
|
||||
|
||||
if (!m_layerTreeHost->initializeRendererIfNeeded())
|
||||
@ -512,11 +523,16 @@ void CCThreadProxy::beginFrame()
|
||||
m_texturesAcquired = false;
|
||||
|
||||
m_layerTreeHost->willCommit();
|
||||
// Before applying scrolls and calling animate, we set m_animateRequested to false.
|
||||
// If it is true now, it means setNeedAnimate was called again. Call setNeedsCommit
|
||||
// now so that we get begin frame when this one is done.
|
||||
if (m_animateRequested)
|
||||
setNeedsCommit();
|
||||
// Before applying scrolls and calling animate, we set m_animateRequested to
|
||||
// false. If it is true now, it means setNeedAnimate was called again, but
|
||||
// during a state when m_commitRequestSentToImplThread = true. We need to
|
||||
// force that call to happen again now so that the commit request is sent to
|
||||
// the impl thread.
|
||||
if (m_animateRequested) {
|
||||
// Forces setNeedsAnimate to consider posting a commit task.
|
||||
m_animateRequested = false;
|
||||
setNeedsAnimate();
|
||||
}
|
||||
|
||||
// Notify the impl thread that the beginFrame has completed. This will
|
||||
// begin the commit process, which is blocking from the main thread's
|
||||
@ -558,12 +574,10 @@ void CCThreadProxy::beginFrameCompleteOnImplThread(CCCompletionEvent* completion
|
||||
} else
|
||||
m_resetContentsTexturesPurgedAfterCommitOnImplThread = true;
|
||||
|
||||
bool hasResourceUpdates = queue->hasMoreUpdates();
|
||||
if (hasResourceUpdates)
|
||||
m_currentTextureUpdateControllerOnImplThread = CCTextureUpdateController::create(this, CCProxy::implThread(), queue, m_layerTreeHostImpl->resourceProvider(), m_layerTreeHostImpl->renderer()->textureCopier(), m_layerTreeHostImpl->renderer()->textureUploader());
|
||||
m_currentTextureUpdateControllerOnImplThread = CCTextureUpdateController::create(CCProxy::implThread(), queue, m_layerTreeHostImpl->resourceProvider(), m_layerTreeHostImpl->renderer()->textureCopier(), m_layerTreeHostImpl->renderer()->textureUploader());
|
||||
m_commitCompletionEventOnImplThread = completion;
|
||||
|
||||
m_schedulerOnImplThread->beginFrameComplete(hasResourceUpdates);
|
||||
m_schedulerOnImplThread->beginFrameComplete();
|
||||
}
|
||||
|
||||
void CCThreadProxy::beginFrameAbortedOnImplThread()
|
||||
@ -576,6 +590,13 @@ void CCThreadProxy::beginFrameAbortedOnImplThread()
|
||||
m_schedulerOnImplThread->beginFrameAborted();
|
||||
}
|
||||
|
||||
bool CCThreadProxy::hasMoreResourceUpdates() const
|
||||
{
|
||||
if (!m_currentTextureUpdateControllerOnImplThread)
|
||||
return false;
|
||||
return m_currentTextureUpdateControllerOnImplThread->hasMoreUpdates();
|
||||
}
|
||||
|
||||
bool CCThreadProxy::canDraw()
|
||||
{
|
||||
ASSERT(isImplThread());
|
||||
@ -595,6 +616,7 @@ void CCThreadProxy::scheduledActionCommit()
|
||||
{
|
||||
TRACE_EVENT0("cc", "CCThreadProxy::scheduledActionCommit");
|
||||
ASSERT(isImplThread());
|
||||
ASSERT(!hasMoreResourceUpdates());
|
||||
ASSERT(m_commitCompletionEventOnImplThread);
|
||||
|
||||
m_currentTextureUpdateControllerOnImplThread.clear();
|
||||
@ -732,12 +754,6 @@ CCScheduledActionDrawAndSwapResult CCThreadProxy::scheduledActionDrawAndSwapForc
|
||||
return scheduledActionDrawAndSwapInternal(true);
|
||||
}
|
||||
|
||||
void CCThreadProxy::updateTexturesCompleted()
|
||||
{
|
||||
ASSERT(isImplThread());
|
||||
m_schedulerOnImplThread->updateResourcesComplete();
|
||||
}
|
||||
|
||||
void CCThreadProxy::didCommitAndDrawFrame()
|
||||
{
|
||||
ASSERT(isMainThread());
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include "CCLayerTreeHostImpl.h"
|
||||
#include "CCProxy.h"
|
||||
#include "CCScheduler.h"
|
||||
#include "CCTextureUpdateController.h"
|
||||
#include <wtf/OwnPtr.h>
|
||||
|
||||
namespace WebCore {
|
||||
@ -20,10 +19,11 @@ class CCLayerTreeHost;
|
||||
class CCScheduler;
|
||||
class CCScopedThreadProxy;
|
||||
class CCTextureUpdateQueue;
|
||||
class CCTextureUpdateController;
|
||||
class CCThread;
|
||||
class CCThreadProxyContextRecreationTimer;
|
||||
|
||||
class CCThreadProxy : public CCProxy, CCLayerTreeHostImplClient, CCSchedulerClient, CCTextureUpdateControllerClient {
|
||||
class CCThreadProxy : public CCProxy, CCLayerTreeHostImplClient, CCSchedulerClient {
|
||||
public:
|
||||
static PassOwnPtr<CCProxy> create(CCLayerTreeHost*);
|
||||
|
||||
@ -64,6 +64,7 @@ public:
|
||||
|
||||
// CCSchedulerClient implementation
|
||||
virtual bool canDraw() OVERRIDE;
|
||||
virtual bool hasMoreResourceUpdates() const OVERRIDE;
|
||||
virtual void scheduledActionBeginFrame() OVERRIDE;
|
||||
virtual CCScheduledActionDrawAndSwapResult scheduledActionDrawAndSwapIfPossible() OVERRIDE;
|
||||
virtual CCScheduledActionDrawAndSwapResult scheduledActionDrawAndSwapForced() OVERRIDE;
|
||||
@ -72,9 +73,6 @@ public:
|
||||
virtual void scheduledActionBeginContextRecreation() OVERRIDE;
|
||||
virtual void scheduledActionAcquireLayerTexturesForMainThread() OVERRIDE;
|
||||
|
||||
// CCTextureUpdateControllerClient implementation
|
||||
virtual void updateTexturesCompleted() OVERRIDE;
|
||||
|
||||
private:
|
||||
explicit CCThreadProxy(CCLayerTreeHost*);
|
||||
friend class CCThreadProxyContextRecreationTimer;
|
||||
@ -129,8 +127,9 @@ private:
|
||||
void setNeedsForcedCommitOnImplThread();
|
||||
|
||||
// Accessed on main thread only.
|
||||
bool m_animateRequested;
|
||||
bool m_commitRequested;
|
||||
bool m_animateRequested; // Set only when setNeedsAnimate is called.
|
||||
bool m_commitRequested; // Set only when setNeedsCommit is called.
|
||||
bool m_commitRequestSentToImplThread; // Set by setNeedsCommit and setNeedsAnimate.
|
||||
bool m_forcedCommitRequested;
|
||||
OwnPtr<CCThreadProxyContextRecreationTimer> m_contextRecreationTimer;
|
||||
CCLayerTreeHost* m_layerTreeHost;
|
||||
|
@ -40,6 +40,8 @@
|
||||
'CCThreadedTest.h',
|
||||
'CCTiledLayerImplTest.cpp',
|
||||
'CCTimerTest.cpp',
|
||||
],
|
||||
'cc_tests_support_files': [
|
||||
'test/CCAnimationTestCommon.cpp',
|
||||
'test/CCAnimationTestCommon.h',
|
||||
'test/CCLayerTestCommon.cpp',
|
||||
@ -60,7 +62,7 @@
|
||||
'test/FakeWebGraphicsContext3D.h',
|
||||
'test/FakeWebScrollbarThemeGeometry.h',
|
||||
'test/MockCCQuadCuller.h',
|
||||
]
|
||||
],
|
||||
},
|
||||
'conditions': [
|
||||
['use_libcc_for_compositor==1 and component!="shared_library"', {
|
||||
@ -69,15 +71,16 @@
|
||||
'target_name': 'cc_unittests',
|
||||
'type': 'executable',
|
||||
'dependencies': [
|
||||
'<(DEPTH)/base/base.gyp:test_support_base',
|
||||
'<(DEPTH)/testing/gtest.gyp:gtest',
|
||||
'<(DEPTH)/testing/gmock.gyp:gmock',
|
||||
'<(DEPTH)/webkit/support/webkit_support.gyp:webkit_support',
|
||||
'<(DEPTH)/skia/skia.gyp:skia',
|
||||
'../base/base.gyp:test_support_base',
|
||||
'../testing/gtest.gyp:gtest',
|
||||
'../testing/gmock.gyp:gmock',
|
||||
'../webkit/support/webkit_support.gyp:webkit_support',
|
||||
'../skia/skia.gyp:skia',
|
||||
# We have to depend on WTF directly to pick up the correct defines for WTF headers - for instance USE_SYSTEM_MALLOC.
|
||||
'<(DEPTH)/third_party/WebKit/Source/WTF/WTF.gyp/WTF.gyp:wtf',
|
||||
'<(DEPTH)/third_party/WebKit/Source/Platform/Platform.gyp/Platform.gyp:webkit_platform',
|
||||
'../third_party/WebKit/Source/WTF/WTF.gyp/WTF.gyp:wtf',
|
||||
'../third_party/WebKit/Source/Platform/Platform.gyp/Platform.gyp:webkit_platform',
|
||||
'cc.gyp:cc',
|
||||
'cc_test_support',
|
||||
],
|
||||
'defines': [
|
||||
'WTF_USE_ACCELERATED_COMPOSITING=1',
|
||||
@ -92,6 +95,30 @@
|
||||
'test/run_all_unittests.cc',
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'cc_test_support',
|
||||
'type': 'static_library',
|
||||
'defines': [
|
||||
'WTF_USE_ACCELERATED_COMPOSITING=1',
|
||||
],
|
||||
'include_dirs': [
|
||||
'stubs',
|
||||
'test',
|
||||
'.',
|
||||
'..',
|
||||
],
|
||||
'dependencies': [
|
||||
'../ui/gl/gl.gyp:gl',
|
||||
'../testing/gtest.gyp:gtest',
|
||||
'../testing/gmock.gyp:gmock',
|
||||
'../skia/skia.gyp:skia',
|
||||
'../third_party/WebKit/Source/WTF/WTF.gyp/WTF.gyp:wtf',
|
||||
'../third_party/WebKit/Source/Platform/Platform.gyp/Platform.gyp:webkit_platform',
|
||||
],
|
||||
'sources': [
|
||||
'<@(cc_tests_support_files)',
|
||||
],
|
||||
},
|
||||
],
|
||||
}, {
|
||||
'targets': [
|
||||
|
@ -61,16 +61,15 @@ def Readfile(gypfile):
|
||||
obj = eval(cc_gyp.read())
|
||||
return obj
|
||||
|
||||
def Main():
|
||||
files = Readfile("cc.gyp")['variables']['cc_source_files']
|
||||
def CopyFiles(files):
|
||||
for f in files:
|
||||
dst = Copy(f)
|
||||
FixCopyrightHeader(dst)
|
||||
|
||||
files = Readfile("cc_tests.gyp")['variables']['cc_tests_source_files']
|
||||
for f in files:
|
||||
dst = Copy(f)
|
||||
FixCopyrightHeader(dst)
|
||||
def Main():
|
||||
CopyFiles(Readfile("cc.gyp")['variables']['cc_source_files'])
|
||||
CopyFiles(Readfile("cc_tests.gyp")['variables']['cc_tests_source_files'])
|
||||
CopyFiles(Readfile("cc_tests.gyp")['variables']['cc_tests_support_files'])
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
|
@ -65,6 +65,16 @@ FakeFloatAnimationCurve::~FakeFloatAnimationCurve()
|
||||
{
|
||||
}
|
||||
|
||||
double FakeFloatAnimationCurve::duration() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
float FakeFloatAnimationCurve::getValue(double now) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
PassOwnPtr<WebCore::CCAnimationCurve> FakeFloatAnimationCurve::clone() const
|
||||
{
|
||||
return adoptPtr(new FakeFloatAnimationCurve);
|
||||
@ -79,6 +89,11 @@ FakeTransformTransition::~FakeTransformTransition()
|
||||
{
|
||||
}
|
||||
|
||||
double FakeTransformTransition::duration() const
|
||||
{
|
||||
return m_duration;
|
||||
}
|
||||
|
||||
WebKit::WebTransformationMatrix FakeTransformTransition::getValue(double time) const
|
||||
{
|
||||
return WebKit::WebTransformationMatrix();
|
||||
@ -101,6 +116,11 @@ FakeFloatTransition::~FakeFloatTransition()
|
||||
{
|
||||
}
|
||||
|
||||
double FakeFloatTransition::duration() const
|
||||
{
|
||||
return m_duration;
|
||||
}
|
||||
|
||||
float FakeFloatTransition::getValue(double time) const
|
||||
{
|
||||
time /= m_duration;
|
||||
@ -118,6 +138,31 @@ FakeLayerAnimationControllerClient::~FakeLayerAnimationControllerClient()
|
||||
{
|
||||
}
|
||||
|
||||
int FakeLayerAnimationControllerClient::id() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void FakeLayerAnimationControllerClient::setOpacityFromAnimation(float opacity)
|
||||
{
|
||||
m_opacity = opacity;
|
||||
}
|
||||
|
||||
float FakeLayerAnimationControllerClient::opacity() const
|
||||
{
|
||||
return m_opacity;
|
||||
}
|
||||
|
||||
void FakeLayerAnimationControllerClient::setTransformFromAnimation(const WebKit::WebTransformationMatrix& transform)
|
||||
{
|
||||
m_transform = transform;
|
||||
}
|
||||
|
||||
const WebKit::WebTransformationMatrix& FakeLayerAnimationControllerClient::transform() const
|
||||
{
|
||||
return m_transform;
|
||||
}
|
||||
|
||||
PassOwnPtr<WebCore::CCAnimationCurve> FakeFloatTransition::clone() const
|
||||
{
|
||||
return adoptPtr(new FakeFloatTransition(*this));
|
||||
|
@ -24,8 +24,8 @@ public:
|
||||
FakeFloatAnimationCurve();
|
||||
virtual ~FakeFloatAnimationCurve();
|
||||
|
||||
virtual double duration() const OVERRIDE { return 1; }
|
||||
virtual float getValue(double now) const OVERRIDE { return 0; }
|
||||
virtual double duration() const OVERRIDE;
|
||||
virtual float getValue(double now) const OVERRIDE;
|
||||
virtual PassOwnPtr<WebCore::CCAnimationCurve> clone() const OVERRIDE;
|
||||
};
|
||||
|
||||
@ -34,7 +34,7 @@ public:
|
||||
FakeTransformTransition(double duration);
|
||||
virtual ~FakeTransformTransition();
|
||||
|
||||
virtual double duration() const OVERRIDE { return m_duration; }
|
||||
virtual double duration() const OVERRIDE;
|
||||
virtual WebKit::WebTransformationMatrix getValue(double time) const OVERRIDE;
|
||||
|
||||
virtual PassOwnPtr<WebCore::CCAnimationCurve> clone() const OVERRIDE;
|
||||
@ -48,7 +48,7 @@ public:
|
||||
FakeFloatTransition(double duration, float from, float to);
|
||||
virtual ~FakeFloatTransition();
|
||||
|
||||
virtual double duration() const OVERRIDE { return m_duration; }
|
||||
virtual double duration() const OVERRIDE;
|
||||
virtual float getValue(double time) const OVERRIDE;
|
||||
|
||||
virtual PassOwnPtr<WebCore::CCAnimationCurve> clone() const OVERRIDE;
|
||||
@ -65,11 +65,11 @@ public:
|
||||
virtual ~FakeLayerAnimationControllerClient();
|
||||
|
||||
// CCLayerAnimationControllerClient implementation
|
||||
virtual int id() const OVERRIDE { return 0; }
|
||||
virtual void setOpacityFromAnimation(float opacity) OVERRIDE { m_opacity = opacity; }
|
||||
virtual float opacity() const OVERRIDE { return m_opacity; }
|
||||
virtual void setTransformFromAnimation(const WebKit::WebTransformationMatrix& transform) OVERRIDE { m_transform = transform; }
|
||||
virtual const WebKit::WebTransformationMatrix& transform() const OVERRIDE { return m_transform; }
|
||||
virtual int id() const OVERRIDE;
|
||||
virtual void setOpacityFromAnimation(float) OVERRIDE;
|
||||
virtual float opacity() const OVERRIDE;
|
||||
virtual void setTransformFromAnimation(const WebKit::WebTransformationMatrix&) OVERRIDE;
|
||||
virtual const WebKit::WebTransformationMatrix& transform() const OVERRIDE;
|
||||
|
||||
private:
|
||||
float m_opacity;
|
||||
|
@ -65,6 +65,11 @@ PassOwnPtr<LayerTextureUpdater::Texture> FakeLayerTextureUpdater::createTexture(
|
||||
return adoptPtr(new Texture(this, CCPrioritizedTexture::create(manager)));
|
||||
}
|
||||
|
||||
LayerTextureUpdater::SampledTexelFormat FakeLayerTextureUpdater::sampledTexelFormat(GC3Denum)
|
||||
{
|
||||
return SampledTexelFormatRGBA;
|
||||
}
|
||||
|
||||
FakeCCTiledLayerImpl::FakeCCTiledLayerImpl(int id)
|
||||
: CCTiledLayerImpl(id)
|
||||
{
|
||||
@ -85,6 +90,11 @@ FakeTiledLayerChromium::FakeTiledLayerChromium(CCPrioritizedTextureManager* text
|
||||
setIsDrawable(true); // So that we don't get false positives if any of these tests expect to return false from drawsContent() for other reasons.
|
||||
}
|
||||
|
||||
FakeTiledLayerWithScaledBounds::FakeTiledLayerWithScaledBounds(CCPrioritizedTextureManager* textureManager)
|
||||
: FakeTiledLayerChromium(textureManager)
|
||||
{
|
||||
}
|
||||
|
||||
FakeTiledLayerChromium::~FakeTiledLayerChromium()
|
||||
{
|
||||
}
|
||||
@ -112,9 +122,29 @@ void FakeTiledLayerChromium::setTexturePriorities(const CCPriorityCalculator& ca
|
||||
}
|
||||
}
|
||||
|
||||
FakeTiledLayerWithScaledBounds::FakeTiledLayerWithScaledBounds(CCPrioritizedTextureManager* textureManager)
|
||||
: FakeTiledLayerChromium(textureManager)
|
||||
WebCore::CCPrioritizedTextureManager* FakeTiledLayerChromium::textureManager() const
|
||||
{
|
||||
return m_textureManager;
|
||||
}
|
||||
|
||||
WebCore::LayerTextureUpdater* FakeTiledLayerChromium::textureUpdater() const
|
||||
{
|
||||
return m_fakeTextureUpdater.get();
|
||||
}
|
||||
|
||||
WebCore::IntSize FakeTiledLayerWithScaledBounds::contentBounds() const
|
||||
{
|
||||
return m_forcedContentBounds;
|
||||
}
|
||||
|
||||
bool FakeTextureUploader::isBusy()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void FakeTextureUploader::uploadTexture(WebCore::CCResourceProvider* resourceProvider, Parameters upload)
|
||||
{
|
||||
upload.texture->updateRect(resourceProvider, upload.sourceRect, upload.destOffset);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
@ -40,7 +40,7 @@ public:
|
||||
virtual ~FakeLayerTextureUpdater();
|
||||
|
||||
virtual PassOwnPtr<WebCore::LayerTextureUpdater::Texture> createTexture(WebCore::CCPrioritizedTextureManager*) OVERRIDE;
|
||||
virtual SampledTexelFormat sampledTexelFormat(GC3Denum) OVERRIDE { return SampledTexelFormatRGBA; }
|
||||
virtual SampledTexelFormat sampledTexelFormat(GC3Denum) OVERRIDE;
|
||||
|
||||
virtual void prepareToUpdate(const WebCore::IntRect& contentRect, const WebCore::IntSize&, float, float, WebCore::IntRect& resultingOpaqueRect, WebCore::CCRenderingStats&) OVERRIDE;
|
||||
// Sets the rect to invalidate during the next call to prepareToUpdate(). After the next
|
||||
@ -102,12 +102,12 @@ public:
|
||||
|
||||
virtual void setTexturePriorities(const WebCore::CCPriorityCalculator&) OVERRIDE;
|
||||
|
||||
virtual WebCore::CCPrioritizedTextureManager* textureManager() const OVERRIDE { return m_textureManager; }
|
||||
virtual WebCore::CCPrioritizedTextureManager* textureManager() const OVERRIDE;
|
||||
FakeLayerTextureUpdater* fakeLayerTextureUpdater() { return m_fakeTextureUpdater.get(); }
|
||||
WebCore::FloatRect updateRect() { return m_updateRect; }
|
||||
|
||||
protected:
|
||||
virtual WebCore::LayerTextureUpdater* textureUpdater() const OVERRIDE { return m_fakeTextureUpdater.get(); }
|
||||
virtual WebCore::LayerTextureUpdater* textureUpdater() const OVERRIDE;
|
||||
virtual void createTextureUpdaterIfNeeded() OVERRIDE { }
|
||||
|
||||
private:
|
||||
@ -121,7 +121,7 @@ public:
|
||||
explicit FakeTiledLayerWithScaledBounds(WebCore::CCPrioritizedTextureManager*);
|
||||
|
||||
void setContentBounds(const WebCore::IntSize& contentBounds) { m_forcedContentBounds = contentBounds; }
|
||||
virtual WebCore::IntSize contentBounds() const OVERRIDE { return m_forcedContentBounds; }
|
||||
virtual WebCore::IntSize contentBounds() const OVERRIDE;
|
||||
|
||||
protected:
|
||||
WebCore::IntSize m_forcedContentBounds;
|
||||
@ -129,16 +129,16 @@ protected:
|
||||
|
||||
class FakeTextureCopier : public WebCore::TextureCopier {
|
||||
public:
|
||||
virtual void copyTexture(Parameters) { }
|
||||
virtual void flush() { }
|
||||
virtual void copyTexture(Parameters) OVERRIDE { }
|
||||
virtual void flush() OVERRIDE { }
|
||||
};
|
||||
|
||||
class FakeTextureUploader : public WebCore::TextureUploader {
|
||||
public:
|
||||
virtual bool isBusy() { return false; }
|
||||
virtual void beginUploads() { }
|
||||
virtual void endUploads() { }
|
||||
virtual void uploadTexture(WebCore::CCResourceProvider* resourceProvider, Parameters upload) { upload.texture->updateRect(resourceProvider, upload.sourceRect, upload.destOffset); }
|
||||
virtual bool isBusy() OVERRIDE;
|
||||
virtual void beginUploads() OVERRIDE { }
|
||||
virtual void endUploads() OVERRIDE { }
|
||||
virtual void uploadTexture(WebCore::CCResourceProvider*, Parameters upload) OVERRIDE;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -7,6 +7,8 @@
|
||||
|
||||
#include <public/WebCompositorOutputSurface.h>
|
||||
#include <public/WebGraphicsContext3D.h>
|
||||
#include <wtf/OwnPtr.h>
|
||||
#include <wtf/PassOwnPtr.h>
|
||||
|
||||
namespace WebKit {
|
||||
|
||||
|
814
webkit/compositor/LayerChromiumTest.cpp
Normal file
814
webkit/compositor/LayerChromiumTest.cpp
Normal file
@ -0,0 +1,814 @@
|
||||
// Copyright 2011 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "LayerChromium.h"
|
||||
|
||||
#include "CCLayerImpl.h"
|
||||
#include "CCLayerTreeHost.h"
|
||||
#include "CCLayerTreeTestCommon.h"
|
||||
#include "CCSingleThreadProxy.h"
|
||||
#include "FakeCCLayerTreeHostClient.h"
|
||||
#include "LayerPainterChromium.h"
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <public/WebCompositor.h>
|
||||
#include <public/WebTransformationMatrix.h>
|
||||
|
||||
using namespace WebCore;
|
||||
using namespace WebKitTests;
|
||||
using WebKit::WebTransformationMatrix;
|
||||
using ::testing::Mock;
|
||||
using ::testing::_;
|
||||
using ::testing::AtLeast;
|
||||
using ::testing::AnyNumber;
|
||||
|
||||
#define EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(numTimesExpectedSetNeedsCommit, codeToTest) do { \
|
||||
EXPECT_CALL(*m_layerTreeHost, setNeedsCommit()).Times((numTimesExpectedSetNeedsCommit)); \
|
||||
codeToTest; \
|
||||
Mock::VerifyAndClearExpectations(m_layerTreeHost.get()); \
|
||||
} while (0)
|
||||
|
||||
namespace {
|
||||
|
||||
class MockCCLayerTreeHost : public CCLayerTreeHost {
|
||||
public:
|
||||
MockCCLayerTreeHost()
|
||||
: CCLayerTreeHost(&m_fakeClient, CCLayerTreeSettings())
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
|
||||
MOCK_METHOD0(setNeedsCommit, void());
|
||||
|
||||
private:
|
||||
FakeCCLayerTreeHostClient m_fakeClient;
|
||||
};
|
||||
|
||||
class MockLayerPainterChromium : public LayerPainterChromium {
|
||||
public:
|
||||
virtual void paint(SkCanvas*, const IntRect&, FloatRect&) OVERRIDE { }
|
||||
};
|
||||
|
||||
|
||||
class LayerChromiumTest : public testing::Test {
|
||||
protected:
|
||||
virtual void SetUp()
|
||||
{
|
||||
// Initialize without threading support.
|
||||
WebKit::WebCompositor::initialize(0);
|
||||
m_layerTreeHost = adoptPtr(new MockCCLayerTreeHost);
|
||||
}
|
||||
|
||||
virtual void TearDown()
|
||||
{
|
||||
Mock::VerifyAndClearExpectations(m_layerTreeHost.get());
|
||||
EXPECT_CALL(*m_layerTreeHost, setNeedsCommit()).Times(AnyNumber());
|
||||
m_parent.clear();
|
||||
m_child1.clear();
|
||||
m_child2.clear();
|
||||
m_child3.clear();
|
||||
m_grandChild1.clear();
|
||||
m_grandChild2.clear();
|
||||
m_grandChild3.clear();
|
||||
|
||||
m_layerTreeHost->setRootLayer(0);
|
||||
m_layerTreeHost.clear();
|
||||
WebKit::WebCompositor::shutdown();
|
||||
}
|
||||
|
||||
void verifyTestTreeInitialState() const
|
||||
{
|
||||
ASSERT_EQ(static_cast<size_t>(3), m_parent->children().size());
|
||||
EXPECT_EQ(m_child1, m_parent->children()[0]);
|
||||
EXPECT_EQ(m_child2, m_parent->children()[1]);
|
||||
EXPECT_EQ(m_child3, m_parent->children()[2]);
|
||||
EXPECT_EQ(m_parent.get(), m_child1->parent());
|
||||
EXPECT_EQ(m_parent.get(), m_child2->parent());
|
||||
EXPECT_EQ(m_parent.get(), m_child3->parent());
|
||||
|
||||
ASSERT_EQ(static_cast<size_t>(2), m_child1->children().size());
|
||||
EXPECT_EQ(m_grandChild1, m_child1->children()[0]);
|
||||
EXPECT_EQ(m_grandChild2, m_child1->children()[1]);
|
||||
EXPECT_EQ(m_child1.get(), m_grandChild1->parent());
|
||||
EXPECT_EQ(m_child1.get(), m_grandChild2->parent());
|
||||
|
||||
ASSERT_EQ(static_cast<size_t>(1), m_child2->children().size());
|
||||
EXPECT_EQ(m_grandChild3, m_child2->children()[0]);
|
||||
EXPECT_EQ(m_child2.get(), m_grandChild3->parent());
|
||||
|
||||
ASSERT_EQ(static_cast<size_t>(0), m_child3->children().size());
|
||||
}
|
||||
|
||||
void createSimpleTestTree()
|
||||
{
|
||||
m_parent = LayerChromium::create();
|
||||
m_child1 = LayerChromium::create();
|
||||
m_child2 = LayerChromium::create();
|
||||
m_child3 = LayerChromium::create();
|
||||
m_grandChild1 = LayerChromium::create();
|
||||
m_grandChild2 = LayerChromium::create();
|
||||
m_grandChild3 = LayerChromium::create();
|
||||
|
||||
EXPECT_CALL(*m_layerTreeHost, setNeedsCommit()).Times(AnyNumber());
|
||||
m_layerTreeHost->setRootLayer(m_parent);
|
||||
|
||||
m_parent->addChild(m_child1);
|
||||
m_parent->addChild(m_child2);
|
||||
m_parent->addChild(m_child3);
|
||||
m_child1->addChild(m_grandChild1);
|
||||
m_child1->addChild(m_grandChild2);
|
||||
m_child2->addChild(m_grandChild3);
|
||||
|
||||
Mock::VerifyAndClearExpectations(m_layerTreeHost.get());
|
||||
|
||||
verifyTestTreeInitialState();
|
||||
}
|
||||
|
||||
OwnPtr<MockCCLayerTreeHost> m_layerTreeHost;
|
||||
RefPtr<LayerChromium> m_parent, m_child1, m_child2, m_child3, m_grandChild1, m_grandChild2, m_grandChild3;
|
||||
};
|
||||
|
||||
TEST_F(LayerChromiumTest, basicCreateAndDestroy)
|
||||
{
|
||||
RefPtr<LayerChromium> testLayer = LayerChromium::create();
|
||||
ASSERT_TRUE(testLayer);
|
||||
|
||||
EXPECT_CALL(*m_layerTreeHost, setNeedsCommit()).Times(0);
|
||||
testLayer->setLayerTreeHost(m_layerTreeHost.get());
|
||||
}
|
||||
|
||||
TEST_F(LayerChromiumTest, addAndRemoveChild)
|
||||
{
|
||||
RefPtr<LayerChromium> parent = LayerChromium::create();
|
||||
RefPtr<LayerChromium> child = LayerChromium::create();
|
||||
|
||||
// Upon creation, layers should not have children or parent.
|
||||
ASSERT_EQ(static_cast<size_t>(0), parent->children().size());
|
||||
EXPECT_FALSE(child->parent());
|
||||
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, m_layerTreeHost->setRootLayer(parent));
|
||||
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, parent->addChild(child));
|
||||
|
||||
ASSERT_EQ(static_cast<size_t>(1), parent->children().size());
|
||||
EXPECT_EQ(child.get(), parent->children()[0]);
|
||||
EXPECT_EQ(parent.get(), child->parent());
|
||||
EXPECT_EQ(parent.get(), child->rootLayer());
|
||||
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(AtLeast(1), child->removeFromParent());
|
||||
}
|
||||
|
||||
TEST_F(LayerChromiumTest, insertChild)
|
||||
{
|
||||
RefPtr<LayerChromium> parent = LayerChromium::create();
|
||||
RefPtr<LayerChromium> child1 = LayerChromium::create();
|
||||
RefPtr<LayerChromium> child2 = LayerChromium::create();
|
||||
RefPtr<LayerChromium> child3 = LayerChromium::create();
|
||||
RefPtr<LayerChromium> child4 = LayerChromium::create();
|
||||
|
||||
parent->setLayerTreeHost(m_layerTreeHost.get());
|
||||
|
||||
ASSERT_EQ(static_cast<size_t>(0), parent->children().size());
|
||||
|
||||
// Case 1: inserting to empty list.
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, parent->insertChild(child3, 0));
|
||||
ASSERT_EQ(static_cast<size_t>(1), parent->children().size());
|
||||
EXPECT_EQ(child3, parent->children()[0]);
|
||||
EXPECT_EQ(parent.get(), child3->parent());
|
||||
|
||||
// Case 2: inserting to beginning of list
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, parent->insertChild(child1, 0));
|
||||
ASSERT_EQ(static_cast<size_t>(2), parent->children().size());
|
||||
EXPECT_EQ(child1, parent->children()[0]);
|
||||
EXPECT_EQ(child3, parent->children()[1]);
|
||||
EXPECT_EQ(parent.get(), child1->parent());
|
||||
|
||||
// Case 3: inserting to middle of list
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, parent->insertChild(child2, 1));
|
||||
ASSERT_EQ(static_cast<size_t>(3), parent->children().size());
|
||||
EXPECT_EQ(child1, parent->children()[0]);
|
||||
EXPECT_EQ(child2, parent->children()[1]);
|
||||
EXPECT_EQ(child3, parent->children()[2]);
|
||||
EXPECT_EQ(parent.get(), child2->parent());
|
||||
|
||||
// Case 4: inserting to end of list
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, parent->insertChild(child4, 3));
|
||||
|
||||
ASSERT_EQ(static_cast<size_t>(4), parent->children().size());
|
||||
EXPECT_EQ(child1, parent->children()[0]);
|
||||
EXPECT_EQ(child2, parent->children()[1]);
|
||||
EXPECT_EQ(child3, parent->children()[2]);
|
||||
EXPECT_EQ(child4, parent->children()[3]);
|
||||
EXPECT_EQ(parent.get(), child4->parent());
|
||||
|
||||
EXPECT_CALL(*m_layerTreeHost, setNeedsCommit()).Times(AtLeast(1));
|
||||
}
|
||||
|
||||
TEST_F(LayerChromiumTest, insertChildPastEndOfList)
|
||||
{
|
||||
RefPtr<LayerChromium> parent = LayerChromium::create();
|
||||
RefPtr<LayerChromium> child1 = LayerChromium::create();
|
||||
RefPtr<LayerChromium> child2 = LayerChromium::create();
|
||||
|
||||
ASSERT_EQ(static_cast<size_t>(0), parent->children().size());
|
||||
|
||||
// insert to an out-of-bounds index
|
||||
parent->insertChild(child1, 53);
|
||||
|
||||
ASSERT_EQ(static_cast<size_t>(1), parent->children().size());
|
||||
EXPECT_EQ(child1, parent->children()[0]);
|
||||
|
||||
// insert another child to out-of-bounds, when list is not already empty.
|
||||
parent->insertChild(child2, 2459);
|
||||
|
||||
ASSERT_EQ(static_cast<size_t>(2), parent->children().size());
|
||||
EXPECT_EQ(child1, parent->children()[0]);
|
||||
EXPECT_EQ(child2, parent->children()[1]);
|
||||
}
|
||||
|
||||
TEST_F(LayerChromiumTest, insertSameChildTwice)
|
||||
{
|
||||
RefPtr<LayerChromium> parent = LayerChromium::create();
|
||||
RefPtr<LayerChromium> child1 = LayerChromium::create();
|
||||
RefPtr<LayerChromium> child2 = LayerChromium::create();
|
||||
|
||||
parent->setLayerTreeHost(m_layerTreeHost.get());
|
||||
|
||||
ASSERT_EQ(static_cast<size_t>(0), parent->children().size());
|
||||
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, parent->insertChild(child1, 0));
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, parent->insertChild(child2, 1));
|
||||
|
||||
ASSERT_EQ(static_cast<size_t>(2), parent->children().size());
|
||||
EXPECT_EQ(child1, parent->children()[0]);
|
||||
EXPECT_EQ(child2, parent->children()[1]);
|
||||
|
||||
// Inserting the same child again should cause the child to be removed and re-inserted at the new location.
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(AtLeast(1), parent->insertChild(child1, 1));
|
||||
|
||||
// child1 should now be at the end of the list.
|
||||
ASSERT_EQ(static_cast<size_t>(2), parent->children().size());
|
||||
EXPECT_EQ(child2, parent->children()[0]);
|
||||
EXPECT_EQ(child1, parent->children()[1]);
|
||||
|
||||
EXPECT_CALL(*m_layerTreeHost, setNeedsCommit()).Times(AtLeast(1));
|
||||
}
|
||||
|
||||
TEST_F(LayerChromiumTest, replaceChildWithNewChild)
|
||||
{
|
||||
createSimpleTestTree();
|
||||
RefPtr<LayerChromium> child4 = LayerChromium::create();
|
||||
|
||||
EXPECT_FALSE(child4->parent());
|
||||
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(AtLeast(1), m_parent->replaceChild(m_child2.get(), child4));
|
||||
|
||||
ASSERT_EQ(static_cast<size_t>(3), m_parent->children().size());
|
||||
EXPECT_EQ(m_child1, m_parent->children()[0]);
|
||||
EXPECT_EQ(child4, m_parent->children()[1]);
|
||||
EXPECT_EQ(m_child3, m_parent->children()[2]);
|
||||
EXPECT_EQ(m_parent.get(), child4->parent());
|
||||
|
||||
EXPECT_FALSE(m_child2->parent());
|
||||
}
|
||||
|
||||
TEST_F(LayerChromiumTest, replaceChildWithNewChildThatHasOtherParent)
|
||||
{
|
||||
createSimpleTestTree();
|
||||
|
||||
// create another simple tree with testLayer and child4.
|
||||
RefPtr<LayerChromium> testLayer = LayerChromium::create();
|
||||
RefPtr<LayerChromium> child4 = LayerChromium::create();
|
||||
testLayer->addChild(child4);
|
||||
ASSERT_EQ(static_cast<size_t>(1), testLayer->children().size());
|
||||
EXPECT_EQ(child4, testLayer->children()[0]);
|
||||
EXPECT_EQ(testLayer.get(), child4->parent());
|
||||
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(AtLeast(1), m_parent->replaceChild(m_child2.get(), child4));
|
||||
|
||||
ASSERT_EQ(static_cast<size_t>(3), m_parent->children().size());
|
||||
EXPECT_EQ(m_child1, m_parent->children()[0]);
|
||||
EXPECT_EQ(child4, m_parent->children()[1]);
|
||||
EXPECT_EQ(m_child3, m_parent->children()[2]);
|
||||
EXPECT_EQ(m_parent.get(), child4->parent());
|
||||
|
||||
// testLayer should no longer have child4,
|
||||
// and child2 should no longer have a parent.
|
||||
ASSERT_EQ(static_cast<size_t>(0), testLayer->children().size());
|
||||
EXPECT_FALSE(m_child2->parent());
|
||||
}
|
||||
|
||||
TEST_F(LayerChromiumTest, replaceChildWithSameChild)
|
||||
{
|
||||
createSimpleTestTree();
|
||||
|
||||
// setNeedsCommit should not be called because its the same child
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(0, m_parent->replaceChild(m_child2.get(), m_child2));
|
||||
|
||||
verifyTestTreeInitialState();
|
||||
}
|
||||
|
||||
TEST_F(LayerChromiumTest, removeAllChildren)
|
||||
{
|
||||
createSimpleTestTree();
|
||||
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(AtLeast(3), m_parent->removeAllChildren());
|
||||
|
||||
ASSERT_EQ(static_cast<size_t>(0), m_parent->children().size());
|
||||
EXPECT_FALSE(m_child1->parent());
|
||||
EXPECT_FALSE(m_child2->parent());
|
||||
EXPECT_FALSE(m_child3->parent());
|
||||
}
|
||||
|
||||
TEST_F(LayerChromiumTest, setChildren)
|
||||
{
|
||||
RefPtr<LayerChromium> oldParent = LayerChromium::create();
|
||||
RefPtr<LayerChromium> newParent = LayerChromium::create();
|
||||
|
||||
RefPtr<LayerChromium> child1 = LayerChromium::create();
|
||||
RefPtr<LayerChromium> child2 = LayerChromium::create();
|
||||
|
||||
Vector<RefPtr<LayerChromium> > newChildren;
|
||||
newChildren.append(child1);
|
||||
newChildren.append(child2);
|
||||
|
||||
// Set up and verify initial test conditions: child1 has a parent, child2 has no parent.
|
||||
oldParent->addChild(child1);
|
||||
ASSERT_EQ(static_cast<size_t>(0), newParent->children().size());
|
||||
EXPECT_EQ(oldParent.get(), child1->parent());
|
||||
EXPECT_FALSE(child2->parent());
|
||||
|
||||
newParent->setLayerTreeHost(m_layerTreeHost.get());
|
||||
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(AtLeast(1), newParent->setChildren(newChildren));
|
||||
|
||||
ASSERT_EQ(static_cast<size_t>(2), newParent->children().size());
|
||||
EXPECT_EQ(newParent.get(), child1->parent());
|
||||
EXPECT_EQ(newParent.get(), child2->parent());
|
||||
|
||||
EXPECT_CALL(*m_layerTreeHost, setNeedsCommit()).Times(AtLeast(1));
|
||||
}
|
||||
|
||||
TEST_F(LayerChromiumTest, getRootLayerAfterTreeManipulations)
|
||||
{
|
||||
createSimpleTestTree();
|
||||
|
||||
// For this test we don't care about setNeedsCommit calls.
|
||||
EXPECT_CALL(*m_layerTreeHost, setNeedsCommit()).Times(AtLeast(1));
|
||||
|
||||
RefPtr<LayerChromium> child4 = LayerChromium::create();
|
||||
|
||||
EXPECT_EQ(m_parent.get(), m_parent->rootLayer());
|
||||
EXPECT_EQ(m_parent.get(), m_child1->rootLayer());
|
||||
EXPECT_EQ(m_parent.get(), m_child2->rootLayer());
|
||||
EXPECT_EQ(m_parent.get(), m_child3->rootLayer());
|
||||
EXPECT_EQ(child4.get(), child4->rootLayer());
|
||||
EXPECT_EQ(m_parent.get(), m_grandChild1->rootLayer());
|
||||
EXPECT_EQ(m_parent.get(), m_grandChild2->rootLayer());
|
||||
EXPECT_EQ(m_parent.get(), m_grandChild3->rootLayer());
|
||||
|
||||
m_child1->removeFromParent();
|
||||
|
||||
// child1 and its children, grandChild1 and grandChild2 are now on a separate subtree.
|
||||
EXPECT_EQ(m_parent.get(), m_parent->rootLayer());
|
||||
EXPECT_EQ(m_child1.get(), m_child1->rootLayer());
|
||||
EXPECT_EQ(m_parent.get(), m_child2->rootLayer());
|
||||
EXPECT_EQ(m_parent.get(), m_child3->rootLayer());
|
||||
EXPECT_EQ(child4.get(), child4->rootLayer());
|
||||
EXPECT_EQ(m_child1.get(), m_grandChild1->rootLayer());
|
||||
EXPECT_EQ(m_child1.get(), m_grandChild2->rootLayer());
|
||||
EXPECT_EQ(m_parent.get(), m_grandChild3->rootLayer());
|
||||
|
||||
m_grandChild3->addChild(child4);
|
||||
|
||||
EXPECT_EQ(m_parent.get(), m_parent->rootLayer());
|
||||
EXPECT_EQ(m_child1.get(), m_child1->rootLayer());
|
||||
EXPECT_EQ(m_parent.get(), m_child2->rootLayer());
|
||||
EXPECT_EQ(m_parent.get(), m_child3->rootLayer());
|
||||
EXPECT_EQ(m_parent.get(), child4->rootLayer());
|
||||
EXPECT_EQ(m_child1.get(), m_grandChild1->rootLayer());
|
||||
EXPECT_EQ(m_child1.get(), m_grandChild2->rootLayer());
|
||||
EXPECT_EQ(m_parent.get(), m_grandChild3->rootLayer());
|
||||
|
||||
m_child2->replaceChild(m_grandChild3.get(), m_child1);
|
||||
|
||||
// grandChild3 gets orphaned and the child1 subtree gets planted back into the tree under child2.
|
||||
EXPECT_EQ(m_parent.get(), m_parent->rootLayer());
|
||||
EXPECT_EQ(m_parent.get(), m_child1->rootLayer());
|
||||
EXPECT_EQ(m_parent.get(), m_child2->rootLayer());
|
||||
EXPECT_EQ(m_parent.get(), m_child3->rootLayer());
|
||||
EXPECT_EQ(m_grandChild3.get(), child4->rootLayer());
|
||||
EXPECT_EQ(m_parent.get(), m_grandChild1->rootLayer());
|
||||
EXPECT_EQ(m_parent.get(), m_grandChild2->rootLayer());
|
||||
EXPECT_EQ(m_grandChild3.get(), m_grandChild3->rootLayer());
|
||||
}
|
||||
|
||||
TEST_F(LayerChromiumTest, checkSetNeedsDisplayCausesCorrectBehavior)
|
||||
{
|
||||
// The semantics for setNeedsDisplay which are tested here:
|
||||
// 1. sets needsDisplay flag appropriately.
|
||||
// 2. indirectly calls setNeedsCommit, exactly once for each call to setNeedsDisplay.
|
||||
|
||||
RefPtr<LayerChromium> testLayer = LayerChromium::create();
|
||||
testLayer->setLayerTreeHost(m_layerTreeHost.get());
|
||||
|
||||
IntSize testBounds = IntSize(501, 508);
|
||||
|
||||
FloatRect dirty1 = FloatRect(10, 15, 1, 2);
|
||||
FloatRect dirty2 = FloatRect(20, 25, 3, 4);
|
||||
FloatRect emptyDirtyRect = FloatRect(40, 45, 0, 0);
|
||||
FloatRect outOfBoundsDirtyRect = FloatRect(400, 405, 500, 502);
|
||||
|
||||
// Before anything, testLayer should not be dirty.
|
||||
EXPECT_FALSE(testLayer->needsDisplay());
|
||||
|
||||
// This is just initialization, but setNeedsCommit behavior is verified anyway to avoid warnings.
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setBounds(testBounds));
|
||||
testLayer = LayerChromium::create();
|
||||
testLayer->setLayerTreeHost(m_layerTreeHost.get());
|
||||
EXPECT_FALSE(testLayer->needsDisplay());
|
||||
|
||||
// The real test begins here.
|
||||
|
||||
// Case 1: needsDisplay flag should not change because of an empty dirty rect.
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setNeedsDisplayRect(emptyDirtyRect));
|
||||
EXPECT_FALSE(testLayer->needsDisplay());
|
||||
|
||||
// Case 2: basic.
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setNeedsDisplayRect(dirty1));
|
||||
EXPECT_TRUE(testLayer->needsDisplay());
|
||||
|
||||
// Case 3: a second dirty rect.
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setNeedsDisplayRect(dirty2));
|
||||
EXPECT_TRUE(testLayer->needsDisplay());
|
||||
|
||||
// Case 4: LayerChromium should accept dirty rects that go beyond its bounds.
|
||||
testLayer = LayerChromium::create();
|
||||
testLayer->setLayerTreeHost(m_layerTreeHost.get());
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setBounds(testBounds));
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setNeedsDisplayRect(outOfBoundsDirtyRect));
|
||||
EXPECT_TRUE(testLayer->needsDisplay());
|
||||
|
||||
// Case 5: setNeedsDisplay() without the dirty rect arg.
|
||||
testLayer = LayerChromium::create();
|
||||
testLayer->setLayerTreeHost(m_layerTreeHost.get());
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setBounds(testBounds));
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setNeedsDisplay());
|
||||
EXPECT_TRUE(testLayer->needsDisplay());
|
||||
}
|
||||
|
||||
TEST_F(LayerChromiumTest, checkPropertyChangeCausesCorrectBehavior)
|
||||
{
|
||||
RefPtr<LayerChromium> testLayer = LayerChromium::create();
|
||||
testLayer->setLayerTreeHost(m_layerTreeHost.get());
|
||||
|
||||
RefPtr<LayerChromium> dummyLayer = LayerChromium::create(); // just a dummy layer for this test case.
|
||||
|
||||
// sanity check of initial test condition
|
||||
EXPECT_FALSE(testLayer->needsDisplay());
|
||||
|
||||
// Test properties that should not call needsDisplay and needsCommit when changed.
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(0, testLayer->setVisibleContentRect(IntRect(0, 0, 40, 50)));
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(0, testLayer->setUseLCDText(true));
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(0, testLayer->setDrawOpacity(0.5));
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(0, testLayer->setRenderTarget(0));
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(0, testLayer->setDrawTransform(WebTransformationMatrix()));
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(0, testLayer->setScreenSpaceTransform(WebTransformationMatrix()));
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(0, testLayer->setDrawableContentRect(IntRect(4, 5, 6, 7)));
|
||||
EXPECT_FALSE(testLayer->needsDisplay());
|
||||
|
||||
// Next, test properties that should call setNeedsCommit (but not setNeedsDisplay)
|
||||
// All properties need to be set to new values in order for setNeedsCommit to be called.
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setAnchorPoint(FloatPoint(1.23f, 4.56f)));
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setAnchorPointZ(0.7f));
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setBackgroundColor(SK_ColorLTGRAY));
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setMasksToBounds(true));
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setMaskLayer(dummyLayer.get()));
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setOpacity(0.5));
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setOpaque(true));
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setPosition(FloatPoint(4, 9)));
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setReplicaLayer(dummyLayer.get()));
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setSublayerTransform(WebTransformationMatrix(0, 0, 0, 0, 0, 0)));
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setScrollable(true));
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setShouldScrollOnMainThread(true));
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setNonFastScrollableRegion(Region(IntRect(1, 1, 2, 2))));
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setHaveWheelEventHandlers(true));
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setScrollPosition(IntPoint(10, 10)));
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setTransform(WebTransformationMatrix(0, 0, 0, 0, 0, 0)));
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setDoubleSided(false));
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setDebugName("Test Layer"));
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setDrawCheckerboardForMissingTiles(!testLayer->drawCheckerboardForMissingTiles()));
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setForceRenderSurface(true));
|
||||
|
||||
// The above tests should not have caused a change to the needsDisplay flag.
|
||||
EXPECT_FALSE(testLayer->needsDisplay());
|
||||
|
||||
// Test properties that should call setNeedsDisplay and setNeedsCommit
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setBounds(IntSize(5, 10)));
|
||||
EXPECT_TRUE(testLayer->needsDisplay());
|
||||
}
|
||||
|
||||
TEST_F(LayerChromiumTest, verifyPushPropertiesAccumulatesUpdateRect)
|
||||
{
|
||||
DebugScopedSetImplThread setImplThread;
|
||||
|
||||
RefPtr<LayerChromium> testLayer = LayerChromium::create();
|
||||
OwnPtr<CCLayerImpl> implLayer = CCLayerImpl::create(1);
|
||||
|
||||
testLayer->setNeedsDisplayRect(FloatRect(FloatPoint::zero(), FloatSize(5, 5)));
|
||||
testLayer->pushPropertiesTo(implLayer.get());
|
||||
EXPECT_FLOAT_RECT_EQ(FloatRect(FloatPoint::zero(), FloatSize(5, 5)), implLayer->updateRect());
|
||||
|
||||
// The CCLayerImpl's updateRect should be accumulated here, since we did not do anything to clear it.
|
||||
testLayer->setNeedsDisplayRect(FloatRect(FloatPoint(10, 10), FloatSize(5, 5)));
|
||||
testLayer->pushPropertiesTo(implLayer.get());
|
||||
EXPECT_FLOAT_RECT_EQ(FloatRect(FloatPoint::zero(), FloatSize(15, 15)), implLayer->updateRect());
|
||||
|
||||
// If we do clear the CCLayerImpl side, then the next updateRect should be fresh without accumulation.
|
||||
implLayer->resetAllChangeTrackingForSubtree();
|
||||
testLayer->setNeedsDisplayRect(FloatRect(FloatPoint(10, 10), FloatSize(5, 5)));
|
||||
testLayer->pushPropertiesTo(implLayer.get());
|
||||
EXPECT_FLOAT_RECT_EQ(FloatRect(FloatPoint(10, 10), FloatSize(5, 5)), implLayer->updateRect());
|
||||
}
|
||||
|
||||
class LayerChromiumWithContentScaling : public LayerChromium {
|
||||
public:
|
||||
explicit LayerChromiumWithContentScaling()
|
||||
: LayerChromium()
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool needsContentsScale() const OVERRIDE
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void setNeedsDisplayRect(const FloatRect& dirtyRect) OVERRIDE
|
||||
{
|
||||
m_lastNeedsDisplayRect = dirtyRect;
|
||||
LayerChromium::setNeedsDisplayRect(dirtyRect);
|
||||
}
|
||||
|
||||
void resetNeedsDisplay()
|
||||
{
|
||||
m_needsDisplay = false;
|
||||
}
|
||||
|
||||
const FloatRect& lastNeedsDisplayRect() const { return m_lastNeedsDisplayRect; }
|
||||
|
||||
private:
|
||||
FloatRect m_lastNeedsDisplayRect;
|
||||
};
|
||||
|
||||
TEST_F(LayerChromiumTest, checkContentsScaleChangeTriggersNeedsDisplay)
|
||||
{
|
||||
RefPtr<LayerChromiumWithContentScaling> testLayer = adoptRef(new LayerChromiumWithContentScaling());
|
||||
testLayer->setLayerTreeHost(m_layerTreeHost.get());
|
||||
|
||||
IntSize testBounds = IntSize(320, 240);
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setBounds(testBounds));
|
||||
|
||||
testLayer->resetNeedsDisplay();
|
||||
EXPECT_FALSE(testLayer->needsDisplay());
|
||||
|
||||
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setContentsScale(testLayer->contentsScale() + 1.f));
|
||||
EXPECT_TRUE(testLayer->needsDisplay());
|
||||
EXPECT_FLOAT_RECT_EQ(FloatRect(0, 0, 320, 240), testLayer->lastNeedsDisplayRect());
|
||||
}
|
||||
|
||||
class FakeCCLayerTreeHost : public CCLayerTreeHost {
|
||||
public:
|
||||
static PassOwnPtr<FakeCCLayerTreeHost> create()
|
||||
{
|
||||
OwnPtr<FakeCCLayerTreeHost> host(adoptPtr(new FakeCCLayerTreeHost));
|
||||
// The initialize call will fail, since our client doesn't provide a valid GraphicsContext3D, but it doesn't matter in the tests that use this fake so ignore the return value.
|
||||
host->initialize();
|
||||
return host.release();
|
||||
}
|
||||
|
||||
private:
|
||||
FakeCCLayerTreeHost()
|
||||
: CCLayerTreeHost(&m_client, CCLayerTreeSettings())
|
||||
{
|
||||
}
|
||||
|
||||
FakeCCLayerTreeHostClient m_client;
|
||||
};
|
||||
|
||||
void assertLayerTreeHostMatchesForSubtree(LayerChromium* layer, CCLayerTreeHost* host)
|
||||
{
|
||||
EXPECT_EQ(host, layer->layerTreeHost());
|
||||
|
||||
for (size_t i = 0; i < layer->children().size(); ++i)
|
||||
assertLayerTreeHostMatchesForSubtree(layer->children()[i].get(), host);
|
||||
|
||||
if (layer->maskLayer())
|
||||
assertLayerTreeHostMatchesForSubtree(layer->maskLayer(), host);
|
||||
|
||||
if (layer->replicaLayer())
|
||||
assertLayerTreeHostMatchesForSubtree(layer->replicaLayer(), host);
|
||||
}
|
||||
|
||||
|
||||
TEST(LayerChromiumLayerTreeHostTest, enteringTree)
|
||||
{
|
||||
WebKit::WebCompositor::initialize(0);
|
||||
RefPtr<LayerChromium> parent = LayerChromium::create();
|
||||
RefPtr<LayerChromium> child = LayerChromium::create();
|
||||
RefPtr<LayerChromium> mask = LayerChromium::create();
|
||||
RefPtr<LayerChromium> replica = LayerChromium::create();
|
||||
RefPtr<LayerChromium> replicaMask = LayerChromium::create();
|
||||
|
||||
// Set up a detached tree of layers. The host pointer should be nil for these layers.
|
||||
parent->addChild(child);
|
||||
child->setMaskLayer(mask.get());
|
||||
child->setReplicaLayer(replica.get());
|
||||
replica->setMaskLayer(mask.get());
|
||||
|
||||
assertLayerTreeHostMatchesForSubtree(parent.get(), 0);
|
||||
|
||||
OwnPtr<FakeCCLayerTreeHost> layerTreeHost(FakeCCLayerTreeHost::create());
|
||||
// Setting the root layer should set the host pointer for all layers in the tree.
|
||||
layerTreeHost->setRootLayer(parent.get());
|
||||
|
||||
assertLayerTreeHostMatchesForSubtree(parent.get(), layerTreeHost.get());
|
||||
|
||||
// Clearing the root layer should also clear out the host pointers for all layers in the tree.
|
||||
layerTreeHost->setRootLayer(0);
|
||||
|
||||
assertLayerTreeHostMatchesForSubtree(parent.get(), 0);
|
||||
|
||||
layerTreeHost.clear();
|
||||
WebKit::WebCompositor::shutdown();
|
||||
}
|
||||
|
||||
TEST(LayerChromiumLayerTreeHostTest, addingLayerSubtree)
|
||||
{
|
||||
WebKit::WebCompositor::initialize(0);
|
||||
RefPtr<LayerChromium> parent = LayerChromium::create();
|
||||
OwnPtr<FakeCCLayerTreeHost> layerTreeHost(FakeCCLayerTreeHost::create());
|
||||
|
||||
layerTreeHost->setRootLayer(parent.get());
|
||||
|
||||
EXPECT_EQ(parent->layerTreeHost(), layerTreeHost.get());
|
||||
|
||||
// Adding a subtree to a layer already associated with a host should set the host pointer on all layers in that subtree.
|
||||
RefPtr<LayerChromium> child = LayerChromium::create();
|
||||
RefPtr<LayerChromium> grandChild = LayerChromium::create();
|
||||
child->addChild(grandChild);
|
||||
|
||||
// Masks, replicas, and replica masks should pick up the new host too.
|
||||
RefPtr<LayerChromium> childMask = LayerChromium::create();
|
||||
child->setMaskLayer(childMask.get());
|
||||
RefPtr<LayerChromium> childReplica = LayerChromium::create();
|
||||
child->setReplicaLayer(childReplica.get());
|
||||
RefPtr<LayerChromium> childReplicaMask = LayerChromium::create();
|
||||
childReplica->setMaskLayer(childReplicaMask.get());
|
||||
|
||||
parent->addChild(child);
|
||||
assertLayerTreeHostMatchesForSubtree(parent.get(), layerTreeHost.get());
|
||||
|
||||
layerTreeHost->setRootLayer(0);
|
||||
layerTreeHost.clear();
|
||||
WebKit::WebCompositor::shutdown();
|
||||
}
|
||||
|
||||
TEST(LayerChromiumLayerTreeHostTest, changeHost)
|
||||
{
|
||||
WebKit::WebCompositor::initialize(0);
|
||||
RefPtr<LayerChromium> parent = LayerChromium::create();
|
||||
RefPtr<LayerChromium> child = LayerChromium::create();
|
||||
RefPtr<LayerChromium> mask = LayerChromium::create();
|
||||
RefPtr<LayerChromium> replica = LayerChromium::create();
|
||||
RefPtr<LayerChromium> replicaMask = LayerChromium::create();
|
||||
|
||||
// Same setup as the previous test.
|
||||
parent->addChild(child);
|
||||
child->setMaskLayer(mask.get());
|
||||
child->setReplicaLayer(replica.get());
|
||||
replica->setMaskLayer(mask.get());
|
||||
|
||||
OwnPtr<FakeCCLayerTreeHost> firstLayerTreeHost(FakeCCLayerTreeHost::create());
|
||||
firstLayerTreeHost->setRootLayer(parent.get());
|
||||
|
||||
assertLayerTreeHostMatchesForSubtree(parent.get(), firstLayerTreeHost.get());
|
||||
|
||||
// Now re-root the tree to a new host (simulating what we do on a context lost event).
|
||||
// This should update the host pointers for all layers in the tree.
|
||||
OwnPtr<FakeCCLayerTreeHost> secondLayerTreeHost(FakeCCLayerTreeHost::create());
|
||||
secondLayerTreeHost->setRootLayer(parent.get());
|
||||
|
||||
assertLayerTreeHostMatchesForSubtree(parent.get(), secondLayerTreeHost.get());
|
||||
|
||||
secondLayerTreeHost->setRootLayer(0);
|
||||
firstLayerTreeHost.clear();
|
||||
secondLayerTreeHost.clear();
|
||||
WebKit::WebCompositor::shutdown();
|
||||
}
|
||||
|
||||
TEST(LayerChromiumLayerTreeHostTest, changeHostInSubtree)
|
||||
{
|
||||
WebKit::WebCompositor::initialize(0);
|
||||
RefPtr<LayerChromium> firstParent = LayerChromium::create();
|
||||
RefPtr<LayerChromium> firstChild = LayerChromium::create();
|
||||
RefPtr<LayerChromium> secondParent = LayerChromium::create();
|
||||
RefPtr<LayerChromium> secondChild = LayerChromium::create();
|
||||
RefPtr<LayerChromium> secondGrandChild = LayerChromium::create();
|
||||
|
||||
// First put all children under the first parent and set the first host.
|
||||
firstParent->addChild(firstChild);
|
||||
secondChild->addChild(secondGrandChild);
|
||||
firstParent->addChild(secondChild);
|
||||
|
||||
OwnPtr<FakeCCLayerTreeHost> firstLayerTreeHost(FakeCCLayerTreeHost::create());
|
||||
firstLayerTreeHost->setRootLayer(firstParent.get());
|
||||
|
||||
assertLayerTreeHostMatchesForSubtree(firstParent.get(), firstLayerTreeHost.get());
|
||||
|
||||
// Now reparent the subtree starting at secondChild to a layer in a different tree.
|
||||
OwnPtr<FakeCCLayerTreeHost> secondLayerTreeHost(FakeCCLayerTreeHost::create());
|
||||
secondLayerTreeHost->setRootLayer(secondParent.get());
|
||||
|
||||
secondParent->addChild(secondChild);
|
||||
|
||||
// The moved layer and its children should point to the new host.
|
||||
EXPECT_EQ(secondLayerTreeHost.get(), secondChild->layerTreeHost());
|
||||
EXPECT_EQ(secondLayerTreeHost.get(), secondGrandChild->layerTreeHost());
|
||||
|
||||
// Test over, cleanup time.
|
||||
firstLayerTreeHost->setRootLayer(0);
|
||||
secondLayerTreeHost->setRootLayer(0);
|
||||
firstLayerTreeHost.clear();
|
||||
secondLayerTreeHost.clear();
|
||||
WebKit::WebCompositor::shutdown();
|
||||
}
|
||||
|
||||
TEST(LayerChromiumLayerTreeHostTest, replaceMaskAndReplicaLayer)
|
||||
{
|
||||
WebKit::WebCompositor::initialize(0);
|
||||
RefPtr<LayerChromium> parent = LayerChromium::create();
|
||||
RefPtr<LayerChromium> mask = LayerChromium::create();
|
||||
RefPtr<LayerChromium> replica = LayerChromium::create();
|
||||
RefPtr<LayerChromium> maskChild = LayerChromium::create();
|
||||
RefPtr<LayerChromium> replicaChild = LayerChromium::create();
|
||||
RefPtr<LayerChromium> maskReplacement = LayerChromium::create();
|
||||
RefPtr<LayerChromium> replicaReplacement = LayerChromium::create();
|
||||
|
||||
parent->setMaskLayer(mask.get());
|
||||
parent->setReplicaLayer(replica.get());
|
||||
mask->addChild(maskChild);
|
||||
replica->addChild(replicaChild);
|
||||
|
||||
OwnPtr<FakeCCLayerTreeHost> layerTreeHost(FakeCCLayerTreeHost::create());
|
||||
layerTreeHost->setRootLayer(parent.get());
|
||||
|
||||
assertLayerTreeHostMatchesForSubtree(parent.get(), layerTreeHost.get());
|
||||
|
||||
// Replacing the mask should clear out the old mask's subtree's host pointers.
|
||||
parent->setMaskLayer(maskReplacement.get());
|
||||
EXPECT_EQ(0, mask->layerTreeHost());
|
||||
EXPECT_EQ(0, maskChild->layerTreeHost());
|
||||
|
||||
// Same for replacing a replica layer.
|
||||
parent->setReplicaLayer(replicaReplacement.get());
|
||||
EXPECT_EQ(0, replica->layerTreeHost());
|
||||
EXPECT_EQ(0, replicaChild->layerTreeHost());
|
||||
|
||||
// Test over, cleanup time.
|
||||
layerTreeHost->setRootLayer(0);
|
||||
layerTreeHost.clear();
|
||||
WebKit::WebCompositor::shutdown();
|
||||
}
|
||||
|
||||
TEST(LayerChromiumLayerTreeHostTest, destroyHostWithNonNullRootLayer)
|
||||
{
|
||||
WebKit::WebCompositor::initialize(0);
|
||||
RefPtr<LayerChromium> root = LayerChromium::create();
|
||||
RefPtr<LayerChromium> child = LayerChromium::create();
|
||||
root->addChild(child);
|
||||
OwnPtr<FakeCCLayerTreeHost> layerTreeHost(FakeCCLayerTreeHost::create());
|
||||
layerTreeHost->setRootLayer(root);
|
||||
layerTreeHost.clear();
|
||||
WebKit::WebCompositor::shutdown();
|
||||
}
|
||||
|
||||
class MockLayerChromium : public LayerChromium {
|
||||
public:
|
||||
bool needsDisplay() const { return m_needsDisplay; }
|
||||
};
|
||||
|
||||
TEST(LayerChromiumTestWithoutFixture, setBoundsTriggersSetNeedsRedrawAfterGettingNonEmptyBounds)
|
||||
{
|
||||
RefPtr<MockLayerChromium> layer(adoptRef(new MockLayerChromium));
|
||||
EXPECT_FALSE(layer->needsDisplay());
|
||||
layer->setBounds(IntSize(0, 10));
|
||||
EXPECT_FALSE(layer->needsDisplay());
|
||||
layer->setBounds(IntSize(10, 10));
|
||||
EXPECT_TRUE(layer->needsDisplay());
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
59
webkit/compositor/TextureCopierTest.cpp
Normal file
59
webkit/compositor/TextureCopierTest.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
// Copyright 2011 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "TextureCopier.h"
|
||||
|
||||
#include "FakeWebGraphicsContext3D.h"
|
||||
#include "GraphicsContext3D.h"
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <wtf/RefPtr.h>
|
||||
|
||||
using namespace WebCore;
|
||||
using namespace WebKit;
|
||||
using testing::InSequence;
|
||||
using testing::Test;
|
||||
using testing::_;
|
||||
|
||||
class MockContext : public FakeWebGraphicsContext3D {
|
||||
public:
|
||||
MOCK_METHOD2(bindFramebuffer, void(WGC3Denum, WebGLId));
|
||||
MOCK_METHOD3(texParameteri, void(WGC3Denum target, WGC3Denum pname, WGC3Dint param));
|
||||
|
||||
MOCK_METHOD3(drawArrays, void(WGC3Denum mode, WGC3Dint first, WGC3Dsizei count));
|
||||
};
|
||||
|
||||
TEST(TextureCopierTest, testDrawArraysCopy)
|
||||
{
|
||||
OwnPtr<MockContext> mockContext = adoptPtr(new MockContext);
|
||||
|
||||
{
|
||||
InSequence sequence;
|
||||
|
||||
// Here we check just some essential properties of copyTexture() to avoid mirroring the full implementation.
|
||||
EXPECT_CALL(*mockContext, bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, _));
|
||||
|
||||
// Make sure linear filtering is disabled during the copy.
|
||||
EXPECT_CALL(*mockContext, texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::NEAREST));
|
||||
EXPECT_CALL(*mockContext, texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::NEAREST));
|
||||
|
||||
EXPECT_CALL(*mockContext, drawArrays(_, _, _));
|
||||
|
||||
// Linear filtering should be restored.
|
||||
EXPECT_CALL(*mockContext, texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR));
|
||||
EXPECT_CALL(*mockContext, texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR));
|
||||
|
||||
// Default framebuffer should be restored
|
||||
EXPECT_CALL(*mockContext, bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0));
|
||||
}
|
||||
|
||||
int sourceTextureId = 1;
|
||||
int destTextureId = 2;
|
||||
IntSize size(256, 128);
|
||||
OwnPtr<AcceleratedTextureCopier> copier(AcceleratedTextureCopier::create(mockContext.get(), false));
|
||||
TextureCopier::Parameters copy = { sourceTextureId, destTextureId, size };
|
||||
copier->copyTexture(copy);
|
||||
}
|
116
webkit/compositor/TextureLayerChromiumTest.cpp
Normal file
116
webkit/compositor/TextureLayerChromiumTest.cpp
Normal file
@ -0,0 +1,116 @@
|
||||
// Copyright 2012 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "TextureLayerChromium.h"
|
||||
|
||||
#include "CCLayerTreeHost.h"
|
||||
#include "FakeCCLayerTreeHostClient.h"
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <public/WebCompositor.h>
|
||||
|
||||
using namespace WebCore;
|
||||
using ::testing::Mock;
|
||||
using ::testing::_;
|
||||
using ::testing::AtLeast;
|
||||
using ::testing::AnyNumber;
|
||||
|
||||
namespace {
|
||||
|
||||
class MockCCLayerTreeHost : public CCLayerTreeHost {
|
||||
public:
|
||||
MockCCLayerTreeHost()
|
||||
: CCLayerTreeHost(&m_fakeClient, CCLayerTreeSettings())
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
|
||||
MOCK_METHOD0(acquireLayerTextures, void());
|
||||
|
||||
private:
|
||||
FakeCCLayerTreeHostClient m_fakeClient;
|
||||
};
|
||||
|
||||
|
||||
class TextureLayerChromiumTest : public testing::Test {
|
||||
protected:
|
||||
virtual void SetUp()
|
||||
{
|
||||
// Initialize without threading support.
|
||||
WebKit::WebCompositor::initialize(0);
|
||||
m_layerTreeHost = adoptPtr(new MockCCLayerTreeHost);
|
||||
}
|
||||
|
||||
virtual void TearDown()
|
||||
{
|
||||
Mock::VerifyAndClearExpectations(m_layerTreeHost.get());
|
||||
EXPECT_CALL(*m_layerTreeHost, acquireLayerTextures()).Times(AnyNumber());
|
||||
|
||||
m_layerTreeHost->setRootLayer(0);
|
||||
m_layerTreeHost.clear();
|
||||
WebKit::WebCompositor::shutdown();
|
||||
}
|
||||
|
||||
OwnPtr<MockCCLayerTreeHost> m_layerTreeHost;
|
||||
};
|
||||
|
||||
TEST_F(TextureLayerChromiumTest, syncImplWhenChangingTextureId)
|
||||
{
|
||||
RefPtr<TextureLayerChromium> testLayer = TextureLayerChromium::create(0);
|
||||
ASSERT_TRUE(testLayer);
|
||||
|
||||
EXPECT_CALL(*m_layerTreeHost, acquireLayerTextures()).Times(AnyNumber());
|
||||
m_layerTreeHost->setRootLayer(testLayer);
|
||||
Mock::VerifyAndClearExpectations(m_layerTreeHost.get());
|
||||
EXPECT_EQ(testLayer->layerTreeHost(), m_layerTreeHost.get());
|
||||
|
||||
EXPECT_CALL(*m_layerTreeHost, acquireLayerTextures()).Times(0);
|
||||
testLayer->setTextureId(1);
|
||||
Mock::VerifyAndClearExpectations(m_layerTreeHost.get());
|
||||
|
||||
EXPECT_CALL(*m_layerTreeHost, acquireLayerTextures()).Times(AtLeast(1));
|
||||
testLayer->setTextureId(2);
|
||||
Mock::VerifyAndClearExpectations(m_layerTreeHost.get());
|
||||
|
||||
EXPECT_CALL(*m_layerTreeHost, acquireLayerTextures()).Times(AtLeast(1));
|
||||
testLayer->setTextureId(0);
|
||||
Mock::VerifyAndClearExpectations(m_layerTreeHost.get());
|
||||
}
|
||||
|
||||
TEST_F(TextureLayerChromiumTest, syncImplWhenRemovingFromTree)
|
||||
{
|
||||
RefPtr<LayerChromium> rootLayer = LayerChromium::create();
|
||||
ASSERT_TRUE(rootLayer);
|
||||
RefPtr<LayerChromium> childLayer = LayerChromium::create();
|
||||
ASSERT_TRUE(childLayer);
|
||||
rootLayer->addChild(childLayer);
|
||||
RefPtr<TextureLayerChromium> testLayer = TextureLayerChromium::create(0);
|
||||
ASSERT_TRUE(testLayer);
|
||||
testLayer->setTextureId(0);
|
||||
childLayer->addChild(testLayer);
|
||||
|
||||
EXPECT_CALL(*m_layerTreeHost, acquireLayerTextures()).Times(AnyNumber());
|
||||
m_layerTreeHost->setRootLayer(rootLayer);
|
||||
Mock::VerifyAndClearExpectations(m_layerTreeHost.get());
|
||||
|
||||
EXPECT_CALL(*m_layerTreeHost, acquireLayerTextures()).Times(0);
|
||||
testLayer->removeFromParent();
|
||||
Mock::VerifyAndClearExpectations(m_layerTreeHost.get());
|
||||
|
||||
EXPECT_CALL(*m_layerTreeHost, acquireLayerTextures()).Times(0);
|
||||
childLayer->addChild(testLayer);
|
||||
Mock::VerifyAndClearExpectations(m_layerTreeHost.get());
|
||||
|
||||
EXPECT_CALL(*m_layerTreeHost, acquireLayerTextures()).Times(0);
|
||||
testLayer->setTextureId(1);
|
||||
Mock::VerifyAndClearExpectations(m_layerTreeHost.get());
|
||||
|
||||
EXPECT_CALL(*m_layerTreeHost, acquireLayerTextures()).Times(AtLeast(1));
|
||||
testLayer->removeFromParent();
|
||||
Mock::VerifyAndClearExpectations(m_layerTreeHost.get());
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
72
webkit/compositor/ThrottledTextureUploaderTest.cpp
Normal file
72
webkit/compositor/ThrottledTextureUploaderTest.cpp
Normal file
@ -0,0 +1,72 @@
|
||||
// Copyright 2012 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "ThrottledTextureUploader.h"
|
||||
|
||||
#include "Extensions3DChromium.h"
|
||||
#include "FakeWebGraphicsContext3D.h"
|
||||
#include "GraphicsContext3D.h"
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <wtf/RefPtr.h>
|
||||
|
||||
using namespace WebCore;
|
||||
using namespace WebKit;
|
||||
|
||||
namespace {
|
||||
|
||||
class FakeWebGraphicsContext3DWithQueryTesting : public FakeWebGraphicsContext3D {
|
||||
public:
|
||||
FakeWebGraphicsContext3DWithQueryTesting() : m_resultAvailable(0)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void getQueryObjectuivEXT(WebGLId, GC3Denum type, GC3Duint* value)
|
||||
{
|
||||
switch (type) {
|
||||
case Extensions3DChromium::QUERY_RESULT_AVAILABLE_EXT:
|
||||
*value = m_resultAvailable;
|
||||
break;
|
||||
default:
|
||||
*value = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void setResultAvailable(unsigned resultAvailable) { m_resultAvailable = resultAvailable; }
|
||||
|
||||
private:
|
||||
unsigned m_resultAvailable;
|
||||
};
|
||||
|
||||
TEST(ThrottledTextureUploaderTest, IsBusy)
|
||||
{
|
||||
OwnPtr<FakeWebGraphicsContext3DWithQueryTesting> fakeContext(adoptPtr(new FakeWebGraphicsContext3DWithQueryTesting));
|
||||
OwnPtr<ThrottledTextureUploader> uploader = ThrottledTextureUploader::create(fakeContext.get(), 2);
|
||||
|
||||
fakeContext->setResultAvailable(0);
|
||||
EXPECT_FALSE(uploader->isBusy());
|
||||
uploader->beginUploads();
|
||||
uploader->endUploads();
|
||||
EXPECT_FALSE(uploader->isBusy());
|
||||
uploader->beginUploads();
|
||||
uploader->endUploads();
|
||||
EXPECT_TRUE(uploader->isBusy());
|
||||
|
||||
fakeContext->setResultAvailable(1);
|
||||
EXPECT_FALSE(uploader->isBusy());
|
||||
uploader->beginUploads();
|
||||
uploader->endUploads();
|
||||
EXPECT_FALSE(uploader->isBusy());
|
||||
uploader->beginUploads();
|
||||
uploader->endUploads();
|
||||
EXPECT_FALSE(uploader->isBusy());
|
||||
uploader->beginUploads();
|
||||
uploader->endUploads();
|
||||
}
|
||||
|
||||
} // namespace
|
1571
webkit/compositor/TiledLayerChromiumTest.cpp
Normal file
1571
webkit/compositor/TiledLayerChromiumTest.cpp
Normal file
File diff suppressed because it is too large
Load Diff
405
webkit/compositor/TreeSynchronizerTest.cpp
Normal file
405
webkit/compositor/TreeSynchronizerTest.cpp
Normal file
@ -0,0 +1,405 @@
|
||||
// Copyright 2011 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "TreeSynchronizer.h"
|
||||
|
||||
#include "CCAnimationTestCommon.h"
|
||||
#include "CCLayerAnimationController.h"
|
||||
#include "CCLayerImpl.h"
|
||||
#include "CCProxy.h"
|
||||
#include "CCSingleThreadProxy.h"
|
||||
#include "LayerChromium.h"
|
||||
#include "Region.h"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using namespace WebCore;
|
||||
using namespace WebKitTests;
|
||||
|
||||
namespace {
|
||||
|
||||
class MockCCLayerImpl : public CCLayerImpl {
|
||||
public:
|
||||
static PassOwnPtr<MockCCLayerImpl> create(int layerId)
|
||||
{
|
||||
return adoptPtr(new MockCCLayerImpl(layerId));
|
||||
}
|
||||
virtual ~MockCCLayerImpl()
|
||||
{
|
||||
if (m_ccLayerDestructionList)
|
||||
m_ccLayerDestructionList->append(id());
|
||||
}
|
||||
|
||||
void setCCLayerDestructionList(Vector<int>* list) { m_ccLayerDestructionList = list; }
|
||||
|
||||
private:
|
||||
MockCCLayerImpl(int layerId)
|
||||
: CCLayerImpl(layerId)
|
||||
, m_ccLayerDestructionList(0)
|
||||
{
|
||||
}
|
||||
|
||||
Vector<int>* m_ccLayerDestructionList;
|
||||
};
|
||||
|
||||
class MockLayerChromium : public LayerChromium {
|
||||
public:
|
||||
static PassRefPtr<MockLayerChromium> create(Vector<int>* ccLayerDestructionList)
|
||||
{
|
||||
return adoptRef(new MockLayerChromium(ccLayerDestructionList));
|
||||
}
|
||||
|
||||
virtual ~MockLayerChromium() { }
|
||||
|
||||
virtual PassOwnPtr<CCLayerImpl> createCCLayerImpl() OVERRIDE
|
||||
{
|
||||
return MockCCLayerImpl::create(m_layerId);
|
||||
}
|
||||
|
||||
virtual void pushPropertiesTo(CCLayerImpl* ccLayer) OVERRIDE
|
||||
{
|
||||
LayerChromium::pushPropertiesTo(ccLayer);
|
||||
|
||||
MockCCLayerImpl* mockCCLayer = static_cast<MockCCLayerImpl*>(ccLayer);
|
||||
mockCCLayer->setCCLayerDestructionList(m_ccLayerDestructionList);
|
||||
}
|
||||
private:
|
||||
MockLayerChromium(Vector<int>* ccLayerDestructionList)
|
||||
: LayerChromium()
|
||||
, m_ccLayerDestructionList(ccLayerDestructionList)
|
||||
{
|
||||
}
|
||||
|
||||
Vector<int>* m_ccLayerDestructionList;
|
||||
};
|
||||
|
||||
class FakeLayerAnimationController : public CCLayerAnimationController {
|
||||
public:
|
||||
static PassOwnPtr<FakeLayerAnimationController> create(CCLayerAnimationControllerClient* client)
|
||||
{
|
||||
return adoptPtr(new FakeLayerAnimationController(client));
|
||||
}
|
||||
|
||||
bool synchronizedAnimations() const { return m_synchronizedAnimations; }
|
||||
|
||||
private:
|
||||
explicit FakeLayerAnimationController(CCLayerAnimationControllerClient* client)
|
||||
: CCLayerAnimationController(client)
|
||||
, m_synchronizedAnimations(false)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void pushAnimationUpdatesTo(CCLayerAnimationController* controllerImpl)
|
||||
{
|
||||
CCLayerAnimationController::pushAnimationUpdatesTo(controllerImpl);
|
||||
m_synchronizedAnimations = true;
|
||||
}
|
||||
|
||||
bool m_synchronizedAnimations;
|
||||
};
|
||||
|
||||
void expectTreesAreIdentical(LayerChromium* layer, CCLayerImpl* ccLayer, CCLayerTreeHostImpl* hostImpl)
|
||||
{
|
||||
ASSERT_TRUE(layer);
|
||||
ASSERT_TRUE(ccLayer);
|
||||
|
||||
EXPECT_EQ(layer->id(), ccLayer->id());
|
||||
EXPECT_EQ(ccLayer->layerTreeHostImpl(), hostImpl);
|
||||
|
||||
EXPECT_EQ(layer->nonFastScrollableRegion(), ccLayer->nonFastScrollableRegion());
|
||||
|
||||
ASSERT_EQ(!!layer->maskLayer(), !!ccLayer->maskLayer());
|
||||
if (layer->maskLayer())
|
||||
expectTreesAreIdentical(layer->maskLayer(), ccLayer->maskLayer(), hostImpl);
|
||||
|
||||
ASSERT_EQ(!!layer->replicaLayer(), !!ccLayer->replicaLayer());
|
||||
if (layer->replicaLayer())
|
||||
expectTreesAreIdentical(layer->replicaLayer(), ccLayer->replicaLayer(), hostImpl);
|
||||
|
||||
const Vector<RefPtr<LayerChromium> >& layerChildren = layer->children();
|
||||
const Vector<OwnPtr<CCLayerImpl> >& ccLayerChildren = ccLayer->children();
|
||||
|
||||
ASSERT_EQ(layerChildren.size(), ccLayerChildren.size());
|
||||
|
||||
for (size_t i = 0; i < layerChildren.size(); ++i)
|
||||
expectTreesAreIdentical(layerChildren[i].get(), ccLayerChildren[i].get(), hostImpl);
|
||||
}
|
||||
|
||||
// Attempts to synchronizes a null tree. This should not crash, and should
|
||||
// return a null tree.
|
||||
TEST(TreeSynchronizerTest, syncNullTree)
|
||||
{
|
||||
DebugScopedSetImplThread impl;
|
||||
|
||||
OwnPtr<CCLayerImpl> ccLayerTreeRoot = TreeSynchronizer::synchronizeTrees(0, nullptr, 0);
|
||||
|
||||
EXPECT_TRUE(!ccLayerTreeRoot.get());
|
||||
}
|
||||
|
||||
// Constructs a very simple tree and synchronizes it without trying to reuse any preexisting layers.
|
||||
TEST(TreeSynchronizerTest, syncSimpleTreeFromEmpty)
|
||||
{
|
||||
DebugScopedSetImplThread impl;
|
||||
|
||||
CCLayerTreeSettings settings;
|
||||
OwnPtr<CCLayerTreeHostImpl> hostImpl = CCLayerTreeHostImpl::create(settings, 0);
|
||||
|
||||
RefPtr<LayerChromium> layerTreeRoot = LayerChromium::create();
|
||||
layerTreeRoot->addChild(LayerChromium::create());
|
||||
layerTreeRoot->addChild(LayerChromium::create());
|
||||
|
||||
OwnPtr<CCLayerImpl> ccLayerTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), nullptr, hostImpl.get());
|
||||
|
||||
expectTreesAreIdentical(layerTreeRoot.get(), ccLayerTreeRoot.get(), hostImpl.get());
|
||||
}
|
||||
|
||||
// Constructs a very simple tree and synchronizes it attempting to reuse some layers
|
||||
TEST(TreeSynchronizerTest, syncSimpleTreeReusingLayers)
|
||||
{
|
||||
DebugScopedSetImplThread impl;
|
||||
Vector<int> ccLayerDestructionList;
|
||||
|
||||
CCLayerTreeSettings settings;
|
||||
OwnPtr<CCLayerTreeHostImpl> hostImpl = CCLayerTreeHostImpl::create(settings, 0);
|
||||
|
||||
RefPtr<LayerChromium> layerTreeRoot = MockLayerChromium::create(&ccLayerDestructionList);
|
||||
layerTreeRoot->addChild(MockLayerChromium::create(&ccLayerDestructionList));
|
||||
layerTreeRoot->addChild(MockLayerChromium::create(&ccLayerDestructionList));
|
||||
|
||||
OwnPtr<CCLayerImpl> ccLayerTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), nullptr, hostImpl.get());
|
||||
expectTreesAreIdentical(layerTreeRoot.get(), ccLayerTreeRoot.get(), hostImpl.get());
|
||||
|
||||
// Add a new layer to the LayerChromium side
|
||||
layerTreeRoot->children()[0]->addChild(MockLayerChromium::create(&ccLayerDestructionList));
|
||||
// Remove one.
|
||||
layerTreeRoot->children()[1]->removeFromParent();
|
||||
int secondCCLayerId = ccLayerTreeRoot->children()[1]->id();
|
||||
|
||||
// Synchronize again. After the sync the trees should be equivalent and we should have created and destroyed one CCLayerImpl.
|
||||
ccLayerTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), ccLayerTreeRoot.release(), hostImpl.get());
|
||||
expectTreesAreIdentical(layerTreeRoot.get(), ccLayerTreeRoot.get(), hostImpl.get());
|
||||
|
||||
ASSERT_EQ(1u, ccLayerDestructionList.size());
|
||||
EXPECT_EQ(secondCCLayerId, ccLayerDestructionList[0]);
|
||||
}
|
||||
|
||||
// Constructs a very simple tree and checks that a stacking-order change is tracked properly.
|
||||
TEST(TreeSynchronizerTest, syncSimpleTreeAndTrackStackingOrderChange)
|
||||
{
|
||||
DebugScopedSetImplThread impl;
|
||||
Vector<int> ccLayerDestructionList;
|
||||
|
||||
CCLayerTreeSettings settings;
|
||||
OwnPtr<CCLayerTreeHostImpl> hostImpl = CCLayerTreeHostImpl::create(settings, 0);
|
||||
|
||||
// Set up the tree and sync once. child2 needs to be synced here, too, even though we
|
||||
// remove it to set up the intended scenario.
|
||||
RefPtr<LayerChromium> layerTreeRoot = MockLayerChromium::create(&ccLayerDestructionList);
|
||||
RefPtr<LayerChromium> child2 = MockLayerChromium::create(&ccLayerDestructionList);
|
||||
layerTreeRoot->addChild(MockLayerChromium::create(&ccLayerDestructionList));
|
||||
layerTreeRoot->addChild(child2);
|
||||
OwnPtr<CCLayerImpl> ccLayerTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), nullptr, hostImpl.get());
|
||||
expectTreesAreIdentical(layerTreeRoot.get(), ccLayerTreeRoot.get(), hostImpl.get());
|
||||
ccLayerTreeRoot->resetAllChangeTrackingForSubtree();
|
||||
|
||||
// re-insert the layer and sync again.
|
||||
child2->removeFromParent();
|
||||
layerTreeRoot->addChild(child2);
|
||||
ccLayerTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), ccLayerTreeRoot.release(), hostImpl.get());
|
||||
expectTreesAreIdentical(layerTreeRoot.get(), ccLayerTreeRoot.get(), hostImpl.get());
|
||||
|
||||
// Check that the impl thread properly tracked the change.
|
||||
EXPECT_FALSE(ccLayerTreeRoot->layerPropertyChanged());
|
||||
EXPECT_FALSE(ccLayerTreeRoot->children()[0]->layerPropertyChanged());
|
||||
EXPECT_TRUE(ccLayerTreeRoot->children()[1]->layerPropertyChanged());
|
||||
}
|
||||
|
||||
TEST(TreeSynchronizerTest, syncSimpleTreeAndProperties)
|
||||
{
|
||||
DebugScopedSetImplThread impl;
|
||||
|
||||
CCLayerTreeSettings settings;
|
||||
OwnPtr<CCLayerTreeHostImpl> hostImpl = CCLayerTreeHostImpl::create(settings, 0);
|
||||
|
||||
RefPtr<LayerChromium> layerTreeRoot = LayerChromium::create();
|
||||
layerTreeRoot->addChild(LayerChromium::create());
|
||||
layerTreeRoot->addChild(LayerChromium::create());
|
||||
|
||||
// Pick some random properties to set. The values are not important, we're just testing that at least some properties are making it through.
|
||||
FloatPoint rootPosition = FloatPoint(2.3f, 7.4f);
|
||||
layerTreeRoot->setPosition(rootPosition);
|
||||
|
||||
float firstChildOpacity = 0.25f;
|
||||
layerTreeRoot->children()[0]->setOpacity(firstChildOpacity);
|
||||
|
||||
IntSize secondChildBounds = IntSize(25, 53);
|
||||
layerTreeRoot->children()[1]->setBounds(secondChildBounds);
|
||||
|
||||
OwnPtr<CCLayerImpl> ccLayerTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), nullptr, hostImpl.get());
|
||||
expectTreesAreIdentical(layerTreeRoot.get(), ccLayerTreeRoot.get(), hostImpl.get());
|
||||
|
||||
// Check that the property values we set on the LayerChromium tree are reflected in the CCLayerImpl tree.
|
||||
FloatPoint rootCCLayerPosition = ccLayerTreeRoot->position();
|
||||
EXPECT_EQ(rootPosition.x(), rootCCLayerPosition.x());
|
||||
EXPECT_EQ(rootPosition.y(), rootCCLayerPosition.y());
|
||||
|
||||
EXPECT_EQ(firstChildOpacity, ccLayerTreeRoot->children()[0]->opacity());
|
||||
|
||||
IntSize secondCCLayerChildBounds = ccLayerTreeRoot->children()[1]->bounds();
|
||||
EXPECT_EQ(secondChildBounds.width(), secondCCLayerChildBounds.width());
|
||||
EXPECT_EQ(secondChildBounds.height(), secondCCLayerChildBounds.height());
|
||||
}
|
||||
|
||||
TEST(TreeSynchronizerTest, reuseCCLayersAfterStructuralChange)
|
||||
{
|
||||
DebugScopedSetImplThread impl;
|
||||
Vector<int> ccLayerDestructionList;
|
||||
|
||||
CCLayerTreeSettings settings;
|
||||
OwnPtr<CCLayerTreeHostImpl> hostImpl = CCLayerTreeHostImpl::create(settings, 0);
|
||||
|
||||
// Set up a tree with this sort of structure:
|
||||
// root --- A --- B ---+--- C
|
||||
// |
|
||||
// +--- D
|
||||
RefPtr<LayerChromium> layerTreeRoot = MockLayerChromium::create(&ccLayerDestructionList);
|
||||
layerTreeRoot->addChild(MockLayerChromium::create(&ccLayerDestructionList));
|
||||
|
||||
RefPtr<LayerChromium> layerA = layerTreeRoot->children()[0].get();
|
||||
layerA->addChild(MockLayerChromium::create(&ccLayerDestructionList));
|
||||
|
||||
RefPtr<LayerChromium> layerB = layerA->children()[0].get();
|
||||
layerB->addChild(MockLayerChromium::create(&ccLayerDestructionList));
|
||||
|
||||
RefPtr<LayerChromium> layerC = layerB->children()[0].get();
|
||||
layerB->addChild(MockLayerChromium::create(&ccLayerDestructionList));
|
||||
RefPtr<LayerChromium> layerD = layerB->children()[1].get();
|
||||
|
||||
OwnPtr<CCLayerImpl> ccLayerTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), nullptr, hostImpl.get());
|
||||
expectTreesAreIdentical(layerTreeRoot.get(), ccLayerTreeRoot.get(), hostImpl.get());
|
||||
|
||||
// Now restructure the tree to look like this:
|
||||
// root --- D ---+--- A
|
||||
// |
|
||||
// +--- C --- B
|
||||
layerTreeRoot->removeAllChildren();
|
||||
layerD->removeAllChildren();
|
||||
layerTreeRoot->addChild(layerD);
|
||||
layerA->removeAllChildren();
|
||||
layerD->addChild(layerA);
|
||||
layerC->removeAllChildren();
|
||||
layerD->addChild(layerC);
|
||||
layerB->removeAllChildren();
|
||||
layerC->addChild(layerB);
|
||||
|
||||
// After another synchronize our trees should match and we should not have destroyed any CCLayerImpls
|
||||
ccLayerTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), ccLayerTreeRoot.release(), hostImpl.get());
|
||||
expectTreesAreIdentical(layerTreeRoot.get(), ccLayerTreeRoot.get(), hostImpl.get());
|
||||
|
||||
EXPECT_EQ(0u, ccLayerDestructionList.size());
|
||||
}
|
||||
|
||||
// Constructs a very simple tree, synchronizes it, then synchronizes to a totally new tree. All layers from the old tree should be deleted.
|
||||
TEST(TreeSynchronizerTest, syncSimpleTreeThenDestroy)
|
||||
{
|
||||
DebugScopedSetImplThread impl;
|
||||
Vector<int> ccLayerDestructionList;
|
||||
|
||||
CCLayerTreeSettings settings;
|
||||
OwnPtr<CCLayerTreeHostImpl> hostImpl = CCLayerTreeHostImpl::create(settings, 0);
|
||||
|
||||
RefPtr<LayerChromium> oldLayerTreeRoot = MockLayerChromium::create(&ccLayerDestructionList);
|
||||
oldLayerTreeRoot->addChild(MockLayerChromium::create(&ccLayerDestructionList));
|
||||
oldLayerTreeRoot->addChild(MockLayerChromium::create(&ccLayerDestructionList));
|
||||
|
||||
int oldTreeRootLayerId = oldLayerTreeRoot->id();
|
||||
int oldTreeFirstChildLayerId = oldLayerTreeRoot->children()[0]->id();
|
||||
int oldTreeSecondChildLayerId = oldLayerTreeRoot->children()[1]->id();
|
||||
|
||||
OwnPtr<CCLayerImpl> ccLayerTreeRoot = TreeSynchronizer::synchronizeTrees(oldLayerTreeRoot.get(), nullptr, hostImpl.get());
|
||||
expectTreesAreIdentical(oldLayerTreeRoot.get(), ccLayerTreeRoot.get(), hostImpl.get());
|
||||
|
||||
// Remove all children on the LayerChromium side.
|
||||
oldLayerTreeRoot->removeAllChildren();
|
||||
|
||||
// Synchronize again. After the sync all CCLayerImpls from the old tree should be deleted.
|
||||
RefPtr<LayerChromium> newLayerTreeRoot = LayerChromium::create();
|
||||
ccLayerTreeRoot = TreeSynchronizer::synchronizeTrees(newLayerTreeRoot.get(), ccLayerTreeRoot.release(), hostImpl.get());
|
||||
expectTreesAreIdentical(newLayerTreeRoot.get(), ccLayerTreeRoot.get(), hostImpl.get());
|
||||
|
||||
ASSERT_EQ(3u, ccLayerDestructionList.size());
|
||||
EXPECT_TRUE(ccLayerDestructionList.contains(oldTreeRootLayerId));
|
||||
EXPECT_TRUE(ccLayerDestructionList.contains(oldTreeFirstChildLayerId));
|
||||
EXPECT_TRUE(ccLayerDestructionList.contains(oldTreeSecondChildLayerId));
|
||||
}
|
||||
|
||||
// Constructs+syncs a tree with mask, replica, and replica mask layers.
|
||||
TEST(TreeSynchronizerTest, syncMaskReplicaAndReplicaMaskLayers)
|
||||
{
|
||||
DebugScopedSetImplThread impl;
|
||||
|
||||
CCLayerTreeSettings settings;
|
||||
OwnPtr<CCLayerTreeHostImpl> hostImpl = CCLayerTreeHostImpl::create(settings, 0);
|
||||
|
||||
RefPtr<LayerChromium> layerTreeRoot = LayerChromium::create();
|
||||
layerTreeRoot->addChild(LayerChromium::create());
|
||||
layerTreeRoot->addChild(LayerChromium::create());
|
||||
layerTreeRoot->addChild(LayerChromium::create());
|
||||
|
||||
// First child gets a mask layer.
|
||||
RefPtr<LayerChromium> maskLayer = LayerChromium::create();
|
||||
layerTreeRoot->children()[0]->setMaskLayer(maskLayer.get());
|
||||
|
||||
// Second child gets a replica layer.
|
||||
RefPtr<LayerChromium> replicaLayer = LayerChromium::create();
|
||||
layerTreeRoot->children()[1]->setReplicaLayer(replicaLayer.get());
|
||||
|
||||
// Third child gets a replica layer with a mask layer.
|
||||
RefPtr<LayerChromium> replicaLayerWithMask = LayerChromium::create();
|
||||
RefPtr<LayerChromium> replicaMaskLayer = LayerChromium::create();
|
||||
replicaLayerWithMask->setMaskLayer(replicaMaskLayer.get());
|
||||
layerTreeRoot->children()[2]->setReplicaLayer(replicaLayerWithMask.get());
|
||||
|
||||
OwnPtr<CCLayerImpl> ccLayerTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), nullptr, hostImpl.get());
|
||||
|
||||
expectTreesAreIdentical(layerTreeRoot.get(), ccLayerTreeRoot.get(), hostImpl.get());
|
||||
|
||||
// Remove the mask layer.
|
||||
layerTreeRoot->children()[0]->setMaskLayer(0);
|
||||
ccLayerTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), ccLayerTreeRoot.release(), hostImpl.get());
|
||||
expectTreesAreIdentical(layerTreeRoot.get(), ccLayerTreeRoot.get(), hostImpl.get());
|
||||
|
||||
// Remove the replica layer.
|
||||
layerTreeRoot->children()[1]->setReplicaLayer(0);
|
||||
ccLayerTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), ccLayerTreeRoot.release(), hostImpl.get());
|
||||
expectTreesAreIdentical(layerTreeRoot.get(), ccLayerTreeRoot.get(), hostImpl.get());
|
||||
|
||||
// Remove the replica mask.
|
||||
replicaLayerWithMask->setMaskLayer(0);
|
||||
ccLayerTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), ccLayerTreeRoot.release(), hostImpl.get());
|
||||
expectTreesAreIdentical(layerTreeRoot.get(), ccLayerTreeRoot.get(), hostImpl.get());
|
||||
}
|
||||
|
||||
TEST(TreeSynchronizerTest, synchronizeAnimations)
|
||||
{
|
||||
DebugScopedSetImplThread impl;
|
||||
|
||||
CCLayerTreeSettings settings;
|
||||
OwnPtr<CCLayerTreeHostImpl> hostImpl = CCLayerTreeHostImpl::create(settings, 0);
|
||||
|
||||
RefPtr<LayerChromium> layerTreeRoot = LayerChromium::create();
|
||||
|
||||
FakeLayerAnimationControllerClient dummy;
|
||||
layerTreeRoot->setLayerAnimationController(FakeLayerAnimationController::create(&dummy));
|
||||
|
||||
EXPECT_FALSE(static_cast<FakeLayerAnimationController*>(layerTreeRoot->layerAnimationController())->synchronizedAnimations());
|
||||
|
||||
OwnPtr<CCLayerImpl> ccLayerTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), nullptr, hostImpl.get());
|
||||
ccLayerTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), ccLayerTreeRoot.release(), hostImpl.get());
|
||||
|
||||
EXPECT_TRUE(static_cast<FakeLayerAnimationController*>(layerTreeRoot->layerAnimationController())->synchronizedAnimations());
|
||||
}
|
||||
|
||||
} // namespace
|
63
webkit/compositor/WebAnimationTest.cpp
Normal file
63
webkit/compositor/WebAnimationTest.cpp
Normal file
@ -0,0 +1,63 @@
|
||||
// Copyright 2012 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <public/WebAnimation.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <public/WebFloatAnimationCurve.h>
|
||||
#include <wtf/OwnPtr.h>
|
||||
#include <wtf/PassOwnPtr.h>
|
||||
|
||||
using namespace WebKit;
|
||||
|
||||
namespace {
|
||||
|
||||
// Linux/Win bots failed on this test.
|
||||
// https://bugs.webkit.org/show_bug.cgi?id=90651
|
||||
#if OS(WINDOWS)
|
||||
#define MAYBE_DefaultSettings DISABLED_DefaultSettings
|
||||
#elif OS(LINUX)
|
||||
#define MAYBE_DefaultSettings DISABLED_DefaultSettings
|
||||
#else
|
||||
#define MAYBE_DefaultSettings DefaultSettings
|
||||
#endif
|
||||
TEST(WebAnimationTest, MAYBE_DefaultSettings)
|
||||
{
|
||||
OwnPtr<WebAnimationCurve> curve = adoptPtr(WebFloatAnimationCurve::create());
|
||||
OwnPtr<WebAnimation> animation = adoptPtr(WebAnimation::create(*curve, WebAnimation::TargetPropertyOpacity));
|
||||
|
||||
// Ensure that the defaults are correct.
|
||||
EXPECT_EQ(1, animation->iterations());
|
||||
EXPECT_EQ(0, animation->startTime());
|
||||
EXPECT_EQ(0, animation->timeOffset());
|
||||
EXPECT_FALSE(animation->alternatesDirection());
|
||||
}
|
||||
|
||||
// Linux/Win bots failed on this test.
|
||||
// https://bugs.webkit.org/show_bug.cgi?id=90651
|
||||
#if OS(WINDOWS)
|
||||
#define MAYBE_ModifiedSettings DISABLED_ModifiedSettings
|
||||
#elif OS(LINUX)
|
||||
#define MAYBE_ModifiedSettings DISABLED_ModifiedSettings
|
||||
#else
|
||||
#define MAYBE_ModifiedSettings ModifiedSettings
|
||||
#endif
|
||||
TEST(WebAnimationTest, MAYBE_ModifiedSettings)
|
||||
{
|
||||
OwnPtr<WebFloatAnimationCurve> curve = adoptPtr(WebFloatAnimationCurve::create());
|
||||
OwnPtr<WebAnimation> animation = adoptPtr(WebAnimation::create(*curve, WebAnimation::TargetPropertyOpacity));
|
||||
animation->setIterations(2);
|
||||
animation->setStartTime(2);
|
||||
animation->setTimeOffset(2);
|
||||
animation->setAlternatesDirection(true);
|
||||
|
||||
EXPECT_EQ(2, animation->iterations());
|
||||
EXPECT_EQ(2, animation->startTime());
|
||||
EXPECT_EQ(2, animation->timeOffset());
|
||||
EXPECT_TRUE(animation->alternatesDirection());
|
||||
}
|
||||
|
||||
} // namespace
|
155
webkit/compositor/WebLayerTest.cpp
Normal file
155
webkit/compositor/WebLayerTest.cpp
Normal file
@ -0,0 +1,155 @@
|
||||
// Copyright 2011 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "config.h"
|
||||
#include <public/WebLayer.h>
|
||||
|
||||
#include "CompositorFakeWebGraphicsContext3D.h"
|
||||
#include "WebLayerImpl.h"
|
||||
#include "WebLayerTreeViewTestCommon.h"
|
||||
#include <public/WebCompositor.h>
|
||||
#include <public/WebContentLayer.h>
|
||||
#include <public/WebContentLayerClient.h>
|
||||
#include <public/WebExternalTextureLayer.h>
|
||||
#include <public/WebFloatPoint.h>
|
||||
#include <public/WebFloatRect.h>
|
||||
#include <public/WebLayerTreeView.h>
|
||||
#include <public/WebLayerTreeViewClient.h>
|
||||
#include <public/WebRect.h>
|
||||
#include <public/WebSize.h>
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
using namespace WebKit;
|
||||
using testing::AnyNumber;
|
||||
using testing::AtLeast;
|
||||
using testing::Mock;
|
||||
using testing::Test;
|
||||
using testing::_;
|
||||
|
||||
namespace {
|
||||
|
||||
class MockWebContentLayerClient : public WebContentLayerClient {
|
||||
public:
|
||||
MOCK_METHOD3(paintContents, void(WebCanvas*, const WebRect& clip, WebFloatRect& opaque));
|
||||
};
|
||||
|
||||
class WebLayerTest : public Test {
|
||||
public:
|
||||
virtual void SetUp()
|
||||
{
|
||||
// Initialize without threading support.
|
||||
WebKit::WebCompositor::initialize(0);
|
||||
m_rootLayer = adoptPtr(WebLayer::create());
|
||||
EXPECT_CALL(m_client, scheduleComposite()).Times(AnyNumber());
|
||||
EXPECT_TRUE(m_view = adoptPtr(WebLayerTreeView::create(&m_client, *m_rootLayer, WebLayerTreeView::Settings())));
|
||||
Mock::VerifyAndClearExpectations(&m_client);
|
||||
}
|
||||
|
||||
virtual void TearDown()
|
||||
{
|
||||
// We may get any number of scheduleComposite calls during shutdown.
|
||||
EXPECT_CALL(m_client, scheduleComposite()).Times(AnyNumber());
|
||||
m_rootLayer.clear();
|
||||
m_view.clear();
|
||||
WebKit::WebCompositor::shutdown();
|
||||
}
|
||||
|
||||
protected:
|
||||
MockWebLayerTreeViewClient m_client;
|
||||
OwnPtr<WebLayer> m_rootLayer;
|
||||
OwnPtr<WebLayerTreeView> m_view;
|
||||
};
|
||||
|
||||
// Tests that the client gets called to ask for a composite if we change the
|
||||
// fields.
|
||||
TEST_F(WebLayerTest, Client)
|
||||
{
|
||||
// Base layer.
|
||||
EXPECT_CALL(m_client, scheduleComposite()).Times(AnyNumber());
|
||||
OwnPtr<WebLayer> layer = adoptPtr(WebLayer::create());
|
||||
m_rootLayer->addChild(layer.get());
|
||||
Mock::VerifyAndClearExpectations(&m_client);
|
||||
|
||||
WebFloatPoint point(3, 4);
|
||||
EXPECT_CALL(m_client, scheduleComposite()).Times(AtLeast(1));
|
||||
layer->setAnchorPoint(point);
|
||||
Mock::VerifyAndClearExpectations(&m_client);
|
||||
EXPECT_EQ(point, layer->anchorPoint());
|
||||
|
||||
EXPECT_CALL(m_client, scheduleComposite()).Times(AtLeast(1));
|
||||
float anchorZ = 5;
|
||||
layer->setAnchorPointZ(anchorZ);
|
||||
Mock::VerifyAndClearExpectations(&m_client);
|
||||
EXPECT_EQ(anchorZ, layer->anchorPointZ());
|
||||
|
||||
WebSize size(7, 8);
|
||||
EXPECT_CALL(m_client, scheduleComposite()).Times(AtLeast(1));
|
||||
layer->setBounds(size);
|
||||
Mock::VerifyAndClearExpectations(&m_client);
|
||||
EXPECT_EQ(size, layer->bounds());
|
||||
|
||||
EXPECT_CALL(m_client, scheduleComposite()).Times(AtLeast(1));
|
||||
layer->setMasksToBounds(true);
|
||||
Mock::VerifyAndClearExpectations(&m_client);
|
||||
EXPECT_TRUE(layer->masksToBounds());
|
||||
|
||||
EXPECT_CALL(m_client, scheduleComposite()).Times(AnyNumber());
|
||||
OwnPtr<WebLayer> otherLayer = adoptPtr(WebLayer::create());
|
||||
m_rootLayer->addChild(otherLayer.get());
|
||||
EXPECT_CALL(m_client, scheduleComposite()).Times(AtLeast(1));
|
||||
layer->setMaskLayer(otherLayer.get());
|
||||
Mock::VerifyAndClearExpectations(&m_client);
|
||||
|
||||
EXPECT_CALL(m_client, scheduleComposite()).Times(AtLeast(1));
|
||||
float opacity = 0.123f;
|
||||
layer->setOpacity(opacity);
|
||||
Mock::VerifyAndClearExpectations(&m_client);
|
||||
EXPECT_EQ(opacity, layer->opacity());
|
||||
|
||||
EXPECT_CALL(m_client, scheduleComposite()).Times(AtLeast(1));
|
||||
layer->setOpaque(true);
|
||||
Mock::VerifyAndClearExpectations(&m_client);
|
||||
EXPECT_TRUE(layer->opaque());
|
||||
|
||||
EXPECT_CALL(m_client, scheduleComposite()).Times(AtLeast(1));
|
||||
layer->setPosition(point);
|
||||
Mock::VerifyAndClearExpectations(&m_client);
|
||||
EXPECT_EQ(point, layer->position());
|
||||
|
||||
// Texture layer.
|
||||
EXPECT_CALL(m_client, scheduleComposite()).Times(AnyNumber());
|
||||
OwnPtr<WebExternalTextureLayer> textureLayer = adoptPtr(WebExternalTextureLayer::create());
|
||||
m_rootLayer->addChild(textureLayer->layer());
|
||||
Mock::VerifyAndClearExpectations(&m_client);
|
||||
|
||||
EXPECT_CALL(m_client, scheduleComposite()).Times(AtLeast(1));
|
||||
textureLayer->setTextureId(3);
|
||||
Mock::VerifyAndClearExpectations(&m_client);
|
||||
|
||||
EXPECT_CALL(m_client, scheduleComposite()).Times(AtLeast(1));
|
||||
textureLayer->setFlipped(true);
|
||||
Mock::VerifyAndClearExpectations(&m_client);
|
||||
|
||||
EXPECT_CALL(m_client, scheduleComposite()).Times(AtLeast(1));
|
||||
WebFloatRect uvRect(0.1f, 0.1f, 0.9f, 0.9f);
|
||||
textureLayer->setUVRect(uvRect);
|
||||
Mock::VerifyAndClearExpectations(&m_client);
|
||||
|
||||
|
||||
// Content layer.
|
||||
MockWebContentLayerClient contentClient;
|
||||
EXPECT_CALL(contentClient, paintContents(_, _, _)).Times(AnyNumber());
|
||||
EXPECT_CALL(m_client, scheduleComposite()).Times(AnyNumber());
|
||||
OwnPtr<WebContentLayer> contentLayer = adoptPtr(WebContentLayer::create(&contentClient));
|
||||
m_rootLayer->addChild(contentLayer->layer());
|
||||
Mock::VerifyAndClearExpectations(&m_client);
|
||||
|
||||
EXPECT_CALL(m_client, scheduleComposite()).Times(AtLeast(1));
|
||||
contentLayer->layer()->setDrawsContent(false);
|
||||
Mock::VerifyAndClearExpectations(&m_client);
|
||||
EXPECT_FALSE(contentLayer->layer()->drawsContent());
|
||||
}
|
||||
|
||||
}
|
187
webkit/compositor/WebLayerTreeViewTest.cpp
Normal file
187
webkit/compositor/WebLayerTreeViewTest.cpp
Normal file
@ -0,0 +1,187 @@
|
||||
// Copyright 2012 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <public/WebLayerTreeView.h>
|
||||
|
||||
#include "CompositorFakeWebGraphicsContext3D.h"
|
||||
#include "FakeWebCompositorOutputSurface.h"
|
||||
#include "WebLayerTreeViewTestCommon.h"
|
||||
#include <gmock/gmock.h>
|
||||
#include <public/Platform.h>
|
||||
#include <public/WebCompositor.h>
|
||||
#include <public/WebLayer.h>
|
||||
#include <public/WebLayerTreeViewClient.h>
|
||||
#include <public/WebThread.h>
|
||||
#include <wtf/RefCounted.h>
|
||||
#include <wtf/RefPtr.h>
|
||||
|
||||
using namespace WebKit;
|
||||
using testing::Mock;
|
||||
using testing::Test;
|
||||
|
||||
namespace {
|
||||
|
||||
class MockWebLayerTreeViewClientForThreadedTests : public MockWebLayerTreeViewClient {
|
||||
public:
|
||||
virtual void didBeginFrame() OVERRIDE
|
||||
{
|
||||
WebKit::Platform::current()->currentThread()->exitRunLoop();
|
||||
MockWebLayerTreeViewClient::didBeginFrame();
|
||||
}
|
||||
};
|
||||
|
||||
class WebLayerTreeViewTestBase : public Test {
|
||||
protected:
|
||||
virtual void initializeCompositor() = 0;
|
||||
virtual WebLayerTreeViewClient* client() = 0;
|
||||
|
||||
public:
|
||||
virtual void SetUp()
|
||||
{
|
||||
initializeCompositor();
|
||||
m_rootLayer = adoptPtr(WebLayer::create());
|
||||
ASSERT_TRUE(m_view = adoptPtr(WebLayerTreeView::create(client(), *m_rootLayer, WebLayerTreeView::Settings())));
|
||||
m_view->setSurfaceReady();
|
||||
}
|
||||
|
||||
virtual void TearDown()
|
||||
{
|
||||
Mock::VerifyAndClearExpectations(client());
|
||||
|
||||
m_rootLayer.clear();
|
||||
m_view.clear();
|
||||
WebKit::WebCompositor::shutdown();
|
||||
}
|
||||
|
||||
protected:
|
||||
OwnPtr<WebLayer> m_rootLayer;
|
||||
OwnPtr<WebLayerTreeView> m_view;
|
||||
};
|
||||
|
||||
class WebLayerTreeViewSingleThreadTest : public WebLayerTreeViewTestBase {
|
||||
protected:
|
||||
void composite()
|
||||
{
|
||||
m_view->composite();
|
||||
}
|
||||
|
||||
virtual void initializeCompositor() OVERRIDE
|
||||
{
|
||||
WebKit::WebCompositor::initialize(0);
|
||||
}
|
||||
|
||||
virtual WebLayerTreeViewClient* client() OVERRIDE
|
||||
{
|
||||
return &m_client;
|
||||
}
|
||||
|
||||
MockWebLayerTreeViewClient m_client;
|
||||
};
|
||||
|
||||
class CancelableTaskWrapper : public RefCounted<CancelableTaskWrapper> {
|
||||
class Task : public WebThread::Task {
|
||||
public:
|
||||
Task(CancelableTaskWrapper* cancelableTask)
|
||||
: m_cancelableTask(cancelableTask)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
virtual void run() OVERRIDE
|
||||
{
|
||||
m_cancelableTask->runIfNotCanceled();
|
||||
}
|
||||
|
||||
RefPtr<CancelableTaskWrapper> m_cancelableTask;
|
||||
};
|
||||
|
||||
public:
|
||||
CancelableTaskWrapper(PassOwnPtr<WebThread::Task> task)
|
||||
: m_task(task)
|
||||
{
|
||||
}
|
||||
|
||||
void cancel()
|
||||
{
|
||||
m_task.clear();
|
||||
}
|
||||
|
||||
WebThread::Task* createTask()
|
||||
{
|
||||
ASSERT(m_task);
|
||||
return new Task(this);
|
||||
}
|
||||
|
||||
void runIfNotCanceled()
|
||||
{
|
||||
if (!m_task)
|
||||
return;
|
||||
m_task->run();
|
||||
m_task.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
OwnPtr<WebThread::Task> m_task;
|
||||
};
|
||||
|
||||
class WebLayerTreeViewThreadedTest : public WebLayerTreeViewTestBase {
|
||||
protected:
|
||||
class TimeoutTask : public WebThread::Task {
|
||||
virtual void run() OVERRIDE
|
||||
{
|
||||
WebKit::Platform::current()->currentThread()->exitRunLoop();
|
||||
}
|
||||
};
|
||||
|
||||
void composite()
|
||||
{
|
||||
m_view->setNeedsRedraw();
|
||||
RefPtr<CancelableTaskWrapper> timeoutTask = adoptRef(new CancelableTaskWrapper(adoptPtr(new TimeoutTask())));
|
||||
WebKit::Platform::current()->currentThread()->postDelayedTask(timeoutTask->createTask(), 5000);
|
||||
WebKit::Platform::current()->currentThread()->enterRunLoop();
|
||||
timeoutTask->cancel();
|
||||
m_view->finishAllRendering();
|
||||
}
|
||||
|
||||
virtual void initializeCompositor() OVERRIDE
|
||||
{
|
||||
m_webThread = adoptPtr(WebKit::Platform::current()->createThread("WebLayerTreeViewTest"));
|
||||
WebCompositor::initialize(m_webThread.get());
|
||||
}
|
||||
|
||||
virtual WebLayerTreeViewClient* client() OVERRIDE
|
||||
{
|
||||
return &m_client;
|
||||
}
|
||||
|
||||
MockWebLayerTreeViewClientForThreadedTests m_client;
|
||||
OwnPtr<WebThread> m_webThread;
|
||||
};
|
||||
|
||||
TEST_F(WebLayerTreeViewSingleThreadTest, InstrumentationCallbacks)
|
||||
{
|
||||
::testing::InSequence dummy;
|
||||
|
||||
EXPECT_CALL(m_client, willCommit());
|
||||
EXPECT_CALL(m_client, didCommit());
|
||||
EXPECT_CALL(m_client, didBeginFrame());
|
||||
|
||||
composite();
|
||||
}
|
||||
|
||||
TEST_F(WebLayerTreeViewThreadedTest, InstrumentationCallbacks)
|
||||
{
|
||||
::testing::InSequence dummy;
|
||||
|
||||
EXPECT_CALL(m_client, willBeginFrame());
|
||||
EXPECT_CALL(m_client, willCommit());
|
||||
EXPECT_CALL(m_client, didCommit());
|
||||
EXPECT_CALL(m_client, didBeginFrame());
|
||||
|
||||
composite();
|
||||
}
|
||||
|
||||
} // namespace
|
619
webkit/compositor/WebTransformOperationsTest.cpp
Normal file
619
webkit/compositor/WebTransformOperationsTest.cpp
Normal file
@ -0,0 +1,619 @@
|
||||
// Copyright 2012 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <public/WebTransformOperations.h>
|
||||
|
||||
#include <public/WebTransformationMatrix.h>
|
||||
|
||||
#include "CCLayerTreeTestCommon.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <wtf/OwnPtr.h>
|
||||
#include <wtf/PassOwnPtr.h>
|
||||
#include <wtf/Vector.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace WebKit;
|
||||
|
||||
TEST(WebTransformOperationTest, transformTypesAreUnique)
|
||||
{
|
||||
Vector<OwnPtr<WebTransformOperations> > transforms;
|
||||
|
||||
WebTransformOperations* toAdd = new WebTransformOperations();
|
||||
toAdd->appendTranslate(1, 0, 0);
|
||||
transforms.append(adoptPtr(toAdd));
|
||||
|
||||
toAdd = new WebTransformOperations();
|
||||
toAdd->appendRotate(0, 0, 1, 2);
|
||||
transforms.append(adoptPtr(toAdd));
|
||||
|
||||
toAdd = new WebTransformOperations();
|
||||
toAdd->appendScale(2, 2, 2);
|
||||
transforms.append(adoptPtr(toAdd));
|
||||
|
||||
toAdd = new WebTransformOperations();
|
||||
toAdd->appendSkew(1, 0);
|
||||
transforms.append(adoptPtr(toAdd));
|
||||
|
||||
toAdd = new WebTransformOperations();
|
||||
toAdd->appendPerspective(800);
|
||||
transforms.append(adoptPtr(toAdd));
|
||||
|
||||
for (size_t i = 0; i < transforms.size(); ++i) {
|
||||
for (size_t j = 0; j < transforms.size(); ++j) {
|
||||
bool matchesType = transforms[i]->matchesTypes(*transforms[j]);
|
||||
EXPECT_TRUE((i == j && matchesType) || !matchesType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(WebTransformOperationTest, matchTypesSameLength)
|
||||
{
|
||||
WebTransformOperations translates;
|
||||
translates.appendTranslate(1, 0, 0);
|
||||
translates.appendTranslate(1, 0, 0);
|
||||
translates.appendTranslate(1, 0, 0);
|
||||
|
||||
WebTransformOperations skews;
|
||||
skews.appendSkew(0, 2);
|
||||
skews.appendSkew(0, 2);
|
||||
skews.appendSkew(0, 2);
|
||||
|
||||
WebTransformOperations translates2;
|
||||
translates2.appendTranslate(0, 2, 0);
|
||||
translates2.appendTranslate(0, 2, 0);
|
||||
translates2.appendTranslate(0, 2, 0);
|
||||
|
||||
WebTransformOperations translates3 = translates2;
|
||||
|
||||
EXPECT_FALSE(translates.matchesTypes(skews));
|
||||
EXPECT_TRUE(translates.matchesTypes(translates2));
|
||||
EXPECT_TRUE(translates.matchesTypes(translates3));
|
||||
}
|
||||
|
||||
TEST(WebTransformOperationTest, matchTypesDifferentLength)
|
||||
{
|
||||
WebTransformOperations translates;
|
||||
translates.appendTranslate(1, 0, 0);
|
||||
translates.appendTranslate(1, 0, 0);
|
||||
translates.appendTranslate(1, 0, 0);
|
||||
|
||||
WebTransformOperations skews;
|
||||
skews.appendSkew(2, 0);
|
||||
skews.appendSkew(2, 0);
|
||||
|
||||
WebTransformOperations translates2;
|
||||
translates2.appendTranslate(0, 2, 0);
|
||||
translates2.appendTranslate(0, 2, 0);
|
||||
|
||||
EXPECT_FALSE(translates.matchesTypes(skews));
|
||||
EXPECT_FALSE(translates.matchesTypes(translates2));
|
||||
}
|
||||
|
||||
void getIdentityOperations(Vector<OwnPtr<WebTransformOperations> >* operations)
|
||||
{
|
||||
WebTransformOperations* toAdd = new WebTransformOperations();
|
||||
operations->append(adoptPtr(toAdd));
|
||||
|
||||
toAdd = new WebTransformOperations();
|
||||
toAdd->appendTranslate(0, 0, 0);
|
||||
operations->append(adoptPtr(toAdd));
|
||||
|
||||
toAdd = new WebTransformOperations();
|
||||
toAdd->appendTranslate(0, 0, 0);
|
||||
toAdd->appendTranslate(0, 0, 0);
|
||||
operations->append(adoptPtr(toAdd));
|
||||
|
||||
toAdd = new WebTransformOperations();
|
||||
toAdd->appendScale(1, 1, 1);
|
||||
operations->append(adoptPtr(toAdd));
|
||||
|
||||
toAdd = new WebTransformOperations();
|
||||
toAdd->appendScale(1, 1, 1);
|
||||
toAdd->appendScale(1, 1, 1);
|
||||
operations->append(adoptPtr(toAdd));
|
||||
|
||||
toAdd = new WebTransformOperations();
|
||||
toAdd->appendSkew(0, 0);
|
||||
operations->append(adoptPtr(toAdd));
|
||||
|
||||
toAdd = new WebTransformOperations();
|
||||
toAdd->appendSkew(0, 0);
|
||||
toAdd->appendSkew(0, 0);
|
||||
operations->append(adoptPtr(toAdd));
|
||||
|
||||
toAdd = new WebTransformOperations();
|
||||
toAdd->appendRotate(0, 0, 1, 0);
|
||||
operations->append(adoptPtr(toAdd));
|
||||
|
||||
toAdd = new WebTransformOperations();
|
||||
toAdd->appendRotate(0, 0, 1, 0);
|
||||
toAdd->appendRotate(0, 0, 1, 0);
|
||||
operations->append(adoptPtr(toAdd));
|
||||
|
||||
toAdd = new WebTransformOperations();
|
||||
toAdd->appendMatrix(WebTransformationMatrix());
|
||||
operations->append(adoptPtr(toAdd));
|
||||
|
||||
toAdd = new WebTransformOperations();
|
||||
toAdd->appendMatrix(WebTransformationMatrix());
|
||||
toAdd->appendMatrix(WebTransformationMatrix());
|
||||
operations->append(adoptPtr(toAdd));
|
||||
}
|
||||
|
||||
TEST(WebTransformOperationTest, identityAlwaysMatches)
|
||||
{
|
||||
Vector<OwnPtr<WebTransformOperations> > operations;
|
||||
getIdentityOperations(&operations);
|
||||
|
||||
for (size_t i = 0; i < operations.size(); ++i) {
|
||||
for (size_t j = 0; j < operations.size(); ++j)
|
||||
EXPECT_TRUE(operations[i]->matchesTypes(*operations[j]));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(WebTransformOperationTest, applyTranslate)
|
||||
{
|
||||
double x = 1;
|
||||
double y = 2;
|
||||
double z = 3;
|
||||
WebTransformOperations operations;
|
||||
operations.appendTranslate(x, y, z);
|
||||
WebTransformationMatrix expected;
|
||||
expected.translate3d(x, y, z);
|
||||
EXPECT_TRANSFORMATION_MATRIX_EQ(expected, operations.apply());
|
||||
}
|
||||
|
||||
TEST(WebTransformOperationTest, applyRotate)
|
||||
{
|
||||
double x = 1;
|
||||
double y = 2;
|
||||
double z = 3;
|
||||
double degrees = 80;
|
||||
WebTransformOperations operations;
|
||||
operations.appendRotate(x, y, z, degrees);
|
||||
WebTransformationMatrix expected;
|
||||
expected.rotate3d(x, y, z, degrees);
|
||||
EXPECT_TRANSFORMATION_MATRIX_EQ(expected, operations.apply());
|
||||
}
|
||||
|
||||
TEST(WebTransformOperationTest, applyScale)
|
||||
{
|
||||
double x = 1;
|
||||
double y = 2;
|
||||
double z = 3;
|
||||
WebTransformOperations operations;
|
||||
operations.appendScale(x, y, z);
|
||||
WebTransformationMatrix expected;
|
||||
expected.scale3d(x, y, z);
|
||||
EXPECT_TRANSFORMATION_MATRIX_EQ(expected, operations.apply());
|
||||
}
|
||||
|
||||
TEST(WebTransformOperationTest, applySkew)
|
||||
{
|
||||
double x = 1;
|
||||
double y = 2;
|
||||
WebTransformOperations operations;
|
||||
operations.appendSkew(x, y);
|
||||
WebTransformationMatrix expected;
|
||||
expected.skewX(x);
|
||||
expected.skewY(y);
|
||||
EXPECT_TRANSFORMATION_MATRIX_EQ(expected, operations.apply());
|
||||
}
|
||||
|
||||
TEST(WebTransformOperationTest, applyPerspective)
|
||||
{
|
||||
double depth = 800;
|
||||
WebTransformOperations operations;
|
||||
operations.appendPerspective(depth);
|
||||
WebTransformationMatrix expected;
|
||||
expected.applyPerspective(depth);
|
||||
EXPECT_TRANSFORMATION_MATRIX_EQ(expected, operations.apply());
|
||||
}
|
||||
|
||||
TEST(WebTransformOperationTest, applyMatrix)
|
||||
{
|
||||
double dx = 1;
|
||||
double dy = 2;
|
||||
double dz = 3;
|
||||
WebTransformationMatrix expectedMatrix;
|
||||
expectedMatrix.translate3d(dx, dy, dz);
|
||||
WebTransformOperations matrixTransform;
|
||||
matrixTransform.appendMatrix(expectedMatrix);
|
||||
EXPECT_TRANSFORMATION_MATRIX_EQ(expectedMatrix, matrixTransform.apply());
|
||||
}
|
||||
|
||||
TEST(WebTransformOperationTest, applyOrder)
|
||||
{
|
||||
double sx = 2;
|
||||
double sy = 4;
|
||||
double sz = 8;
|
||||
|
||||
double dx = 1;
|
||||
double dy = 2;
|
||||
double dz = 3;
|
||||
|
||||
WebTransformOperations operations;
|
||||
operations.appendScale(sx, sy, sz);
|
||||
operations.appendTranslate(dx, dy, dz);
|
||||
|
||||
WebTransformationMatrix expectedScaleMatrix;
|
||||
expectedScaleMatrix.scale3d(sx, sy, sz);
|
||||
|
||||
WebTransformationMatrix expectedTranslateMatrix;
|
||||
expectedTranslateMatrix.translate3d(dx, dy, dz);
|
||||
|
||||
WebTransformationMatrix expectedCombinedMatrix = expectedScaleMatrix;
|
||||
expectedCombinedMatrix.multiply(expectedTranslateMatrix);
|
||||
|
||||
EXPECT_TRANSFORMATION_MATRIX_EQ(expectedCombinedMatrix, operations.apply());
|
||||
}
|
||||
|
||||
TEST(WebTransformOperationTest, blendOrder)
|
||||
{
|
||||
double sx1 = 2;
|
||||
double sy1 = 4;
|
||||
double sz1 = 8;
|
||||
|
||||
double dx1 = 1;
|
||||
double dy1 = 2;
|
||||
double dz1 = 3;
|
||||
|
||||
double sx2 = 4;
|
||||
double sy2 = 8;
|
||||
double sz2 = 16;
|
||||
|
||||
double dx2 = 10;
|
||||
double dy2 = 20;
|
||||
double dz2 = 30;
|
||||
|
||||
WebTransformOperations operationsFrom;
|
||||
operationsFrom.appendScale(sx1, sy1, sz1);
|
||||
operationsFrom.appendTranslate(dx1, dy1, dz1);
|
||||
|
||||
WebTransformOperations operationsTo;
|
||||
operationsTo.appendScale(sx2, sy2, sz2);
|
||||
operationsTo.appendTranslate(dx2, dy2, dz2);
|
||||
|
||||
WebTransformationMatrix scaleFrom;
|
||||
scaleFrom.scale3d(sx1, sy1, sz1);
|
||||
WebTransformationMatrix translateFrom;
|
||||
translateFrom.translate3d(dx1, dy1, dz1);
|
||||
|
||||
WebTransformationMatrix scaleTo;
|
||||
scaleTo.scale3d(sx2, sy2, sz2);
|
||||
WebTransformationMatrix translateTo;
|
||||
translateTo.translate3d(dx2, dy2, dz2);
|
||||
|
||||
double progress = 0.25;
|
||||
|
||||
WebTransformationMatrix blendedScale = scaleTo;
|
||||
blendedScale.blend(scaleFrom, progress);
|
||||
|
||||
WebTransformationMatrix blendedTranslate = translateTo;
|
||||
blendedTranslate.blend(translateFrom, progress);
|
||||
|
||||
WebTransformationMatrix expected = blendedScale;
|
||||
expected.multiply(blendedTranslate);
|
||||
|
||||
EXPECT_TRANSFORMATION_MATRIX_EQ(expected, operationsTo.blend(operationsFrom, progress));
|
||||
}
|
||||
|
||||
static void checkProgress(double progress,
|
||||
const WebTransformationMatrix& fromMatrix,
|
||||
const WebTransformationMatrix& toMatrix,
|
||||
const WebTransformOperations& fromTransform,
|
||||
const WebTransformOperations& toTransform)
|
||||
{
|
||||
WebTransformationMatrix expectedMatrix = toMatrix;
|
||||
expectedMatrix.blend(fromMatrix, progress);
|
||||
EXPECT_TRANSFORMATION_MATRIX_EQ(expectedMatrix, toTransform.blend(fromTransform, progress));
|
||||
}
|
||||
|
||||
TEST(WebTransformOperationTest, blendProgress)
|
||||
{
|
||||
double sx = 2;
|
||||
double sy = 4;
|
||||
double sz = 8;
|
||||
WebTransformOperations operationsFrom;
|
||||
operationsFrom.appendScale(sx, sy, sz);
|
||||
|
||||
WebTransformationMatrix matrixFrom;
|
||||
matrixFrom.scale3d(sx, sy, sz);
|
||||
|
||||
sx = 4;
|
||||
sy = 8;
|
||||
sz = 16;
|
||||
WebTransformOperations operationsTo;
|
||||
operationsTo.appendScale(sx, sy, sz);
|
||||
|
||||
WebTransformationMatrix matrixTo;
|
||||
matrixTo.scale3d(sx, sy, sz);
|
||||
|
||||
checkProgress(-1, matrixFrom, matrixTo, operationsFrom, operationsTo);
|
||||
checkProgress(0, matrixFrom, matrixTo, operationsFrom, operationsTo);
|
||||
checkProgress(0.25, matrixFrom, matrixTo, operationsFrom, operationsTo);
|
||||
checkProgress(0.5, matrixFrom, matrixTo, operationsFrom, operationsTo);
|
||||
checkProgress(1, matrixFrom, matrixTo, operationsFrom, operationsTo);
|
||||
checkProgress(2, matrixFrom, matrixTo, operationsFrom, operationsTo);
|
||||
}
|
||||
|
||||
TEST(WebTransformOperationTest, blendWhenTypesDoNotMatch)
|
||||
{
|
||||
double sx1 = 2;
|
||||
double sy1 = 4;
|
||||
double sz1 = 8;
|
||||
|
||||
double dx1 = 1;
|
||||
double dy1 = 2;
|
||||
double dz1 = 3;
|
||||
|
||||
double sx2 = 4;
|
||||
double sy2 = 8;
|
||||
double sz2 = 16;
|
||||
|
||||
double dx2 = 10;
|
||||
double dy2 = 20;
|
||||
double dz2 = 30;
|
||||
|
||||
WebTransformOperations operationsFrom;
|
||||
operationsFrom.appendScale(sx1, sy1, sz1);
|
||||
operationsFrom.appendTranslate(dx1, dy1, dz1);
|
||||
|
||||
WebTransformOperations operationsTo;
|
||||
operationsTo.appendTranslate(dx2, dy2, dz2);
|
||||
operationsTo.appendScale(sx2, sy2, sz2);
|
||||
|
||||
WebTransformationMatrix from;
|
||||
from.scale3d(sx1, sy1, sz1);
|
||||
from.translate3d(dx1, dy1, dz1);
|
||||
|
||||
WebTransformationMatrix to;
|
||||
to.translate3d(dx2, dy2, dz2);
|
||||
to.scale3d(sx2, sy2, sz2);
|
||||
|
||||
double progress = 0.25;
|
||||
|
||||
WebTransformationMatrix expected = to;
|
||||
expected.blend(from, progress);
|
||||
|
||||
EXPECT_TRANSFORMATION_MATRIX_EQ(expected, operationsTo.blend(operationsFrom, progress));
|
||||
}
|
||||
|
||||
TEST(WebTransformOperationTest, largeRotationsWithSameAxis)
|
||||
{
|
||||
WebTransformOperations operationsFrom;
|
||||
operationsFrom.appendRotate(0, 0, 1, 0);
|
||||
|
||||
WebTransformOperations operationsTo;
|
||||
operationsTo.appendRotate(0, 0, 2, 360);
|
||||
|
||||
double progress = 0.5;
|
||||
|
||||
WebTransformationMatrix expected;
|
||||
expected.rotate3d(0, 0, 1, 180);
|
||||
|
||||
EXPECT_TRANSFORMATION_MATRIX_EQ(expected, operationsTo.blend(operationsFrom, progress));
|
||||
}
|
||||
|
||||
TEST(WebTransformOperationTest, largeRotationsWithSameAxisInDifferentDirection)
|
||||
{
|
||||
WebTransformOperations operationsFrom;
|
||||
operationsFrom.appendRotate(0, 0, 1, 180);
|
||||
|
||||
WebTransformOperations operationsTo;
|
||||
operationsTo.appendRotate(0, 0, -1, 180);
|
||||
|
||||
double progress = 0.5;
|
||||
|
||||
WebTransformationMatrix expected;
|
||||
|
||||
EXPECT_TRANSFORMATION_MATRIX_EQ(expected, operationsTo.blend(operationsFrom, progress));
|
||||
}
|
||||
|
||||
TEST(WebTransformOperationTest, largeRotationsWithDifferentAxes)
|
||||
{
|
||||
WebTransformOperations operationsFrom;
|
||||
operationsFrom.appendRotate(0, 0, 1, 180);
|
||||
|
||||
WebTransformOperations operationsTo;
|
||||
operationsTo.appendRotate(0, 1, 0, 180);
|
||||
|
||||
double progress = 0.5;
|
||||
WebTransformationMatrix matrixFrom;
|
||||
matrixFrom.rotate3d(0, 0, 1, 180);
|
||||
|
||||
WebTransformationMatrix matrixTo;
|
||||
matrixTo.rotate3d(0, 1, 0, 180);
|
||||
|
||||
WebTransformationMatrix expected = matrixTo;
|
||||
expected.blend(matrixFrom, progress);
|
||||
|
||||
EXPECT_TRANSFORMATION_MATRIX_EQ(expected, operationsTo.blend(operationsFrom, progress));
|
||||
}
|
||||
|
||||
TEST(WebTransformOperationTest, blendRotationFromIdentity)
|
||||
{
|
||||
Vector<OwnPtr<WebTransformOperations> > identityOperations;
|
||||
getIdentityOperations(&identityOperations);
|
||||
|
||||
for (size_t i = 0; i < identityOperations.size(); ++i) {
|
||||
WebTransformOperations operations;
|
||||
operations.appendRotate(0, 0, 1, 360);
|
||||
|
||||
double progress = 0.5;
|
||||
|
||||
WebTransformationMatrix expected;
|
||||
expected.rotate3d(0, 0, 1, 180);
|
||||
|
||||
EXPECT_TRANSFORMATION_MATRIX_EQ(expected, operations.blend(*identityOperations[i], progress));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(WebTransformOperationTest, blendTranslationFromIdentity)
|
||||
{
|
||||
Vector<OwnPtr<WebTransformOperations> > identityOperations;
|
||||
getIdentityOperations(&identityOperations);
|
||||
|
||||
for (size_t i = 0; i < identityOperations.size(); ++i) {
|
||||
WebTransformOperations operations;
|
||||
operations.appendTranslate(2, 2, 2);
|
||||
|
||||
double progress = 0.5;
|
||||
|
||||
WebTransformationMatrix expected;
|
||||
expected.translate3d(1, 1, 1);
|
||||
|
||||
EXPECT_TRANSFORMATION_MATRIX_EQ(expected, operations.blend(*identityOperations[i], progress));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(WebTransformOperationTest, blendScaleFromIdentity)
|
||||
{
|
||||
Vector<OwnPtr<WebTransformOperations> > identityOperations;
|
||||
getIdentityOperations(&identityOperations);
|
||||
|
||||
for (size_t i = 0; i < identityOperations.size(); ++i) {
|
||||
WebTransformOperations operations;
|
||||
operations.appendScale(3, 3, 3);
|
||||
|
||||
double progress = 0.5;
|
||||
|
||||
WebTransformationMatrix expected;
|
||||
expected.scale3d(2, 2, 2);
|
||||
|
||||
EXPECT_TRANSFORMATION_MATRIX_EQ(expected, operations.blend(*identityOperations[i], progress));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(WebTransformOperationTest, blendSkewFromIdentity)
|
||||
{
|
||||
Vector<OwnPtr<WebTransformOperations> > identityOperations;
|
||||
getIdentityOperations(&identityOperations);
|
||||
|
||||
for (size_t i = 0; i < identityOperations.size(); ++i) {
|
||||
WebTransformOperations operations;
|
||||
operations.appendSkew(2, 2);
|
||||
|
||||
double progress = 0.5;
|
||||
|
||||
WebTransformationMatrix expected;
|
||||
expected.skewX(1);
|
||||
expected.skewY(1);
|
||||
|
||||
EXPECT_TRANSFORMATION_MATRIX_EQ(expected, operations.blend(*identityOperations[i], progress));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(WebTransformOperationTest, blendPerspectiveFromIdentity)
|
||||
{
|
||||
Vector<OwnPtr<WebTransformOperations> > identityOperations;
|
||||
getIdentityOperations(&identityOperations);
|
||||
|
||||
for (size_t i = 0; i < identityOperations.size(); ++i) {
|
||||
WebTransformOperations operations;
|
||||
operations.appendPerspective(1000);
|
||||
|
||||
double progress = 0.5;
|
||||
|
||||
WebTransformationMatrix expected;
|
||||
expected.applyPerspective(500 + 0.5 * numeric_limits<double>::max());
|
||||
|
||||
EXPECT_TRANSFORMATION_MATRIX_EQ(expected, operations.blend(*identityOperations[i], progress));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(WebTransformOperationTest, blendRotationToIdentity)
|
||||
{
|
||||
Vector<OwnPtr<WebTransformOperations> > identityOperations;
|
||||
getIdentityOperations(&identityOperations);
|
||||
|
||||
for (size_t i = 0; i < identityOperations.size(); ++i) {
|
||||
WebTransformOperations operations;
|
||||
operations.appendRotate(0, 0, 1, 360);
|
||||
|
||||
double progress = 0.5;
|
||||
|
||||
WebTransformationMatrix expected;
|
||||
expected.rotate3d(0, 0, 1, 180);
|
||||
|
||||
EXPECT_TRANSFORMATION_MATRIX_EQ(expected, identityOperations[i]->blend(operations, progress));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(WebTransformOperationTest, blendTranslationToIdentity)
|
||||
{
|
||||
Vector<OwnPtr<WebTransformOperations> > identityOperations;
|
||||
getIdentityOperations(&identityOperations);
|
||||
|
||||
for (size_t i = 0; i < identityOperations.size(); ++i) {
|
||||
WebTransformOperations operations;
|
||||
operations.appendTranslate(2, 2, 2);
|
||||
|
||||
double progress = 0.5;
|
||||
|
||||
WebTransformationMatrix expected;
|
||||
expected.translate3d(1, 1, 1);
|
||||
|
||||
EXPECT_TRANSFORMATION_MATRIX_EQ(expected, identityOperations[i]->blend(operations, progress));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(WebTransformOperationTest, blendScaleToIdentity)
|
||||
{
|
||||
Vector<OwnPtr<WebTransformOperations> > identityOperations;
|
||||
getIdentityOperations(&identityOperations);
|
||||
|
||||
for (size_t i = 0; i < identityOperations.size(); ++i) {
|
||||
WebTransformOperations operations;
|
||||
operations.appendScale(3, 3, 3);
|
||||
|
||||
double progress = 0.5;
|
||||
|
||||
WebTransformationMatrix expected;
|
||||
expected.scale3d(2, 2, 2);
|
||||
|
||||
EXPECT_TRANSFORMATION_MATRIX_EQ(expected, identityOperations[i]->blend(operations, progress));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(WebTransformOperationTest, blendSkewToIdentity)
|
||||
{
|
||||
Vector<OwnPtr<WebTransformOperations> > identityOperations;
|
||||
getIdentityOperations(&identityOperations);
|
||||
|
||||
for (size_t i = 0; i < identityOperations.size(); ++i) {
|
||||
WebTransformOperations operations;
|
||||
operations.appendSkew(2, 2);
|
||||
|
||||
double progress = 0.5;
|
||||
|
||||
WebTransformationMatrix expected;
|
||||
expected.skewX(1);
|
||||
expected.skewY(1);
|
||||
|
||||
EXPECT_TRANSFORMATION_MATRIX_EQ(expected, identityOperations[i]->blend(operations, progress));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(WebTransformOperationTest, blendPerspectiveToIdentity)
|
||||
{
|
||||
Vector<OwnPtr<WebTransformOperations> > identityOperations;
|
||||
getIdentityOperations(&identityOperations);
|
||||
|
||||
for (size_t i = 0; i < identityOperations.size(); ++i) {
|
||||
WebTransformOperations operations;
|
||||
operations.appendPerspective(1000);
|
||||
|
||||
double progress = 0.5;
|
||||
|
||||
WebTransformationMatrix expected;
|
||||
expected.applyPerspective(500 + 0.5 * numeric_limits<double>::max());
|
||||
|
||||
EXPECT_TRANSFORMATION_MATRIX_EQ(expected, identityOperations[i]->blend(operations, progress));
|
||||
}
|
||||
}
|
||||
|
1305
webkit/compositor/WebTransformationMatrixTest.cpp
Normal file
1305
webkit/compositor/WebTransformationMatrixTest.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -52,21 +52,21 @@
|
||||
'target_name': 'webkit_compositor',
|
||||
'type': 'static_library',
|
||||
'dependencies': [
|
||||
'<(DEPTH)/base/base.gyp:base',
|
||||
'<(DEPTH)/cc/cc.gyp:cc',
|
||||
'<(DEPTH)/skia/skia.gyp:skia',
|
||||
'<(DEPTH)/third_party/WebKit/Source/Platform/Platform.gyp/Platform.gyp:webkit_platform',
|
||||
'../../base/base.gyp:base',
|
||||
'../../cc/cc.gyp:cc',
|
||||
'../../skia/skia.gyp:skia',
|
||||
'../../third_party/WebKit/Source/Platform/Platform.gyp/Platform.gyp:webkit_platform',
|
||||
# We have to depend on WTF directly to pick up the correct defines for WTF headers - for instance USE_SYSTEM_MALLOC.
|
||||
'<(DEPTH)/third_party/WebKit/Source/WTF/WTF.gyp/WTF.gyp:wtf',
|
||||
'../../third_party/WebKit/Source/WTF/WTF.gyp/WTF.gyp:wtf',
|
||||
],
|
||||
'defines': [
|
||||
'WEBKIT_IMPLEMENTATION=1',
|
||||
],
|
||||
'include_dirs': [
|
||||
'<(DEPTH)/cc',
|
||||
'<(DEPTH)/cc/stubs',
|
||||
'../../cc',
|
||||
'../../cc/stubs',
|
||||
'stubs',
|
||||
'<(DEPTH)/third_party/WebKit/Source/WebKit/chromium/public',
|
||||
'../../third_party/WebKit/Source/WebKit/chromium/public',
|
||||
],
|
||||
'sources': [
|
||||
'<@(webkit_compositor_sources)',
|
||||
|
@ -7,8 +7,23 @@
|
||||
'chromium_code': 0,
|
||||
'use_libcc_for_compositor%': 0,
|
||||
'webkit_compositor_tests_sources': [
|
||||
'LayerChromiumTest.cpp',
|
||||
'TextureCopierTest.cpp',
|
||||
'TextureLayerChromiumTest.cpp',
|
||||
'ThrottledTextureUploaderTest.cpp',
|
||||
'TiledLayerChromiumTest.cpp',
|
||||
'TreeSynchronizerTest.cpp',
|
||||
'WebAnimationTest.cpp',
|
||||
'WebFloatAnimationCurveTest.cpp',
|
||||
'WebFloatAnimationCurveTest.cpp',
|
||||
'WebLayerTest.cpp',
|
||||
'WebLayerTreeViewTest.cpp',
|
||||
'WebTransformAnimationCurveTest.cpp',
|
||||
'WebTransformAnimationCurveTest.cpp',
|
||||
'WebTransformOperationsTest.cpp',
|
||||
'WebTransformationMatrixTest.cpp',
|
||||
'test/FakeWebScrollbarThemeGeometry.h',
|
||||
'test/WebLayerTreeViewTestCommon.h',
|
||||
],
|
||||
},
|
||||
'conditions': [
|
||||
@ -18,19 +33,23 @@
|
||||
'target_name': 'webkit_compositor_unittests',
|
||||
'type' : 'executable',
|
||||
'dependencies': [
|
||||
'<(DEPTH)/base/base.gyp:test_support_base',
|
||||
'<(DEPTH)/cc/cc.gyp:cc',
|
||||
'<(DEPTH)/testing/gmock.gyp:gmock',
|
||||
'<(DEPTH)/testing/gtest.gyp:gtest',
|
||||
'<(DEPTH)/third_party/WebKit/Source/Platform/Platform.gyp/Platform.gyp:webkit_platform',
|
||||
'<(DEPTH)/third_party/WebKit/Source/WTF/WTF.gyp/WTF.gyp:wtf',
|
||||
'<(DEPTH)/webkit/support/webkit_support.gyp:webkit_support',
|
||||
'../../base/base.gyp:test_support_base',
|
||||
'../../cc/cc.gyp:cc',
|
||||
'../../cc/cc_tests.gyp:cc_test_support',
|
||||
'../../skia/skia.gyp:skia',
|
||||
'../../testing/gmock.gyp:gmock',
|
||||
'../../testing/gtest.gyp:gtest',
|
||||
'../../third_party/WebKit/Source/Platform/Platform.gyp/Platform.gyp:webkit_platform',
|
||||
'../../third_party/WebKit/Source/WTF/WTF.gyp/WTF.gyp:wtf',
|
||||
'../../webkit/support/webkit_support.gyp:webkit_support',
|
||||
'compositor.gyp:webkit_compositor',
|
||||
],
|
||||
'include_dirs': [
|
||||
'.',
|
||||
'test',
|
||||
'<(DEPTH)/cc',
|
||||
'<(DEPTH)/cc/stubs',
|
||||
'<(DEPTH)/cc/test',
|
||||
],
|
||||
'sources': [
|
||||
'<@(webkit_compositor_tests_sources)',
|
||||
|
@ -15,6 +15,8 @@ def Copy(name):
|
||||
src = name
|
||||
dst = name
|
||||
fullsrc = ""
|
||||
if name.startswith("test/"):
|
||||
src = src[5:]
|
||||
for prefix in prefixes:
|
||||
candidate = "%s/%s" % (prefix, src)
|
||||
if os.path.exists(candidate):
|
||||
|
48
webkit/compositor/test/FakeWebScrollbarThemeGeometry.h
Normal file
48
webkit/compositor/test/FakeWebScrollbarThemeGeometry.h
Normal file
@ -0,0 +1,48 @@
|
||||
// Copyright 2012 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef FakeWebScrollbarThemeGeometry_h
|
||||
#define FakeWebScrollbarThemeGeometry_h
|
||||
|
||||
#include <public/WebScrollbarThemeGeometry.h>
|
||||
#include <wtf/PassOwnPtr.h>
|
||||
|
||||
namespace WebKit {
|
||||
|
||||
class FakeWebScrollbarThemeGeometry : public WebKit::WebScrollbarThemeGeometry {
|
||||
public:
|
||||
static PassOwnPtr<WebKit::WebScrollbarThemeGeometry> create() { return adoptPtr(new WebKit::FakeWebScrollbarThemeGeometry()); }
|
||||
|
||||
virtual WebKit::WebScrollbarThemeGeometry* clone() const OVERRIDE
|
||||
{
|
||||
return new FakeWebScrollbarThemeGeometry();
|
||||
}
|
||||
|
||||
virtual int thumbPosition(WebScrollbar*) OVERRIDE { return 0; }
|
||||
virtual int thumbLength(WebScrollbar*) OVERRIDE { return 0; }
|
||||
virtual int trackPosition(WebScrollbar*) OVERRIDE { return 0; }
|
||||
virtual int trackLength(WebScrollbar*) OVERRIDE { return 0; }
|
||||
virtual bool hasButtons(WebScrollbar*) OVERRIDE { return false; }
|
||||
virtual bool hasThumb(WebScrollbar*) OVERRIDE { return false; }
|
||||
virtual WebRect trackRect(WebScrollbar*) OVERRIDE { return WebRect(); }
|
||||
virtual WebRect thumbRect(WebScrollbar*) OVERRIDE { return WebRect(); }
|
||||
virtual int minimumThumbLength(WebScrollbar*) OVERRIDE { return 0; }
|
||||
virtual int scrollbarThickness(WebScrollbar*) OVERRIDE { return 0; }
|
||||
virtual WebRect backButtonStartRect(WebScrollbar*) OVERRIDE { return WebRect(); }
|
||||
virtual WebRect backButtonEndRect(WebScrollbar*) OVERRIDE { return WebRect(); }
|
||||
virtual WebRect forwardButtonStartRect(WebScrollbar*) OVERRIDE { return WebRect(); }
|
||||
virtual WebRect forwardButtonEndRect(WebScrollbar*) OVERRIDE { return WebRect(); }
|
||||
virtual WebRect constrainTrackRectToTrackPieces(WebScrollbar*, const WebRect&) OVERRIDE { return WebRect(); }
|
||||
|
||||
virtual void splitTrack(WebScrollbar*, const WebRect& track, WebRect& startTrack, WebRect& thumb, WebRect& endTrack) OVERRIDE
|
||||
{
|
||||
startTrack = WebRect();
|
||||
thumb = WebRect();
|
||||
endTrack = WebRect();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace WebKit
|
||||
|
||||
#endif // FakeWebScrollbarThemeGeometry_h
|
38
webkit/compositor/test/WebLayerTreeViewTestCommon.h
Normal file
38
webkit/compositor/test/WebLayerTreeViewTestCommon.h
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright 2012 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef WebLayerTreeViewTestCommon_h
|
||||
#define WebLayerTreeViewTestCommon_h
|
||||
|
||||
#include "CompositorFakeWebGraphicsContext3D.h"
|
||||
#include "FakeWebCompositorOutputSurface.h"
|
||||
#include <gmock/gmock.h>
|
||||
#include <public/WebLayerTreeViewClient.h>
|
||||
|
||||
namespace WebKit {
|
||||
|
||||
class MockWebLayerTreeViewClient : public WebLayerTreeViewClient {
|
||||
public:
|
||||
MOCK_METHOD0(scheduleComposite, void());
|
||||
virtual void updateAnimations(double frameBeginTime) OVERRIDE { }
|
||||
MOCK_METHOD0(willBeginFrame, void());
|
||||
MOCK_METHOD0(didBeginFrame, void());
|
||||
virtual void layout() OVERRIDE { }
|
||||
virtual void applyScrollAndScale(const WebSize& scrollDelta, float scaleFactor) OVERRIDE { }
|
||||
|
||||
virtual WebCompositorOutputSurface* createOutputSurface() OVERRIDE
|
||||
{
|
||||
return FakeWebCompositorOutputSurface::create(CompositorFakeWebGraphicsContext3D::create(WebGraphicsContext3D::Attributes())).leakPtr();
|
||||
}
|
||||
virtual void didRecreateOutputSurface(bool) OVERRIDE { }
|
||||
|
||||
MOCK_METHOD0(willCommit, void());
|
||||
MOCK_METHOD0(didCommit, void());
|
||||
virtual void didCommitAndDrawFrame() OVERRIDE { }
|
||||
virtual void didCompleteSwapBuffers() OVERRIDE { }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // WebLayerTreeViewTestCommon_h
|
Reference in New Issue
Block a user