Changeset 96066 in webkit
- Timestamp:
- Sep 26, 2011 7:18:14 PM (13 years ago)
- Location:
- trunk/Source
- Files:
-
- 17 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r96064 r96066 1 2011-09-26 Nat Duca <nduca@chromium.org> 2 3 [chromium] Make CCThreadProxy draw 4 https://bugs.webkit.org/show_bug.cgi?id=67417 5 6 Update the CCThreadProxy to correctly implement the CCProxy 7 interface, do all the right committing and updating steps, and 8 draw a picture on the screen. 9 10 Reviewed by James Robinson. 11 12 * platform/graphics/IntRect.h: 13 * platform/graphics/chromium/LayerRendererChromium.cpp: 14 (WebCore::LayerRendererChromium::~LayerRendererChromium): 15 * platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp: 16 (WebCore::CCHeadsUpDisplay::enabled): 17 * platform/graphics/chromium/cc/CCLayerImpl.cpp: 18 (WebCore::CCLayerImpl::CCLayerImpl): 19 (WebCore::CCLayerImpl::~CCLayerImpl): 20 * platform/graphics/chromium/cc/CCLayerTreeHost.cpp: 21 (WebCore::CCLayerTreeHost::CCLayerTreeHost): 22 (WebCore::CCLayerTreeHost::commitTo): 23 (WebCore::CCLayerTreeHost::commitComplete): 24 (WebCore::CCLayerTreeHost::setNeedsRedraw): 25 * platform/graphics/chromium/cc/CCLayerTreeHost.h: 26 * platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp: 27 (WebCore::CCLayerTreeHostImpl::CCLayerTreeHostImpl): 28 (WebCore::CCLayerTreeHostImpl::~CCLayerTreeHostImpl): 29 * platform/graphics/chromium/cc/CCSingleThreadProxy.cpp: 30 (WebCore::CCSingleThreadProxy::finishAllRendering): 31 (WebCore::CCSingleThreadProxy::setNeedsCommit): 32 (WebCore::CCSingleThreadProxy::commitIfNeeded): 33 * platform/graphics/chromium/cc/CCThreadProxy.cpp: 34 (WebCore::CCThreadProxy::CCThreadProxy): 35 (WebCore::CCThreadProxy::~CCThreadProxy): 36 (WebCore::CCThreadProxy::compositeAndReadback): 37 (WebCore::CCThreadProxy::drawLayersAndReadbackOnCCThread): 38 (WebCore::CCThreadProxy::finishAllRendering): 39 (WebCore::CCThreadProxy::isStarted): 40 (WebCore::CCThreadProxy::setNeedsCommit): 41 (WebCore::CCThreadProxy::setNeedsCommitAndRedraw): 42 (WebCore::CCThreadProxy::setNeedsRedraw): 43 (WebCore::CCThreadProxy::start): 44 (WebCore::CCThreadProxy::stop): 45 (WebCore::CCThreadProxy::finishAllRenderingOnCCThread): 46 (WebCore::CCThreadProxy::createBeginFrameAndCommitTaskOnCCThread): 47 (WebCore::CCThreadProxy::beginFrameAndCommit): 48 (WebCore::CCThreadProxy::commitOnCCThread): 49 (WebCore::CCThreadProxy::scheduleDrawTaskOnCCThread): 50 (WebCore::CCThreadProxy::drawLayersAndPresentOnCCThread): 51 (WebCore::CCThreadProxy::drawLayersOnCCThread): 52 (WebCore::CCThreadProxy::updateSchedulerStateOnCCThread): 53 * platform/graphics/chromium/cc/CCThreadProxy.h: 54 1 55 2011-09-26 Adam Klein <adamk@chromium.org> 2 56 -
trunk/Source/WebCore/platform/CrossThreadCopier.h
r95702 r96066 42 42 namespace WebCore { 43 43 44 class IntRect; 44 45 class KURL; 45 46 class ResourceError; … … 64 65 }; 65 66 67 // To allow a type to be passed across threads using its copy constructor, add a forward declaration of the type and 68 // a CopyThreadCopierBase<false, false, TypeName> : public CrossThreadCopierPassThrough<TypeName> { }; to this file. 66 69 template<> struct CrossThreadCopierBase<false, false, ThreadableLoaderOptions> : public CrossThreadCopierPassThrough<ThreadableLoaderOptions> { 70 }; 71 72 template<> struct CrossThreadCopierBase<false, false, IntRect> : public CrossThreadCopierPassThrough<IntRect> { 67 73 }; 68 74 -
trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
r95988 r96066 182 182 LayerRendererChromium::~LayerRendererChromium() 183 183 { 184 ASSERT(CCProxy::isImplThread 185 ()); 184 186 m_headsUpDisplay.clear(); // Explicitly destroy the HUD before the TextureManager dies. 185 187 cleanupSharedObjects(); -
trunk/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp
r95901 r96066 90 90 bool CCHeadsUpDisplay::enabled() const 91 91 { 92 // FIXME: HUD does not work in compositor thread mode. 93 if (settings().enableCompositorThread) 94 return false; 92 95 return settings().showPlatformLayerTree || settings().showFPSCounter; 93 96 } -
trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp
r95901 r96066 56 56 , m_debugBorderWidth(0) 57 57 { 58 ASSERT(CCProxy::isImplThread()); 58 59 } 59 60 60 61 CCLayerImpl::~CCLayerImpl() 61 62 { 63 ASSERT(CCProxy::isImplThread()); 62 64 } 63 65 -
trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp
r95988 r96066 56 56 , m_visible(true) 57 57 { 58 ASSERT(CCProxy::isMainThread()); 58 59 } 59 60 … … 63 64 // Accelerated Painting is not supported in threaded mode. Turn it off. 64 65 m_settings.acceleratePainting = false; 66 // The HUD does not work in threaded mode. Turn it off. 67 m_settings.showFPSCounter = false; 68 m_settings.showPlatformLayerTree = false; 69 65 70 m_proxy = CCThreadProxy::create(this); 66 71 } else … … 106 111 } 107 112 113 // This function commits the CCLayerTreeHost to an impl tree. When modifying 114 // this function, keep in mind that the function *runs* on the impl thread! Any 115 // code that is logically a main thread operation, e.g. deletion of a LayerChromium, 116 // should be delayed until the CCLayerTreeHost::commitComplete, which will run 117 // after the commit, but on the main thread. 108 118 void CCLayerTreeHost::commitTo(CCLayerTreeHostImpl* hostImpl) 109 119 { … … 116 126 117 127 updateCompositorResources(m_updateList, hostImpl->context()); 118 clearPendingUpdate();119 128 120 129 hostImpl->setVisible(m_visible); … … 123 132 124 133 hostImpl->layerRenderer()->setContentsTextureMemoryUseBytes(m_contentsTextureManager->currentMemoryUseBytes()); 125 m_contentsTextureManager->unprotectAllTextures();126 134 127 135 // Synchronize trees, if one exists at all... … … 132 140 133 141 m_frameNumber++; 142 } 143 144 void CCLayerTreeHost::commitComplete() 145 { 146 clearPendingUpdate(); 147 m_contentsTextureManager->unprotectAllTextures(); 134 148 } 135 149 … … 210 224 { 211 225 #if USE(THREADED_COMPOSITING) 212 TRACE_EVENT("CCLayerTreeHost::setNeedsRedraw", this, 0);213 226 m_proxy->setNeedsRedraw(); 214 227 #else -
trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h
r95988 r96066 98 98 // CCLayerTreeHost interface to CCProxy. 99 99 void animateAndLayout(double frameBeginTime); 100 void commitComplete(); 100 101 void commitTo(CCLayerTreeHostImpl*); 101 102 PassOwnPtr<CCThread> createCompositorThread(); -
trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp
r95988 r96066 49 49 , m_settings(settings) 50 50 { 51 ASSERT(CCProxy::isImplThread()); 51 52 } 52 53 53 54 CCLayerTreeHostImpl::~CCLayerTreeHostImpl() 54 55 { 56 ASSERT(CCProxy::isImplThread()); 55 57 TRACE_EVENT("CCLayerTreeHostImpl::~CCLayerTreeHostImpl()", this, 0); 56 58 if (m_layerRenderer) -
trunk/Source/WebCore/platform/graphics/chromium/cc/CCProxy.cpp
r95901 r96066 38 38 39 39 #ifndef NDEBUG 40 bool CCProxy::isMainThread()41 {42 return ::isMainThread();43 }44 40 45 41 namespace { 46 42 bool fakeImplThread = false; 47 43 static WTF::ThreadIdentifier implThreadID; 44 } 45 46 bool CCProxy::isMainThread() 47 { 48 return ::isMainThread() && !fakeImplThread; 48 49 } 49 50 -
trunk/Source/WebCore/platform/graphics/chromium/cc/CCProxy.h
r95901 r96066 76 76 #endif 77 77 78 // Temporary hack while render_widget still does scheduling for CCLayerTreeHostMainThreadI 79 virtual GraphicsContext3D* context() = 0; 80 78 81 // Testing hooks 79 82 virtual void loseCompositorContext(int numTimes) = 0; 80 83 81 // Temporary hack while render_widget still does scheduling for CCLayerTreeHostMainThreadI 82 virtual GraphicsContext3D* context() = 0; 84 #ifndef NDEBUG 85 static void setImplThread(bool); 86 static void setImplThread(WTF::ThreadIdentifier); 87 #endif 83 88 84 89 protected: 85 90 CCProxy() { } 86 91 friend class ScopedSetImplThread; 87 #ifndef NDEBUG88 static void setImplThread(bool);89 static void setImplThread(WTF::ThreadIdentifier);90 #endif91 92 }; 92 93 -
trunk/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.cpp
r95901 r96066 43 43 { 44 44 #ifndef NDEBUG 45 ASSERT(CCProxy::isMainThread()); 45 46 CCProxy::setImplThread(true); 46 47 #endif … … 66 67 { 67 68 TRACE_EVENT("CCSingleThreadProxy::CCSingleThreadProxy", this, 0); 68 ASSERT( isMainThread());69 ASSERT(CCProxy::isMainThread()); 69 70 } 70 71 … … 78 79 { 79 80 TRACE_EVENT("CCSingleThreadProxy::~CCSingleThreadProxy", this, 0); 80 ASSERT( isMainThread());81 ASSERT(CCProxy::isMainThread()); 81 82 ASSERT(!m_layerTreeHostImpl && !m_layerTreeHost); // make sure stop() got called. 82 83 } … … 84 85 bool CCSingleThreadProxy::compositeAndReadback(void *pixels, const IntRect& rect) 85 86 { 86 ASSERT( isMainThread());87 ASSERT(CCProxy::isMainThread()); 87 88 88 89 if (!recreateContextIfNeeded()) … … 104 105 GraphicsContext3D* CCSingleThreadProxy::context() 105 106 { 106 ASSERT( isMainThread());107 ASSERT(CCProxy::isMainThread()); 107 108 ScopedSetImplThread impl; 108 109 return m_layerTreeHostImpl->context(); … … 111 112 void CCSingleThreadProxy::finishAllRendering() 112 113 { 113 ASSERT(isMainThread()); 114 ScopedSetImplThread impl; 115 m_layerTreeHostImpl->finishAllRendering(); 114 ASSERT(CCProxy::isMainThread()); 115 { 116 ScopedSetImplThread impl; 117 m_layerTreeHostImpl->finishAllRendering(); 118 } 116 119 } 117 120 118 121 bool CCSingleThreadProxy::isStarted() const 119 122 { 120 ASSERT( isMainThread());123 ASSERT(CCProxy::isMainThread()); 121 124 return m_layerTreeHostImpl; 122 125 } … … 124 127 bool CCSingleThreadProxy::initializeLayerRenderer() 125 128 { 126 ASSERT( isMainThread());129 ASSERT(CCProxy::isMainThread()); 127 130 RefPtr<GraphicsContext3D> context = m_layerTreeHost->createLayerTreeHostContext3D(); 128 131 if (!context) … … 132 135 { 133 136 ScopedSetImplThread impl; 134 return m_layerTreeHostImpl->initializeLayerRenderer(context); 137 bool ok = m_layerTreeHostImpl->initializeLayerRenderer(context); 138 if (ok) 139 m_layerRendererCapabilitiesForMainThread = m_layerTreeHostImpl->layerRendererCapabilities(); 140 return ok; 135 141 } 136 142 } … … 138 144 const LayerRendererCapabilities& CCSingleThreadProxy::layerRendererCapabilities() const 139 145 { 140 ScopedSetImplThread impl;141 return m_layer TreeHostImpl->layerRendererCapabilities();146 // Note: this gets called during the commit by the "impl" thread 147 return m_layerRendererCapabilitiesForMainThread; 142 148 } 143 149 … … 150 156 void CCSingleThreadProxy::setNeedsCommit() 151 157 { 152 ASSERT( isMainThread());158 ASSERT(CCProxy::isMainThread()); 153 159 // Commit immediately 154 160 { … … 158 164 m_layerTreeHostImpl->commitComplete(); 159 165 } 166 m_layerTreeHost->commitComplete(); 160 167 } 161 168 162 169 void CCSingleThreadProxy::setNeedsCommitAndRedraw() 163 170 { 164 ASSERT( isMainThread());171 ASSERT(CCProxy::isMainThread()); 165 172 #if !USE(THREADED_COMPOSITING) 166 173 m_layerTreeHost->scheduleComposite(); … … 181 188 { 182 189 TRACE_EVENT("CCSingleThreadProxy::stop", this, 0); 183 ASSERT( isMainThread());190 ASSERT(CCProxy::isMainThread()); 184 191 { 185 192 ScopedSetImplThread impl; … … 207 214 bool CCSingleThreadProxy::recreateContextIfNeeded() 208 215 { 209 ASSERT( isMainThread());216 ASSERT(CCProxy::isMainThread()); 210 217 if (!m_graphicsContextLost) 211 218 return true; … … 218 225 if (context) { 219 226 ASSERT(context->hasOneRef()); 220 if (m_layerTreeHostImpl->initializeLayerRenderer(context)) { 227 bool ok; 228 { 229 ScopedSetImplThread impl; 230 ok = m_layerTreeHostImpl->initializeLayerRenderer(context); 231 if (ok) 232 m_layerRendererCapabilitiesForMainThread = m_layerTreeHostImpl->layerRendererCapabilities(); 233 } 234 if (ok) { 221 235 m_layerTreeHost->didRecreateGraphicsContext(true); 222 236 m_graphicsContextLost = false; … … 241 255 void CCSingleThreadProxy::commitIfNeeded() 242 256 { 257 ASSERT(CCProxy::isMainThread()); 258 243 259 // Update 244 260 m_layerTreeHost->updateLayers(); … … 251 267 m_layerTreeHostImpl->commitComplete(); 252 268 } 269 m_layerTreeHost->commitComplete(); 253 270 } 254 271 -
trunk/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.h
r95901 r96066 70 70 // Used on the CCThread, but checked on main thread during initialization/shutdown. 71 71 OwnPtr<CCLayerTreeHostImpl> m_layerTreeHostImpl; 72 LayerRendererCapabilities m_layerRendererCapabilitiesForMainThread; 72 73 73 74 int m_numFailedRecreateAttempts; -
trunk/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.cpp
r95901 r96066 32 32 #include "cc/CCMainThreadTask.h" 33 33 #include "cc/CCThreadTask.h" 34 #include <wtf/CurrentTime.h> 34 35 #include <wtf/MainThread.h> 35 36 … … 49 50 50 51 CCThreadProxy::CCThreadProxy(CCLayerTreeHost* layerTreeHost) 51 : m_commit Pending(false)52 : m_commitRequested(false) 52 53 , m_layerTreeHost(layerTreeHost) 54 , m_started(false) 55 , m_lastExecutedBeginFrameAndCommitSequenceNumber(-1) 56 , m_numBeginFrameAndCommitsIssuedOnCCThread(0) 57 , m_beginFrameAndCommitPendingOnCCThread(false) 58 , m_drawTaskPostedOnCCThread(false) 59 , m_redrawRequestedOnCCThread(false) 53 60 { 54 61 TRACE_EVENT("CCThreadProxy::CCThreadProxy", this, 0); … … 67 74 TRACE_EVENT("CCThreadProxy::~CCThreadProxy", this, 0); 68 75 ASSERT(isMainThread()); 69 ASSERT(!m_layerTreeHostImpl); // Make sure stop() got called. 70 ASSERT(!m_layerTreeHost); // Make sure stop() got called. 76 ASSERT(!m_started); 71 77 72 78 numProxies--; … … 79 85 bool CCThreadProxy::compositeAndReadback(void *pixels, const IntRect& rect) 80 86 { 81 ASSERT_NOT_REACHED(); 82 return false; 87 ASSERT(isMainThread()); 88 ASSERT(m_layerTreeHost); 89 90 // If a commit is pending, perform the commit first. 91 if (m_commitRequested) { 92 // This bit of code is uglier than it should be because returning 93 // pointers via the CCThread task model is really messy. Effectively, we 94 // are making a blocking call to createBeginFrameAndCommitTaskOnCCThread, 95 // and trying to get the CCMainThread::Task it returns so we can run it. 96 OwnPtr<CCMainThread::Task> beginFrameAndCommitTask; 97 { 98 CCMainThread::Task* taskPtr = 0; 99 CCCompletionEvent completion; 100 ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::obtainBeginFrameAndCommitTaskFromCCThread, AllowCrossThreadAccess(&completion), AllowCrossThreadAccess(&taskPtr))); 101 completion.wait(); 102 beginFrameAndCommitTask = adoptPtr(taskPtr); 103 } 104 105 beginFrameAndCommitTask->performTask(); 106 } 107 108 // Draw using the new tree and read back the results. 109 bool success = false; 110 CCCompletionEvent completion; 111 ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::drawLayersAndReadbackOnCCThread, AllowCrossThreadAccess(&completion), AllowCrossThreadAccess(&success), AllowCrossThreadAccess(pixels), rect)); 112 completion.wait(); 113 return success; 114 } 115 116 void CCThreadProxy::drawLayersAndReadbackOnCCThread(CCCompletionEvent* completion, bool* success, void* pixels, const IntRect& rect) 117 { 118 ASSERT(CCProxy::isImplThread()); 119 if (!m_layerTreeHostImpl) { 120 *success = false; 121 completion->signal(); 122 return; 123 } 124 drawLayersOnCCThread(); 125 m_layerTreeHostImpl->readback(pixels, rect); 126 *success = m_layerTreeHostImpl->isContextLost(); 127 completion->signal(); 83 128 } 84 129 … … 90 135 void CCThreadProxy::finishAllRendering() 91 136 { 92 ASSERT_NOT_REACHED(); 137 ASSERT(CCProxy::isMainThread()); 138 139 // Make sure all GL drawing is finished on the impl thread. 140 CCCompletionEvent completion; 141 ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::finishAllRenderingOnCCThread, AllowCrossThreadAccess(&completion))); 142 completion.wait(); 93 143 } 94 144 95 145 bool CCThreadProxy::isStarted() const 96 146 { 97 return m_layerTreeHostImpl; 147 ASSERT(CCProxy::isMainThread()); 148 return m_started; 98 149 } 99 150 … … 112 163 // are pushed into the initializeSucceeded and capabilities local variables. 113 164 CCCompletionEvent completion; 114 bool initializeSucceeded ;165 bool initializeSucceeded = false; 115 166 LayerRendererCapabilities capabilities; 116 167 ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::initializeLayerRendererOnCCThread, … … 136 187 { 137 188 ASSERT(isMainThread()); 138 if (m_commit Pending)189 if (m_commitRequested) 139 190 return; 140 191 141 192 TRACE_EVENT("CCThreadProxy::setNeedsCommit", this, 0); 142 m_commit Pending= true;143 ccThread->postTask(createCCThreadTask(this, &CCThreadProxy:: setNeedsCommitOnCCThread));193 m_commitRequested = true; 194 ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::updateSchedulerStateOnCCThread, m_commitRequested, true)); 144 195 } 145 196 … … 147 198 { 148 199 ASSERT(isMainThread()); 149 if (m_commitPending) 150 return; 200 if (m_commitRequested) 201 return; 202 m_commitRequested = true; 151 203 152 204 TRACE_EVENT("CCThreadProxy::setNeedsCommitAndRedraw", this, 0); 153 m_commitPending = true; 154 ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::setNeedsCommitAndRedrawOnCCThread)); 205 ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::updateSchedulerStateOnCCThread, m_commitRequested, true)); 155 206 } 156 207 … … 158 209 { 159 210 ASSERT(isMainThread()); 160 ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::setNeedsRedrawOnCCThread)); 211 if (m_commitRequested) // Implies that a commit is in flight. 212 return; 213 // Unlike setNeedsCommit that tracks whether a commit message has been sent, 214 // setNeedsRedraw always sends a message to the compositor thread. This is 215 // because the compositor thread can draw without telling the main 216 // thread. This should not be much of a problem because calls to 217 // setNeedsRedraw messages are uncommon (only triggered by WM_PAINT/etc), 218 // compared to setNeedsCommitAndRedraw messages. 219 TRACE_EVENT("CCThreadProxy::setNeedsRedraw", this, 0); 220 ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::updateSchedulerStateOnCCThread, false, true)); 161 221 } 162 222 163 223 void CCThreadProxy::start() 164 224 { 225 ASSERT(isMainThread()); 165 226 // Create LayerTreeHostImpl. 166 227 CCCompletionEvent completion; 167 228 ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::initializeImplOnCCThread, AllowCrossThreadAccess(&completion))); 168 229 completion.wait(); 230 231 m_started = true; 169 232 } 170 233 … … 173 236 TRACE_EVENT("CCThreadProxy::stop", this, 0); 174 237 ASSERT(isMainThread()); 238 ASSERT(m_started); 239 175 240 // Synchronously deletes the impl. 176 241 CCCompletionEvent completion; … … 180 245 ASSERT(!m_layerTreeHostImpl); // verify that the impl deleted. 181 246 m_layerTreeHost = 0; 182 } 183 184 void CCThreadProxy::beginFrameAndCommitOnCCThread() 185 { 186 TRACE_EVENT("CCThreadProxy::beginFrameAndCommitOnCCThread", this, 0); 187 ASSERT(isImplThread()); 188 // TEMP HACK so we can exercise this code in unit tests. 189 CCMainThread::postTask(createMainThreadTask(this, &CCThreadProxy::beginFrameAndCommit, 0.0)); 190 } 191 192 void CCThreadProxy::beginFrameAndCommit(double frameBeginTime) 193 { 247 m_started = false; 248 } 249 250 void CCThreadProxy::finishAllRenderingOnCCThread(CCCompletionEvent* completion) 251 { 252 TRACE_EVENT("CCThreadProxy::finishAllRenderingOnCCThread", this, 0); 253 ASSERT(isImplThread()); 254 ASSERT(!m_beginFrameAndCommitPendingOnCCThread); 255 if (m_redrawRequestedOnCCThread) { 256 drawLayersOnCCThread(); 257 m_layerTreeHostImpl->present(); 258 m_redrawRequestedOnCCThread = false; 259 } 260 m_layerTreeHostImpl->finishAllRendering(); 261 completion->signal(); 262 } 263 264 void CCThreadProxy::obtainBeginFrameAndCommitTaskFromCCThread(CCCompletionEvent* completion, CCMainThread::Task** taskPtr) 265 { 266 OwnPtr<CCMainThread::Task> task = createBeginFrameAndCommitTaskOnCCThread(); 267 *taskPtr = task.leakPtr(); 268 completion->signal(); 269 } 270 271 PassOwnPtr<CCMainThread::Task> CCThreadProxy::createBeginFrameAndCommitTaskOnCCThread() 272 { 273 TRACE_EVENT("CCThreadProxy::createBeginFrameAndCommitTaskOnCCThread", this, 0); 274 ASSERT(isImplThread()); 275 double frameBeginTime = currentTime(); 276 m_beginFrameAndCommitPendingOnCCThread = true; 277 278 // NOTE, it is possible to receieve a request for a 279 // beginFrameAndCommitOnCCThread from finishAllRendering while a 280 // beginFrameAndCommitOnCCThread is enqueued. Since CCMainThread doesn't 281 // provide a threadsafe way to cancel tasks, it is important that 282 // beginFrameAndCommit be structured to understand that it may get called at 283 // a point that it shouldn't. We do this by assigning a sequence number to 284 // every new beginFrameAndCommit task. Then, beginFrameAndCommit tracks the 285 // last executed sequence number, dropping beginFrameAndCommit with sequence 286 // numbers below the last executed one. 287 int thisTaskSequenceNumber = m_numBeginFrameAndCommitsIssuedOnCCThread; 288 m_numBeginFrameAndCommitsIssuedOnCCThread++; 289 return createMainThreadTask(this, &CCThreadProxy::beginFrameAndCommit, thisTaskSequenceNumber, frameBeginTime); 290 } 291 292 void CCThreadProxy::beginFrameAndCommit(int sequenceNumber, double frameBeginTime) 293 { 294 TRACE_EVENT("CCThreadProxy::beginFrameAndCommit", this, 0); 194 295 ASSERT(isMainThread()); 195 296 if (!m_layerTreeHost) 196 297 return; 197 298 198 TRACE_EVENT("CCThreadProxy::requestFrameAndCommit", this, 0); 299 // Drop beginFrameAndCommit calls that occur out of sequence. See createBeginFrameAndCommitTaskOnCCThread for 300 // an explanation of how out-of-sequence beginFrameAndCommit tasks can occur. 301 if (sequenceNumber < m_lastExecutedBeginFrameAndCommitSequenceNumber) { 302 TRACE_EVENT("EarlyOut_StaleBeginFrameAndCommit", this, 0); 303 return; 304 } 305 m_lastExecutedBeginFrameAndCommitSequenceNumber = sequenceNumber; 306 307 ASSERT(m_commitRequested); 308 309 // FIXME: recreate the context if it was requested by the impl thread 199 310 { 200 311 TRACE_EVENT("CCLayerTreeHost::animateAndLayout", this, 0); … … 202 313 } 203 314 204 m_commitPending = false; 205 206 // Blocking call to CCThreadProxy::performCommit 207 CCCompletionEvent completion; 208 ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::commitOnCCThread, AllowCrossThreadAccess(&completion))); 209 completion.wait(); 315 ASSERT(m_lastExecutedBeginFrameAndCommitSequenceNumber == sequenceNumber); 316 317 // Clear the commit flag after animateAndLayout here --- objects that only 318 // layout when painted will trigger another setNeedsCommit inside 319 // updateLayers. 320 m_commitRequested = false; 321 322 m_layerTreeHost->updateLayers(); 323 324 { 325 // Blocking call to CCThreadProxy::commitOnCCThread 326 TRACE_EVENT("commit", this, 0); 327 CCCompletionEvent completion; 328 ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::commitOnCCThread, AllowCrossThreadAccess(&completion))); 329 completion.wait(); 330 } 331 332 m_layerTreeHost->commitComplete(); 333 334 ASSERT(m_lastExecutedBeginFrameAndCommitSequenceNumber == sequenceNumber); 210 335 } 211 336 212 337 void CCThreadProxy::commitOnCCThread(CCCompletionEvent* completion) 213 338 { 214 ASSERT(isImplThread()); 215 TRACE_EVENT("CCThreadProxy::commitOnCCThread", this, 0); 339 TRACE_EVENT("CCThreadProxy::beginFrameAndCommitOnCCThread", this, 0); 340 ASSERT(isImplThread()); 341 ASSERT(m_beginFrameAndCommitPendingOnCCThread); 342 m_beginFrameAndCommitPendingOnCCThread = false; 343 if (!m_layerTreeHostImpl) { 344 completion->signal(); 345 return; 346 } 216 347 m_layerTreeHostImpl->beginCommit(); 217 { 218 TRACE_EVENT("CCLayerTreeHost::commit", this, 0); 219 m_layerTreeHost->commitTo(m_layerTreeHostImpl.get()); 220 } 221 completion->signal(); 222 348 m_layerTreeHost->commitTo(m_layerTreeHostImpl.get()); 223 349 m_layerTreeHostImpl->commitComplete(); 224 setNeedsRedrawOnCCThread(); 350 351 completion->signal(); 352 353 if (m_redrawRequestedOnCCThread) 354 scheduleDrawTaskOnCCThread(); 355 } 356 357 void CCThreadProxy::scheduleDrawTaskOnCCThread() 358 { 359 ASSERT(isImplThread()); 360 if (m_drawTaskPostedOnCCThread) 361 return; 362 TRACE_EVENT("CCThreadProxy::scheduleDrawTaskOnCCThread", this, 0); 363 ASSERT(m_layerTreeHostImpl); 364 m_drawTaskPostedOnCCThread = true; 365 ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::drawLayersAndPresentOnCCThread)); 366 } 367 368 void CCThreadProxy::drawLayersAndPresentOnCCThread() 369 { 370 TRACE_EVENT("CCThreadProxy::drawLayersOnCCThread", this, 0); 371 ASSERT(isImplThread()); 372 if (!m_layerTreeHostImpl) 373 return; 374 375 drawLayersOnCCThread(); 376 m_layerTreeHostImpl->present(); 377 m_redrawRequestedOnCCThread = false; 378 m_drawTaskPostedOnCCThread = false; 225 379 } 226 380 … … 229 383 TRACE_EVENT("CCThreadProxy::drawLayersOnCCThread", this, 0); 230 384 ASSERT(isImplThread()); 231 if (m_layerTreeHostImpl)232 m_layerTreeHostImpl->drawLayers();233 }234 235 void CCThreadProxy::setNeedsCommitOnCCThread()236 {237 TRACE_EVENT("CCThreadProxy::setNeedsCommitOnCCThread", this, 0);238 ASSERT(isImplThread());239 385 ASSERT(m_layerTreeHostImpl); 240 // FIXME: Not yet implemented, see https://bugs.webkit.org/show_bug.cgi?id=67417 241 ASSERT_NOT_REACHED(); 242 } 243 244 void CCThreadProxy::setNeedsCommitAndRedrawOnCCThread() 245 { 246 TRACE_EVENT("CCThreadProxy::setNeedsCommitAndRedrawOnCCThread", this, 0); 386 387 m_layerTreeHostImpl->drawLayers(); 388 ASSERT(!m_layerTreeHostImpl->isContextLost()); 389 } 390 391 void CCThreadProxy::updateSchedulerStateOnCCThread(bool commitRequested, bool redrawRequested) 392 { 393 TRACE_EVENT("CCThreadProxy::updateSchedulerStateOnCCThread", this, 0); 247 394 ASSERT(isImplThread()); 248 395 ASSERT(m_layerTreeHostImpl); 249 // TEMP HACK so we can exercise this code in unit tests. 250 CCMainThread::postTask(createMainThreadTask(this, &CCThreadProxy::beginFrameAndCommit, 0.0)); 251 } 252 253 void CCThreadProxy::setNeedsRedrawOnCCThread() 254 { 255 TRACE_EVENT("CCThreadProxy::setNeedsRedrawOnCCThread", this, 0); 256 // TEMP HACK so we can exercise this code in unit tests. 257 drawLayersOnCCThread(); 396 397 // FIXME: use CCScheduler to decide when to manage the conversion of this 398 // commit request into an actual createBeginFrameAndCommitTaskOnCCThread call. 399 m_redrawRequestedOnCCThread |= redrawRequested; 400 if (!m_beginFrameAndCommitPendingOnCCThread) { 401 CCMainThread::postTask(createBeginFrameAndCommitTaskOnCCThread()); 402 return; 403 } 404 405 // If no commit is pending, but a redraw is requested, then post a redraw right away 406 if (m_redrawRequestedOnCCThread) 407 scheduleDrawTaskOnCCThread(); 258 408 } 259 409 -
trunk/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.h
r95901 r96066 28 28 #include "cc/CCCompletionEvent.h" 29 29 #include "cc/CCLayerTreeHostImpl.h" 30 #include "cc/CCMainThread.h" 30 31 #include "cc/CCProxy.h" 31 32 #include <wtf/OwnPtr.h> … … 59 60 60 61 // Called on CCMainThread 61 void beginFrameAndCommit( double frameBeginTime);62 void beginFrameAndCommit(int sequenceNumber, double frameBeginTime); 62 63 63 64 // Called on CCThread 64 void beginFrameAndCommitOnCCThread(); 65 PassOwnPtr<CCMainThread::Task> createBeginFrameAndCommitTaskOnCCThread(); 66 void obtainBeginFrameAndCommitTaskFromCCThread(CCCompletionEvent*, CCMainThread::Task**); 65 67 void commitOnCCThread(CCCompletionEvent*); 68 void drawLayersAndPresentOnCCThread(); 66 69 void drawLayersOnCCThread(); 70 void drawLayersAndReadbackOnCCThread(CCCompletionEvent*, bool* success, void* pixels, const IntRect&); 71 void finishAllRenderingOnCCThread(CCCompletionEvent*); 67 72 void initializeImplOnCCThread(CCCompletionEvent*); 68 73 void initializeLayerRendererOnCCThread(GraphicsContext3D*, CCCompletionEvent*, bool* initializeSucceeded, LayerRendererCapabilities*); 69 74 void setNeedsCommitOnCCThread(); 70 void setNeedsCommitAndRedrawOnCCThread(); 71 void setNeedsRedrawOnCCThread(); 75 void updateSchedulerStateOnCCThread(bool commitRequested, bool redrawRequested); 72 76 void layerTreeHostClosedOnCCThread(CCCompletionEvent*); 73 74 // Used on main-thread only. 75 bool m_commitPending; 77 void scheduleDrawTaskOnCCThread(); 76 78 77 79 // Accessed on main thread only. 80 bool m_commitRequested; 78 81 CCLayerTreeHost* m_layerTreeHost; 79 82 LayerRendererCapabilities m_layerRendererCapabilitiesMainThreadCopy; 83 bool m_started; 84 int m_lastExecutedBeginFrameAndCommitSequenceNumber; 80 85 81 // Used on the CCThread , but checked on main thread during initialization/shutdown.86 // Used on the CCThread only 82 87 OwnPtr<CCLayerTreeHostImpl> m_layerTreeHostImpl; 88 int m_numBeginFrameAndCommitsIssuedOnCCThread; 89 bool m_beginFrameAndCommitPendingOnCCThread; 90 bool m_drawTaskPostedOnCCThread; 91 bool m_redrawRequestedOnCCThread; 83 92 }; 84 93 -
trunk/Source/WebKit/chromium/ChangeLog
r96054 r96066 1 2011-09-26 Nat Duca <nduca@chromium.org> 2 3 [chromium] Make CCThreadProxy draw 4 https://bugs.webkit.org/show_bug.cgi?id=67417 5 6 Disable CCLayerTreeHostTest temporarily. Will re-enable 7 with https://bugs.webkit.org/show_bug.cgi?id=67418 8 9 Reviewed by James Robinson. 10 11 * tests/CCLayerTreeHostTest.cpp: 12 1 13 2011-09-26 Joshua Bell <jsbell@chromium.org> 2 14 -
trunk/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp
r95901 r96066 171 171 } 172 172 173 #if !USE(THREADED_COMPOSITING) 174 virtual void scheduleComposite() { } 175 #endif 176 173 177 private: 174 178 explicit MockLayerTreeHostClient(TestHooks* testHooks) : m_testHooks(testHooks) { } … … 209 213 , m_endWhenBeginReturns(false) 210 214 , m_running(false) 211 , m_timedOut(false) { } 215 , m_timedOut(false) 216 { 217 #if USE(THREADED_COMPOSITING) 218 m_settings.enableCompositorThread = true; 219 #else 220 m_settings.enableCompositorThread = false; 221 #endif 222 } 212 223 213 224 void doBeginTest(); … … 271 282 } 272 283 284 CCSettings m_settings; 273 285 OwnPtr<MockLayerTreeHostClient> m_client; 274 286 RefPtr<CCLayerTreeHost> m_layerTreeHost; … … 288 300 m_client = MockLayerTreeHostClient::create(this); 289 301 290 CCSettings settings;291 settings.enableCompositorThread = true;292 302 RefPtr<LayerChromium> rootLayer; 293 m_layerTreeHost = MockLayerTreeHost::create(this, m_client.get(), rootLayer, settings);303 m_layerTreeHost = MockLayerTreeHost::create(this, m_client.get(), rootLayer, m_settings); 294 304 ASSERT(m_layerTreeHost); 295 305 … … 546 556 TEST_F(CCLayerTreeHostTestSetNeedsRedraw, run) 547 557 { 558 CCSettings setings; 548 559 runTest(); 549 560 } … … 551 562 } // namespace 552 563 553 #endif // USE(THREADED_COMPOSITING)564 #endif -
trunk/Source/WebKit/chromium/tests/TreeSynchronizerTest.cpp
r95901 r96066 29 29 #include "LayerChromium.h" 30 30 #include "cc/CCLayerImpl.h" 31 #include "cc/CCProxy.h" 31 32 #include <gtest/gtest.h> 32 33 … … 34 35 35 36 namespace { 37 38 class ScopedSetImplThread { 39 public: 40 ScopedSetImplThread() 41 { 42 #ifndef NDEBUG 43 CCProxy::setImplThread(true); 44 #endif 45 } 46 ~ScopedSetImplThread() 47 { 48 #ifndef NDEBUG 49 CCProxy::setImplThread(false); 50 #endif 51 } 52 }; 36 53 37 54 class MockCCLayerImpl : public CCLayerImpl { … … 117 134 TEST(TreeSynchronizerTest, syncSimpleTreeFromEmpty) 118 135 { 136 ScopedSetImplThread impl; 119 137 RefPtr<LayerChromium> layerTreeRoot = LayerChromium::create(0); 120 138 layerTreeRoot->addChild(LayerChromium::create(0)); … … 129 147 TEST(TreeSynchronizerTest, syncSimpleTreeReusingLayers) 130 148 { 149 ScopedSetImplThread impl; 131 150 Vector<int> ccLayerDestructionList; 132 151 … … 154 173 TEST(TreeSynchronizerTest, syncSimpleTreeAndProperties) 155 174 { 175 ScopedSetImplThread impl; 156 176 RefPtr<LayerChromium> layerTreeRoot = LayerChromium::create(0); 157 177 layerTreeRoot->addChild(LayerChromium::create(0)); … … 185 205 TEST(TreeSynchronizerTest, reuseCCLayersAfterStructuralChange) 186 206 { 207 ScopedSetImplThread impl; 187 208 Vector<int> ccLayerDestructionList; 188 209 … … 231 252 TEST(TreeSynchronizerTest, syncSimpleTreeThenDestroy) 232 253 { 254 ScopedSetImplThread impl; 233 255 Vector<int> ccLayerDestructionList; 234 256 … … 261 283 TEST(TreeSynchronizerTest, syncMaskReplicaAndReplicaMaskLayers) 262 284 { 285 ScopedSetImplThread impl; 263 286 RefPtr<LayerChromium> layerTreeRoot = LayerChromium::create(0); 264 287 layerTreeRoot->addChild(LayerChromium::create(0));
Note: See TracChangeset
for help on using the changeset viewer.