summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/graphics/android/BaseLayerAndroid.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/platform/graphics/android/BaseLayerAndroid.cpp')
-rw-r--r--WebCore/platform/graphics/android/BaseLayerAndroid.cpp214
1 files changed, 214 insertions, 0 deletions
diff --git a/WebCore/platform/graphics/android/BaseLayerAndroid.cpp b/WebCore/platform/graphics/android/BaseLayerAndroid.cpp
new file mode 100644
index 0000000..0bb2928
--- /dev/null
+++ b/WebCore/platform/graphics/android/BaseLayerAndroid.cpp
@@ -0,0 +1,214 @@
+/*
+ * 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.
+ */
+
+#include "config.h"
+#include "BaseLayerAndroid.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+#include "GLUtils.h"
+#include "ShaderProgram.h"
+#include "SkCanvas.h"
+#include "TilesManager.h"
+#include <GLES2/gl2.h>
+#include <wtf/CurrentTime.h>
+#endif // USE(ACCELERATED_COMPOSITING)
+
+#ifdef DEBUG
+
+#include <cutils/log.h>
+#include <wtf/text/CString.h>
+
+#undef XLOG
+#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "BaseLayerAndroid", __VA_ARGS__)
+
+#else
+
+#undef XLOG
+#define XLOG(...)
+
+#endif // DEBUG
+
+namespace WebCore {
+
+using namespace android;
+
+#ifdef DEBUG_COUNT
+static int gBaseLayerAndroidCount = 0;
+int BaseLayerAndroid::count()
+{
+ return gBaseLayerAndroidCount;
+}
+#endif
+
+BaseLayerAndroid::BaseLayerAndroid()
+{
+#ifdef DEBUG_COUNT
+ gBaseLayerAndroidCount++;
+#endif
+}
+
+BaseLayerAndroid::~BaseLayerAndroid()
+{
+ m_content.clear();
+#ifdef DEBUG_COUNT
+ gBaseLayerAndroidCount--;
+#endif
+}
+
+void BaseLayerAndroid::setContent(const PictureSet& src)
+{
+ m_content.set(src);
+}
+
+#if USE(ACCELERATED_COMPOSITING)
+bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale)
+{
+ if (m_content.isEmpty())
+ return false;
+ if (!m_glWebViewState)
+ return false;
+
+ double currentTime = WTF::currentTime();
+ bool goingDown = m_previousVisible.fTop - viewport.fTop <= 0;
+ bool goingLeft = m_previousVisible.fLeft - viewport.fLeft >= 0;
+
+ m_glWebViewState->setViewport(viewport, scale);
+
+ int firstTileX = m_glWebViewState->firstTileX();
+ int firstTileY = m_glWebViewState->firstTileY();
+
+ XLOG("drawBasePicture, TX: %d, TY: %d scale %.2f", firstTileX, firstTileY, scale);
+ if (scale == m_glWebViewState->currentScale()) {
+ m_glWebViewState->setOriginalTilesPosX(firstTileX);
+ m_glWebViewState->setOriginalTilesPosY(firstTileY);
+ }
+
+ // If we have a different scale than the current one, we have to
+ // decide what to do. The current behaviour is to delay an update,
+ // so that we do not slow down zooming unnecessarily.
+ if (m_glWebViewState->currentScale() != scale
+ && (m_glWebViewState->scaleRequestState() == GLWebViewState::kNoScaleRequest
+ || m_glWebViewState->scaleRequestState() == GLWebViewState::kWillScheduleRequest
+ || m_glWebViewState->futureScale() != scale)) {
+ m_glWebViewState->scheduleUpdate(currentTime, scale);
+ }
+
+ float transparency = 1;
+ bool doSwap = false;
+
+ // Here we have to schedule the painting of the tiles corresponding
+ // to the new tiles for the new scale factor (see above)
+ if (m_glWebViewState->scaleRequestState() == GLWebViewState::kRequestNewScale
+ || m_glWebViewState->scaleRequestState() == GLWebViewState::kReceivedNewScale) {
+ TiledPage* nextTiledPage = m_glWebViewState->backPage();
+ nextTiledPage->setScale(scale);
+
+ // Check if the page is ready...
+ if (m_glWebViewState->scaleRequestState() == GLWebViewState::kRequestNewScale
+ && nextTiledPage->ready(firstTileX, firstTileY)) {
+ m_glWebViewState->setScaleRequestState(GLWebViewState::kReceivedNewScale);
+ }
+
+ // If the page is ready, display it. We do a short transition between
+ // the two pages (current one and future one with the new scale factor)
+ if (m_glWebViewState->scaleRequestState() == GLWebViewState::kReceivedNewScale) {
+ double transitionTime = m_glWebViewState->transitionTime(currentTime);
+ transparency = m_glWebViewState->transparency(currentTime);
+
+ float newTilesTransparency = 1;
+ if (scale < m_glWebViewState->currentScale())
+ newTilesTransparency = 1 - transparency;
+
+ nextTiledPage->draw(newTilesTransparency, viewport,
+ firstTileX, firstTileY);
+
+ // The transition between the two pages is finished, swap them
+ if (currentTime > transitionTime) {
+ m_glWebViewState->setCurrentScale(scale);
+ m_glWebViewState->resetTransitionTime();
+ doSwap = true;
+ }
+ } else {
+ // If the page is not ready, schedule it if needed.
+ nextTiledPage->prepare(goingDown, goingLeft, firstTileX, firstTileY);
+ }
+ }
+
+ // Display the current page
+ TiledPage* tiledPage = m_glWebViewState->frontPage();
+ tiledPage->setScale(m_glWebViewState->currentScale());
+ int originalTX = m_glWebViewState->originalTilesPosX();
+ int originalTY = m_glWebViewState->originalTilesPosY();
+ tiledPage->prepare(goingDown, goingLeft, originalTX, originalTY);
+ tiledPage->draw(transparency, viewport, originalTX, originalTY);
+
+ bool ret = false;
+ if (!tiledPage->ready(originalTX, originalTY)
+ || m_glWebViewState->scaleRequestState() != GLWebViewState::kNoScaleRequest)
+ ret = true;
+
+ if (doSwap)
+ m_glWebViewState->swapPages();
+
+ return ret;
+}
+#endif // USE(ACCELERATED_COMPOSITING)
+
+bool BaseLayerAndroid::drawGL(IntRect& viewRect, SkRect& visibleRect,
+ float scale, SkColor color)
+{
+ bool ret = false;
+#if USE(ACCELERATED_COMPOSITING)
+ int left = viewRect.x();
+ int top = viewRect.y();
+ int width = viewRect.width();
+ int height = viewRect.height();
+ XLOG("drawBasePicture drawGL() viewRect: %d, %d, %d, %d",
+ left, top, width, height);
+
+ glEnable(GL_SCISSOR_TEST);
+
+ glScissor(left, top, width, height);
+ glClearColor((float)SkColorGetR(color) / 255.0,
+ (float)SkColorGetG(color) / 255.0,
+ (float)SkColorGetB(color) / 255.0, 1);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glViewport(left, top, width, height);
+ ShaderProgram* shader = TilesManager::instance()->shader();
+ glUseProgram(shader->program());
+ glUniform1i(shader->textureSampler(), 0);
+
+ ret = drawBasePictureInGL(visibleRect, scale);
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ m_previousVisible = visibleRect;
+#endif // USE(ACCELERATED_COMPOSITING)
+ return ret;
+}
+
+} // namespace WebCore