summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.cpp
diff options
context:
space:
mode:
authorNicolas Roard <nicolasroard@google.com>2012-04-06 11:35:50 -0700
committerNicolas Roard <nicolasroard@google.com>2012-04-06 14:03:59 -0700
commit2e510fd5b5a30f1315c272d44ae3aa4cba355498 (patch)
treedb3af5f32855d329856f190c3509ae11ae519851 /Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.cpp
parentc88c88907b618e468ec3928b06a3a31d4f99b9c6 (diff)
downloadexternal_webkit-2e510fd5b5a30f1315c272d44ae3aa4cba355498.zip
external_webkit-2e510fd5b5a30f1315c272d44ae3aa4cba355498.tar.gz
external_webkit-2e510fd5b5a30f1315c272d44ae3aa4cba355498.tar.bz2
Reorganize platform/graphics/android
Change-Id: Idc67155cfa99784dcd931e705336bfa063ecae46
Diffstat (limited to 'Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.cpp')
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.cpp182
1 files changed, 182 insertions, 0 deletions
diff --git a/Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.cpp b/Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.cpp
new file mode 100644
index 0000000..f884e52
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.cpp
@@ -0,0 +1,182 @@
+/*
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define LOG_TAG "TexturesGenerator"
+#define LOG_NDEBUG 1
+
+#include "config.h"
+#include "TexturesGenerator.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "AndroidLog.h"
+#include "GLUtils.h"
+#include "PaintTileOperation.h"
+#include "TilesManager.h"
+#include "TransferQueue.h"
+
+namespace WebCore {
+
+void TexturesGenerator::scheduleOperation(QueuedOperation* operation)
+{
+ {
+ android::Mutex::Autolock lock(mRequestedOperationsLock);
+ mRequestedOperations.append(operation);
+ }
+ mRequestedOperationsCond.signal();
+}
+
+void TexturesGenerator::removeOperationsForFilter(OperationFilter* filter, bool waitForRunning)
+{
+ if (!filter)
+ return;
+
+ android::Mutex::Autolock lock(mRequestedOperationsLock);
+ for (unsigned int i = 0; i < mRequestedOperations.size();) {
+ QueuedOperation* operation = mRequestedOperations[i];
+ if (filter->check(operation)) {
+ mRequestedOperations.remove(i);
+ delete operation;
+ } else {
+ i++;
+ }
+ }
+
+ if (waitForRunning && m_currentOperation) {
+ QueuedOperation* operation = m_currentOperation;
+
+ if (operation && filter->check(operation)) {
+ m_waitForCompletion = true;
+ // The reason we are signaling the transferQueue is :
+ // TransferQueue may be waiting a slot to work on, but now UI
+ // thread is waiting for Tex Gen thread to finish first before the
+ // UI thread can free a slot for the transferQueue.
+ // Therefore, it could be a deadlock.
+ // The solution is use this as a flag to tell Tex Gen thread that
+ // UI thread is waiting now, Tex Gen thread should not wait for the
+ // queue any more.
+ m_tilesManager->transferQueue()->interruptTransferQueue(true);
+ }
+
+ delete filter;
+
+ // At this point, it means that we are currently executing an operation that
+ // we want to be removed -- we should wait until it is done, so that
+ // when we return our caller can be sure that there is no more operations
+ // in the queue matching the given filter.
+ while (m_waitForCompletion)
+ mRequestedOperationsCond.wait(mRequestedOperationsLock);
+ } else {
+ delete filter;
+ }
+}
+
+status_t TexturesGenerator::readyToRun()
+{
+ ALOGV("Thread ready to run");
+ return NO_ERROR;
+}
+
+// Must be called from within a lock!
+QueuedOperation* TexturesGenerator::popNext()
+{
+ // Priority can change between when it was added and now
+ // Hence why the entire queue is rescanned
+ QueuedOperation* current = mRequestedOperations.last();
+ int currentPriority = current->priority();
+ if (currentPriority < 0) {
+ mRequestedOperations.removeLast();
+ return current;
+ }
+ int currentIndex = mRequestedOperations.size() - 1;
+ // Scan from the back to make removing faster (less items to copy)
+ for (int i = mRequestedOperations.size() - 2; i >= 0; i--) {
+ QueuedOperation *next = mRequestedOperations[i];
+ int nextPriority = next->priority();
+ if (nextPriority < 0) {
+ // Found a very high priority item, go ahead and just handle it now
+ mRequestedOperations.remove(i);
+ return next;
+ }
+ // pick items preferrably by priority, or if equal, by order of
+ // insertion (as we add items at the back of the queue)
+ if (nextPriority <= currentPriority) {
+ current = next;
+ currentPriority = nextPriority;
+ currentIndex = i;
+ }
+ }
+ mRequestedOperations.remove(currentIndex);
+ return current;
+}
+
+bool TexturesGenerator::threadLoop()
+{
+ // Check if we have any pending operations.
+ mRequestedOperationsLock.lock();
+ while (!mRequestedOperations.size())
+ mRequestedOperationsCond.wait(mRequestedOperationsLock);
+
+ ALOGV("threadLoop, got signal");
+ mRequestedOperationsLock.unlock();
+
+ m_currentOperation = 0;
+ bool stop = false;
+ while (!stop) {
+ mRequestedOperationsLock.lock();
+ ALOGV("threadLoop, %d operations in the queue", mRequestedOperations.size());
+ if (mRequestedOperations.size())
+ m_currentOperation = popNext();
+ mRequestedOperationsLock.unlock();
+
+ if (m_currentOperation) {
+ ALOGV("threadLoop, painting the request with priority %d",
+ m_currentOperation->priority());
+ m_currentOperation->run();
+ }
+
+ QueuedOperation* oldOperation = m_currentOperation;
+ mRequestedOperationsLock.lock();
+ if (m_currentOperation)
+ m_currentOperation = 0;
+ if (!mRequestedOperations.size())
+ stop = true;
+ if (m_waitForCompletion) {
+ m_waitForCompletion = false;
+ m_tilesManager->transferQueue()->interruptTransferQueue(false);
+ mRequestedOperationsCond.signal();
+ }
+ mRequestedOperationsLock.unlock();
+ if (oldOperation)
+ delete oldOperation; // delete outside lock
+ }
+ ALOGV("threadLoop empty");
+
+ return true;
+}
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)