05e9f54ddaecaab241e9b5a4adc5bf15c742d202
[WebKit.git] / Source / WebCore / platform / graphics / chromium / cc / CCTextureUpdater.cpp
1 /*
2  * Copyright (C) 2011 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27
28 #if USE(ACCELERATED_COMPOSITING)
29
30 #include "cc/CCTextureUpdater.h"
31
32 #include "GraphicsContext3D.h"
33 #include "LayerTextureUpdater.h"
34 #include "ManagedTexture.h"
35 #include "TextureCopier.h"
36 #include "TextureUploader.h"
37
38 using namespace std;
39
40 namespace WebCore {
41
42 CCTextureUpdater::CCTextureUpdater()
43     : m_entryIndex(0)
44 {
45 }
46
47 CCTextureUpdater::~CCTextureUpdater()
48 {
49 }
50
51 void CCTextureUpdater::appendUpdate(LayerTextureUpdater::Texture* texture, const IntRect& sourceRect, const IntRect& destRect, Vector<UpdateEntry>& entries)
52 {
53     ASSERT(texture);
54
55     UpdateEntry entry;
56     entry.texture = texture;
57     entry.sourceRect = sourceRect;
58     entry.destRect = destRect;
59     entries.append(entry);
60 }
61
62 void CCTextureUpdater::appendUpdate(LayerTextureUpdater::Texture* texture, const IntRect& sourceRect, const IntRect& destRect)
63 {
64     appendUpdate(texture, sourceRect, destRect, m_entries);
65 }
66
67 void CCTextureUpdater::appendPartialUpdate(LayerTextureUpdater::Texture* texture, const IntRect& sourceRect, const IntRect& destRect)
68 {
69     appendUpdate(texture, sourceRect, destRect, m_partialEntries);
70 }
71
72 void CCTextureUpdater::appendCopy(unsigned sourceTexture, unsigned destTexture, const IntSize& size)
73 {
74     CopyEntry copy;
75     copy.sourceTexture = sourceTexture;
76     copy.destTexture = destTexture;
77     copy.size = size;
78     m_copyEntries.append(copy);
79 }
80
81 void CCTextureUpdater::appendManagedCopy(unsigned sourceTexture, ManagedTexture* destTexture, const IntSize& size)
82 {
83     ManagedCopyEntry copy;
84     copy.sourceTexture = sourceTexture;
85     copy.destTexture = destTexture;
86     copy.size = size;
87     m_managedCopyEntries.append(copy);
88 }
89
90 bool CCTextureUpdater::hasMoreUpdates() const
91 {
92     return m_entries.size() || m_partialEntries.size() || m_copyEntries.size() || m_managedCopyEntries.size();
93 }
94
95 void CCTextureUpdater::update(CCGraphicsContext* context, TextureAllocator* allocator, TextureCopier* copier, TextureUploader* uploader, size_t count)
96 {
97     size_t index;
98
99     if (m_entries.size() || m_partialEntries.size()) {
100         if (uploader->isBusy())
101             return;
102
103         uploader->beginUploads();
104
105         size_t maxIndex = min(m_entryIndex + count, m_entries.size());
106         for (index = m_entryIndex; index < maxIndex; ++index) {
107             UpdateEntry& entry = m_entries[index];
108             uploader->uploadTexture(context, entry.texture, allocator, entry.sourceRect, entry.destRect);
109         }
110
111         bool moreUploads = maxIndex < m_entries.size();
112
113         ASSERT(m_partialEntries.size() <= count);
114         // We need another update batch if the number of updates remaining
115         // in |count| is greater than the remaining partial entries.
116         if ((count - (index - m_entryIndex)) < m_partialEntries.size())
117             moreUploads = true;
118
119         if (moreUploads) {
120             m_entryIndex = index;
121             uploader->endUploads();
122             return;
123         }
124
125         for (index = 0; index < m_partialEntries.size(); ++index) {
126             UpdateEntry& entry = m_partialEntries[index];
127             uploader->uploadTexture(context, entry.texture, allocator, entry.sourceRect, entry.destRect);
128         }
129
130         uploader->endUploads();
131     }
132
133     for (index = 0; index < m_copyEntries.size(); ++index) {
134         CopyEntry& copyEntry = m_copyEntries[index];
135         copier->copyTexture(context, copyEntry.sourceTexture, copyEntry.destTexture, copyEntry.size);
136     }
137     for (index = 0; index < m_managedCopyEntries.size(); ++index) {
138         ManagedCopyEntry& managedCopyEntry = m_managedCopyEntries[index];
139         managedCopyEntry.destTexture->allocate(allocator);
140         copier->copyTexture(context, managedCopyEntry.sourceTexture, managedCopyEntry.destTexture->textureId(), managedCopyEntry.size);
141     }
142     // If we've performed any texture copies, we need to insert a flush here into the compositor context
143     // before letting the main thread proceed as it may make draw calls to the source texture of one of
144     // our copy operations.
145     if (m_copyEntries.size() || m_managedCopyEntries.size()) {
146         GraphicsContext3D* context3d = context->context3D();
147         if (context3d)
148             context3d->flush();
149         // FIXME: Implement this path for software compositing.
150     }
151
152     // If no entries left to process, auto-clear.
153     clear();
154 }
155
156 void CCTextureUpdater::clear()
157 {
158     m_entryIndex = 0;
159     m_entries.clear();
160     m_partialEntries.clear();
161     m_copyEntries.clear();
162     m_managedCopyEntries.clear();
163 }
164
165 }
166
167 #endif // USE(ACCELERATED_COMPOSITING)