blob: 25d41cca581bb25b83adb03ad0fbf5172fee4c23 [file] [log] [blame]
[email protected]94f206c12012-08-25 00:09:141// Copyright 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "config.h"
6
7#include "CCTextureUpdateController.h"
8
9#include "GraphicsContext3D.h"
10#include "TextureCopier.h"
11#include "TextureUploader.h"
12#include <wtf/CurrentTime.h>
13
14namespace {
15
16// Number of textures to update with each call to updateMoreTexturesIfEnoughTimeRemaining().
17static const size_t textureUpdatesPerTick = 12;
18
19// Measured in seconds.
20static const double textureUpdateTickRate = 0.004;
21
22// Flush interval when performing texture uploads.
23static const int textureUploadFlushPeriod = 4;
24
25} // anonymous namespace
26
27namespace WebCore {
28
29size_t CCTextureUpdateController::maxPartialTextureUpdates()
30{
31 return textureUpdatesPerTick;
32}
33
34void CCTextureUpdateController::updateTextures(CCResourceProvider* resourceProvider, TextureCopier* copier, TextureUploader* uploader, CCTextureUpdateQueue* queue, size_t count)
35{
36 if (queue->fullUploadSize() || queue->partialUploadSize()) {
37 if (uploader->isBusy())
38 return;
39
40 uploader->beginUploads();
41
42 size_t fullUploadCount = 0;
43 while (queue->fullUploadSize() && fullUploadCount < count) {
44 uploader->uploadTexture(resourceProvider, queue->takeFirstFullUpload());
45 fullUploadCount++;
46 if (!(fullUploadCount % textureUploadFlushPeriod))
47 resourceProvider->shallowFlushIfSupported();
48 }
49
50 // Make sure there are no dangling uploads without a flush.
51 if (fullUploadCount % textureUploadFlushPeriod)
52 resourceProvider->shallowFlushIfSupported();
53
54 bool moreUploads = queue->fullUploadSize();
55
56 ASSERT(queue->partialUploadSize() <= count);
57 // We need another update batch if the number of updates remaining
58 // in |count| is greater than the remaining partial entries.
59 if ((count - fullUploadCount) < queue->partialUploadSize())
60 moreUploads = true;
61
62 if (moreUploads) {
63 uploader->endUploads();
64 return;
65 }
66
67 size_t partialUploadCount = 0;
68 while (queue->partialUploadSize()) {
69 uploader->uploadTexture(resourceProvider, queue->takeFirstPartialUpload());
70 partialUploadCount++;
71 if (!(partialUploadCount % textureUploadFlushPeriod))
72 resourceProvider->shallowFlushIfSupported();
73 }
74
75 // Make sure there are no dangling partial uploads without a flush.
76 if (partialUploadCount % textureUploadFlushPeriod)
77 resourceProvider->shallowFlushIfSupported();
78
79 uploader->endUploads();
80 }
81
82 size_t copyCount = 0;
83 while (queue->copySize()) {
84 copier->copyTexture(queue->takeFirstCopy());
85 copyCount++;
86 }
87
88 // If we've performed any texture copies, we need to insert a flush here into the compositor context
89 // before letting the main thread proceed as it may make draw calls to the source texture of one of
90 // our copy operations.
91 if (copyCount)
92 copier->flush();
93}
94
95CCTextureUpdateController::CCTextureUpdateController(CCThread* thread, PassOwnPtr<CCTextureUpdateQueue> queue, CCResourceProvider* resourceProvider, TextureCopier* copier, TextureUploader* uploader)
96 : m_timer(adoptPtr(new CCTimer(thread, this)))
97 , m_queue(queue)
98 , m_resourceProvider(resourceProvider)
99 , m_copier(copier)
100 , m_uploader(uploader)
101 , m_monotonicTimeLimit(0)
102 , m_firstUpdateAttempt(true)
103{
104}
105
106CCTextureUpdateController::~CCTextureUpdateController()
107{
108}
109
110bool CCTextureUpdateController::hasMoreUpdates() const
111{
112 return m_queue->hasMoreUpdates();
113}
114
115void CCTextureUpdateController::updateMoreTextures(double monotonicTimeLimit)
116{
117 m_monotonicTimeLimit = monotonicTimeLimit;
118
119 if (!m_queue->hasMoreUpdates())
120 return;
121
122 // Call updateMoreTexturesNow() directly unless it's the first update
123 // attempt. This ensures that we empty the update queue in a finite
124 // amount of time.
125 if (m_firstUpdateAttempt) {
126 updateMoreTexturesIfEnoughTimeRemaining();
127 m_firstUpdateAttempt = false;
128 } else
129 updateMoreTexturesNow();
130}
131
132void CCTextureUpdateController::onTimerFired()
133{
134 if (!m_queue->hasMoreUpdates())
135 return;
136
137 updateMoreTexturesIfEnoughTimeRemaining();
138}
139
140double CCTextureUpdateController::monotonicTimeNow() const
141{
142 return monotonicallyIncreasingTime();
143}
144
145double CCTextureUpdateController::updateMoreTexturesTime() const
146{
147 return textureUpdateTickRate;
148}
149
150size_t CCTextureUpdateController::updateMoreTexturesSize() const
151{
152 return textureUpdatesPerTick;
153}
154
155void CCTextureUpdateController::updateMoreTexturesIfEnoughTimeRemaining()
156{
157 bool hasTimeRemaining = monotonicTimeNow() < m_monotonicTimeLimit - updateMoreTexturesTime();
158 if (hasTimeRemaining)
159 updateMoreTexturesNow();
160}
161
162void CCTextureUpdateController::updateMoreTexturesNow()
163{
164 m_timer->startOneShot(updateMoreTexturesTime());
165 updateTextures(m_resourceProvider, m_copier, m_uploader, m_queue.get(), updateMoreTexturesSize());
166}
167
168}