• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2010, The Android Open Source Project
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  *  * Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  *  * Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #include "config.h"
27 #include "TexturesGenerator.h"
28 
29 #if USE(ACCELERATED_COMPOSITING)
30 
31 #include "BaseLayerAndroid.h"
32 #include "GLUtils.h"
33 #include "PaintTileOperation.h"
34 #include "TilesManager.h"
35 
36 #ifdef DEBUG
37 
38 #include <cutils/log.h>
39 #include <wtf/CurrentTime.h>
40 #include <wtf/text/CString.h>
41 
42 #undef XLOG
43 #define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "TexturesGenerator", __VA_ARGS__)
44 
45 #else
46 
47 #undef XLOG
48 #define XLOG(...)
49 
50 #endif // DEBUG
51 
52 namespace WebCore {
53 
scheduleOperation(QueuedOperation * operation)54 void TexturesGenerator::scheduleOperation(QueuedOperation* operation)
55 {
56     {
57         android::Mutex::Autolock lock(mRequestedOperationsLock);
58         mRequestedOperations.append(operation);
59     }
60     mRequestedOperationsCond.signal();
61 }
62 
removeOperationsForPage(TiledPage * page)63 void TexturesGenerator::removeOperationsForPage(TiledPage* page)
64 {
65     removeOperationsForFilter(new PageFilter(page));
66 }
67 
removePaintOperationsForPage(TiledPage * page,bool waitForRunning)68 void TexturesGenerator::removePaintOperationsForPage(TiledPage* page, bool waitForRunning)
69 {
70     removeOperationsForFilter(new PagePaintFilter(page), waitForRunning);
71 }
72 
removeOperationsForFilter(OperationFilter * filter)73 void TexturesGenerator::removeOperationsForFilter(OperationFilter* filter)
74 {
75     removeOperationsForFilter(filter, true);
76 }
77 
removeOperationsForFilter(OperationFilter * filter,bool waitForRunning)78 void TexturesGenerator::removeOperationsForFilter(OperationFilter* filter, bool waitForRunning)
79 {
80     if (!filter)
81         return;
82 
83     android::Mutex::Autolock lock(mRequestedOperationsLock);
84     for (unsigned int i = 0; i < mRequestedOperations.size();) {
85         QueuedOperation* operation = mRequestedOperations[i];
86         if (filter->check(operation)) {
87             mRequestedOperations.remove(i);
88             delete operation;
89         } else {
90             i++;
91         }
92     }
93 
94     if (waitForRunning && m_currentOperation) {
95         QueuedOperation* operation = m_currentOperation;
96 
97         if (operation && filter->check(operation)) {
98             m_waitForCompletion = true;
99             // The reason we are signaling the transferQueue is :
100             // TransferQueue may be waiting a slot to work on, but now UI
101             // thread is waiting for Tex Gen thread to finish first before the
102             // UI thread can free a slot for the transferQueue.
103             // Therefore, it could be a deadlock.
104             // The solution is use this as a flag to tell Tex Gen thread that
105             // UI thread is waiting now, Tex Gen thread should not wait for the
106             // queue any more.
107             TilesManager::instance()->transferQueue()->interruptTransferQueue(true);
108         }
109 
110         delete filter;
111 
112         // At this point, it means that we are currently executing an operation that
113         // we want to be removed -- we should wait until it is done, so that
114         // when we return our caller can be sure that there is no more operations
115         // in the queue matching the given filter.
116         while (m_waitForCompletion)
117             mRequestedOperationsCond.wait(mRequestedOperationsLock);
118     } else {
119         delete filter;
120     }
121 }
122 
readyToRun()123 status_t TexturesGenerator::readyToRun()
124 {
125     TilesManager::instance()->markGeneratorAsReady();
126     XLOG("Thread ready to run");
127     return NO_ERROR;
128 }
129 
130 // Must be called from within a lock!
popNext()131 QueuedOperation* TexturesGenerator::popNext()
132 {
133     // Priority can change between when it was added and now
134     // Hence why the entire queue is rescanned
135     QueuedOperation* current = mRequestedOperations.last();
136     int currentPriority = current->priority();
137     if (currentPriority < 0) {
138         mRequestedOperations.removeLast();
139         return current;
140     }
141     int currentIndex = mRequestedOperations.size() - 1;
142     // Scan from the back to make removing faster (less items to copy)
143     for (int i = mRequestedOperations.size() - 2; i >= 0; i--) {
144         QueuedOperation *next = mRequestedOperations[i];
145         int nextPriority = next->priority();
146         if (nextPriority < 0) {
147             // Found a very high priority item, go ahead and just handle it now
148             mRequestedOperations.remove(i);
149             return next;
150         }
151         // pick items preferrably by priority, or if equal, by order of
152         // insertion (as we add items at the back of the queue)
153         if (nextPriority <= currentPriority) {
154             current = next;
155             currentPriority = nextPriority;
156             currentIndex = i;
157         }
158     }
159     mRequestedOperations.remove(currentIndex);
160     return current;
161 }
162 
threadLoop()163 bool TexturesGenerator::threadLoop()
164 {
165     // Check if we have any pending operations.
166     mRequestedOperationsLock.lock();
167     while (!mRequestedOperations.size())
168         mRequestedOperationsCond.wait(mRequestedOperationsLock);
169 
170     XLOG("threadLoop, got signal");
171     mRequestedOperationsLock.unlock();
172 
173     m_currentOperation = 0;
174     bool stop = false;
175     while (!stop) {
176         mRequestedOperationsLock.lock();
177         XLOG("threadLoop, %d operations in the queue", mRequestedOperations.size());
178         if (mRequestedOperations.size())
179             m_currentOperation = popNext();
180         mRequestedOperationsLock.unlock();
181 
182         if (m_currentOperation) {
183             XLOG("threadLoop, painting the request with priority %d", m_currentOperation->priority());
184             m_currentOperation->run();
185         }
186 
187         mRequestedOperationsLock.lock();
188         if (m_currentOperation) {
189             delete m_currentOperation;
190             m_currentOperation = 0;
191         }
192         if (!mRequestedOperations.size())
193             stop = true;
194         if (m_waitForCompletion) {
195             m_waitForCompletion = false;
196             TilesManager::instance()->transferQueue()->interruptTransferQueue(false);
197             mRequestedOperationsCond.signal();
198         }
199         mRequestedOperationsLock.unlock();
200 
201     }
202     XLOG("threadLoop empty");
203 
204     return true;
205 }
206 
207 } // namespace WebCore
208 
209 #endif // USE(ACCELERATED_COMPOSITING)
210