summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/graphics/android/GLWebViewState.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/platform/graphics/android/GLWebViewState.cpp')
-rw-r--r--WebCore/platform/graphics/android/GLWebViewState.cpp574
1 files changed, 0 insertions, 574 deletions
diff --git a/WebCore/platform/graphics/android/GLWebViewState.cpp b/WebCore/platform/graphics/android/GLWebViewState.cpp
deleted file mode 100644
index 4acd563..0000000
--- a/WebCore/platform/graphics/android/GLWebViewState.cpp
+++ /dev/null
@@ -1,574 +0,0 @@
-/*
- * 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 "GLWebViewState.h"
-
-#if USE(ACCELERATED_COMPOSITING)
-
-#include "BaseLayerAndroid.h"
-#include "ClassTracker.h"
-#include "GLUtils.h"
-#include "LayerAndroid.h"
-#include "TilesManager.h"
-#include <wtf/CurrentTime.h>
-
-#include <cutils/log.h>
-#include <wtf/text/CString.h>
-
-#undef XLOGC
-#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "GLWebViewState", __VA_ARGS__)
-
-#ifdef DEBUG
-
-#undef XLOG
-#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "GLWebViewState", __VA_ARGS__)
-
-#else
-
-#undef XLOG
-#define XLOG(...)
-
-#endif // DEBUG
-
-#define FIRST_TILED_PAGE_ID 1
-#define SECOND_TILED_PAGE_ID 2
-
-#define FRAMERATE_CAP 0.01666 // We cap at 60 fps
-
-namespace WebCore {
-
-using namespace android;
-
-GLWebViewState::GLWebViewState(android::Mutex* buttonMutex)
- : m_scaleRequestState(kNoScaleRequest)
- , m_currentScale(1)
- , m_futureScale(1)
- , m_updateTime(-1)
- , m_transitionTime(-1)
- , m_baseLayer(0)
- , m_currentBaseLayer(0)
- , m_previouslyUsedRoot(0)
- , m_currentPictureCounter(0)
- , m_usePageA(true)
- , m_frameworkInval(0, 0, 0, 0)
- , m_frameworkLayersInval(0, 0, 0, 0)
- , m_globalButtonMutex(buttonMutex)
- , m_baseLayerUpdate(true)
- , m_backgroundColor(SK_ColorWHITE)
- , m_prevDrawTime(0)
- , m_displayRings(false)
- , m_focusRingTexture(-1)
-{
- m_viewport.setEmpty();
- m_previousViewport.setEmpty();
- m_futureViewportTileBounds.setEmpty();
- m_viewportTileBounds.setEmpty();
- m_preZoomBounds.setEmpty();
-
- m_tiledPageA = new TiledPage(FIRST_TILED_PAGE_ID, this);
- m_tiledPageB = new TiledPage(SECOND_TILED_PAGE_ID, this);
-#ifdef DEBUG_COUNT
- ClassTracker::instance()->increment("GLWebViewState");
-#endif
-#ifdef MEASURES_PERF
- m_timeCounter = 0;
- m_totalTimeCounter = 0;
- m_measurePerfs = false;
-#endif
-}
-
-GLWebViewState::~GLWebViewState()
-{
- // We have to destroy the two tiled pages first as their destructor
- // may depend on the existence of this GLWebViewState and some of its
- // instance variables in order to complete.
- // Explicitely, currently we need to have the m_currentBaseLayer around
- // in order to complete any pending paint operations (the tiled pages
- // will remove any pending operations, and wait if one is underway).
- delete m_tiledPageA;
- delete m_tiledPageB;
- SkSafeUnref(m_currentBaseLayer);
- SkSafeUnref(m_baseLayer);
- m_baseLayer = 0;
- m_currentBaseLayer = 0;
-#ifdef DEBUG_COUNT
- ClassTracker::instance()->decrement("GLWebViewState");
-#endif
-}
-
-void GLWebViewState::setBaseLayer(BaseLayerAndroid* layer, const SkRegion& inval,
- bool showVisualIndicator, bool isPictureAfterFirstLayout)
-{
- android::Mutex::Autolock lock(m_baseLayerLock);
- if (!layer || isPictureAfterFirstLayout) {
- m_tiledPageA->setUsable(false);
- m_tiledPageB->setUsable(false);
- }
- if (isPictureAfterFirstLayout) {
- m_baseLayerUpdate = true;
- m_invalidateRegion.setEmpty();
- }
- if (m_baseLayer && layer)
- m_baseLayer->swapExtra(layer);
-
- SkSafeRef(layer);
- SkSafeUnref(m_baseLayer);
- m_baseLayer = layer;
- if (m_baseLayer)
- m_baseLayer->setGLWebViewState(this);
-
- // We only update the layers if we are not currently
- // waiting for a tiledPage to be painted
- if (m_baseLayerUpdate) {
- SkSafeRef(layer);
- SkSafeUnref(m_currentBaseLayer);
- m_currentBaseLayer = layer;
- }
- m_displayRings = false;
- invalRegion(inval);
-
-#ifdef MEASURES_PERF
- if (m_measurePerfs && !showVisualIndicator)
- dumpMeasures();
- m_measurePerfs = showVisualIndicator;
-#endif
-
- TilesManager::instance()->setShowVisualIndicator(showVisualIndicator);
-}
-
-void GLWebViewState::setRings(Vector<IntRect>& rings, bool isPressed)
-{
- android::Mutex::Autolock lock(m_baseLayerLock);
- m_displayRings = true;
- m_rings = rings;
- m_ringsIsPressed = isPressed;
-}
-
-void GLWebViewState::invalRegion(const SkRegion& region)
-{
- SkRegion::Iterator iterator(region);
- while (!iterator.done()) {
- SkIRect r = iterator.rect();
- IntRect ir(r.fLeft, r.fTop, r.width(), r.height());
- inval(ir);
- iterator.next();
- }
-}
-
-void GLWebViewState::unlockBaseLayerUpdate() {
- if (m_baseLayerUpdate)
- return;
-
- m_baseLayerUpdate = true;
- android::Mutex::Autolock lock(m_baseLayerLock);
- SkSafeRef(m_baseLayer);
- SkSafeUnref(m_currentBaseLayer);
- m_currentBaseLayer = m_baseLayer;
-
- invalRegion(m_invalidateRegion);
- m_invalidateRegion.setEmpty();
-}
-
-void GLWebViewState::setExtra(BaseLayerAndroid* layer, SkPicture& picture,
- const IntRect& rect, bool allowSame)
-{
- android::Mutex::Autolock lock(m_baseLayerLock);
- if (!m_baseLayerUpdate)
- return;
-
- layer->setExtra(picture);
-
- if (!allowSame && m_lastInval == rect)
- return;
-
- if (!rect.isEmpty())
- inval(rect);
- if (!m_lastInval.isEmpty())
- inval(m_lastInval);
- m_lastInval = rect;
- m_displayRings = false;
-}
-
-void GLWebViewState::inval(const IntRect& rect)
-{
- if (m_baseLayerUpdate) {
- m_currentPictureCounter++;
- if (!rect.isEmpty()) {
- // find which tiles fall within the invalRect and mark them as dirty
- m_tiledPageA->invalidateRect(rect, m_currentPictureCounter);
- m_tiledPageB->invalidateRect(rect, m_currentPictureCounter);
- if (m_frameworkInval.isEmpty())
- m_frameworkInval = rect;
- else
- m_frameworkInval.unite(rect);
- XLOG("intermediate invalRect(%d, %d, %d, %d) after unite with rect %d %d %d %d", m_frameworkInval.x(),
- m_frameworkInval.y(), m_frameworkInval.right(), m_frameworkInval.bottom(),
- rect.x(), rect.y(), rect.right(), rect.bottom());
- }
- } else {
- m_invalidateRegion.op(rect.x(), rect.y(), rect.right(), rect.bottom(), SkRegion::kUnion_Op);
- }
-}
-
-void GLWebViewState::resetRings()
-{
- m_displayRings = false;
-}
-
-void GLWebViewState::drawFocusRing(IntRect& srcRect)
-{
- // TODO: use a 9-patch texture to draw the focus ring
- // instead of plain colors
- const float alpha = 0.3;
- float borderAlpha = 0.40;
-
- const int r = 104;
- const int g = 153;
- const int b = 255;
-
- int padding = 4;
- int border = 1;
- int fuzzyBorder = border * 2;
- if (!m_ringsIsPressed) {
- padding = 0;
- border = 2;
- fuzzyBorder = 3;
- borderAlpha = 0.2;
- }
- if (m_focusRingTexture == -1)
- m_focusRingTexture = GLUtils::createSampleColorTexture(r, g, b);
-
- SkRect rLeft, rTop, rRight, rBottom, rOverlay;
-
- IntRect rect(srcRect.x() - padding, srcRect.y() - padding,
- srcRect.width() + (padding * 2), srcRect.height() + (padding * 2));
- rLeft.set(rect.x() - border, rect.y(),
- rect.x(), rect.y() + rect.height());
- rTop.set(rect.x() - border, rect.y() - border,
- rect.x() + rect.width() + border, rect.y());
- rRight.set(rect.x() + rect.width(), rect.y(),
- rect.x() + rect.width() + border,
- rect.y() + rect.height());
- rBottom.set(rect.x() - border, rect.y() + rect.height(),
- rect.x() + rect.width() + border,
- rect.y() + rect.height() + border);
- rOverlay.set(rect.x() - fuzzyBorder, rect.y() - fuzzyBorder,
- rect.x() + rect.width() + fuzzyBorder,
- rect.y() + rect.height() + fuzzyBorder);
-
- TilesManager::instance()->shader()->drawQuad(rLeft, m_focusRingTexture, borderAlpha);
- TilesManager::instance()->shader()->drawQuad(rTop, m_focusRingTexture, borderAlpha);
- TilesManager::instance()->shader()->drawQuad(rRight, m_focusRingTexture, borderAlpha);
- TilesManager::instance()->shader()->drawQuad(rBottom, m_focusRingTexture, borderAlpha);
- if (m_ringsIsPressed) {
- TilesManager::instance()->shader()->drawQuad(rOverlay, m_focusRingTexture, alpha);
- } else {
- rLeft.set(rect.x() - fuzzyBorder, rect.y(),
- rect.x(), rect.y() + rect.height());
- rTop.set(rect.x() - fuzzyBorder, rect.y() - fuzzyBorder,
- rect.x() + rect.width() + fuzzyBorder, rect.y());
- rRight.set(rect.x() + rect.width(), rect.y(),
- rect.x() + rect.width() + fuzzyBorder,
- rect.y() + rect.height());
- rBottom.set(rect.x() - fuzzyBorder, rect.y() + rect.height(),
- rect.x() + rect.width() + fuzzyBorder,
- rect.y() + rect.height() + fuzzyBorder);
- TilesManager::instance()->shader()->drawQuad(rLeft, m_focusRingTexture, alpha);
- TilesManager::instance()->shader()->drawQuad(rTop, m_focusRingTexture, alpha);
- TilesManager::instance()->shader()->drawQuad(rRight, m_focusRingTexture, alpha);
- TilesManager::instance()->shader()->drawQuad(rBottom, m_focusRingTexture, alpha);
- }
-}
-
-void GLWebViewState::paintExtras()
-{
- if (m_displayRings) {
- // TODO: handles correctly the multi-rings case
- for (int i=0; i<m_rings.size(); i++) {
- IntRect rect = m_rings.at(i);
- drawFocusRing(rect);
- }
- }
-}
-
-unsigned int GLWebViewState::paintBaseLayerContent(SkCanvas* canvas)
-{
- android::Mutex::Autolock lock(m_baseLayerLock);
- if (m_currentBaseLayer) {
- m_globalButtonMutex->lock();
- m_currentBaseLayer->drawCanvas(canvas);
- m_globalButtonMutex->unlock();
- }
- return m_currentPictureCounter;
-}
-
-void GLWebViewState::scheduleUpdate(const double& currentTime,
- const SkIRect& viewport, float scale)
-{
- // if no update time, set it
- if (updateTime() == -1) {
- m_scaleRequestState = kWillScheduleRequest;
- setUpdateTime(currentTime + s_updateInitialDelay);
- setFutureScale(scale);
- setFutureViewport(viewport);
- return;
- }
-
- if (currentTime < updateTime())
- return;
-
- // we reached the scheduled update time, check if we can update
- if (futureScale() == scale) {
- // we are still with the previous scale, let's go
- // with the update
- m_scaleRequestState = kRequestNewScale;
- setUpdateTime(-1);
- } else {
- // we reached the update time, but the planned update was for
- // a different scale factor -- meaning the user is still probably
- // in the process of zooming. Let's push the update time a bit.
- setUpdateTime(currentTime + s_updateDelay);
- setFutureScale(scale);
- setFutureViewport(viewport);
- }
-}
-
-double GLWebViewState::zoomInTransitionTime(double currentTime)
-{
- if (m_transitionTime == -1)
- m_transitionTime = currentTime + s_zoomInTransitionDelay;
- return m_transitionTime;
-}
-
-double GLWebViewState::zoomOutTransitionTime(double currentTime)
-{
- if (m_transitionTime == -1)
- m_transitionTime = currentTime + s_zoomOutTransitionDelay;
- return m_transitionTime;
-}
-
-
-float GLWebViewState::zoomInTransparency(double currentTime)
-{
- float t = zoomInTransitionTime(currentTime) - currentTime;
- t *= s_invZoomInTransitionDelay;
- return fmin(1, fmax(0, t));
-}
-
-float GLWebViewState::zoomOutTransparency(double currentTime)
-{
- float t = zoomOutTransitionTime(currentTime) - currentTime;
- t *= s_invZoomOutTransitionDelay;
- return fmin(1, fmax(0, t));
-}
-
-TiledPage* GLWebViewState::sibling(TiledPage* page)
-{
- return (page == m_tiledPageA) ? m_tiledPageB : m_tiledPageA;
-}
-
-TiledPage* GLWebViewState::frontPage()
-{
- android::Mutex::Autolock lock(m_tiledPageLock);
- return m_usePageA ? m_tiledPageA : m_tiledPageB;
-}
-
-TiledPage* GLWebViewState::backPage()
-{
- android::Mutex::Autolock lock(m_tiledPageLock);
- return m_usePageA ? m_tiledPageB : m_tiledPageA;
-}
-
-void GLWebViewState::swapPages()
-{
- android::Mutex::Autolock lock(m_tiledPageLock);
- m_usePageA ^= true;
- TiledPage* working = m_usePageA ? m_tiledPageB : m_tiledPageA;
- if (m_scaleRequestState != kNoScaleRequest)
- TilesManager::instance()->resetTextureUsage(working);
-
- m_scaleRequestState = kNoScaleRequest;
-}
-
-int GLWebViewState::baseContentWidth()
-{
- return m_currentBaseLayer ? m_currentBaseLayer->getWidth() : 0;
-
-}
-int GLWebViewState::baseContentHeight()
-{
- return m_currentBaseLayer ? m_currentBaseLayer->getHeight() : 0;
-}
-
-void GLWebViewState::setViewport(SkRect& viewport, float scale)
-{
- m_previousViewport = m_viewport;
- if ((m_viewport == viewport) &&
- (m_futureScale == scale))
- return;
-
- m_viewport = viewport;
- XLOG("New VIEWPORT %.2f - %.2f %.2f - %.2f (w: %2.f h: %.2f scale: %.2f currentScale: %.2f futureScale: %.2f)",
- m_viewport.fLeft, m_viewport.fTop, m_viewport.fRight, m_viewport.fBottom,
- m_viewport.width(), m_viewport.height(), scale, m_currentScale, m_futureScale);
-
- const float invTileContentWidth = scale / TilesManager::tileWidth();
- const float invTileContentHeight = scale / TilesManager::tileHeight();
-
- m_viewportTileBounds.set(
- static_cast<int>(floorf(viewport.fLeft * invTileContentWidth)),
- static_cast<int>(floorf(viewport.fTop * invTileContentHeight)),
- static_cast<int>(ceilf(viewport.fRight * invTileContentWidth)),
- static_cast<int>(ceilf(viewport.fBottom * invTileContentHeight)));
-
- int maxTextureCount = (m_viewportTileBounds.width() + TilesManager::instance()->expandedTileBoundsX() * 2 + 1) *
- (m_viewportTileBounds.height() + TilesManager::instance()->expandedTileBoundsY() * 2 + 1) * 2;
- TilesManager::instance()->setMaxTextureCount(maxTextureCount);
- m_tiledPageA->updateBaseTileSize();
- m_tiledPageB->updateBaseTileSize();
-}
-
-#ifdef MEASURES_PERF
-void GLWebViewState::dumpMeasures()
-{
- for (int i = 0; i < m_timeCounter; i++) {
- XLOGC("%d delay: %d ms", m_totalTimeCounter + i,
- static_cast<int>(m_delayTimes[i]*1000));
- m_delayTimes[i] = 0;
- }
- m_totalTimeCounter += m_timeCounter;
- m_timeCounter = 0;
-}
-#endif // MEASURES_PERF
-
-void GLWebViewState::resetFrameworkInval()
-{
- m_frameworkInval.setX(0);
- m_frameworkInval.setY(0);
- m_frameworkInval.setWidth(0);
- m_frameworkInval.setHeight(0);
-}
-
-void GLWebViewState::addDirtyArea(const IntRect& rect)
-{
- if (rect.isEmpty())
- return;
-
- IntRect inflatedRect = rect;
- inflatedRect.inflate(8);
- if (m_frameworkLayersInval.isEmpty())
- m_frameworkLayersInval = inflatedRect;
- else
- m_frameworkLayersInval.unite(inflatedRect);
-}
-
-void GLWebViewState::resetLayersDirtyArea()
-{
- m_frameworkLayersInval.setX(0);
- m_frameworkLayersInval.setY(0);
- m_frameworkLayersInval.setWidth(0);
- m_frameworkLayersInval.setHeight(0);
-}
-
-bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect,
- IntRect& webViewRect, int titleBarHeight,
- IntRect& clip, float scale, SkColor color)
-{
- glFinish();
-
- double currentTime = WTF::currentTime();
- double delta = currentTime - m_prevDrawTime;
-
- if (delta < FRAMERATE_CAP) {
- unsigned int usecs = (FRAMERATE_CAP - delta) * 1E6;
- usleep(usecs);
- }
-
- m_prevDrawTime = currentTime;
-
- m_baseLayerLock.lock();
- BaseLayerAndroid* baseLayer = m_currentBaseLayer;
- SkSafeRef(baseLayer);
- BaseLayerAndroid* baseForComposited = m_baseLayer;
- SkSafeRef(baseForComposited);
- m_baseLayerLock.unlock();
- if (!baseLayer) {
- SkSafeUnref(baseForComposited);
- return false;
- }
-
- XLOG("drawGL, rect(%d, %d, %d, %d), viewport(%.2f, %.2f, %.2f, %.2f)",
- rect.x(), rect.y(), rect.right(), rect.bottom(),
- viewport.fLeft, viewport.fTop, viewport.fRight, viewport.fBottom);
-
- resetLayersDirtyArea();
-
- if (!baseForComposited ||
- (baseForComposited && !baseForComposited->countChildren())) {
- SkSafeRef(baseLayer);
- SkSafeUnref(baseForComposited);
- baseForComposited = baseLayer;
- }
-
- LayerAndroid* compositedRoot = 0;
- if (baseForComposited && baseForComposited->countChildren() >= 1)
- compositedRoot = static_cast<LayerAndroid*>(baseForComposited->getChild(0));
-
- bool ret = baseLayer->drawGL(compositedRoot, rect, viewport, webViewRect, titleBarHeight, clip, scale, color);
- m_previouslyUsedRoot = compositedRoot;
- if (ret) {
- FloatRect frameworkInval = TilesManager::instance()->shader()->rectInInvScreenCoord(m_frameworkInval);
- IntRect inval(frameworkInval.x(), frameworkInval.y(), frameworkInval.width(), frameworkInval.height());
-
- inval.unite(m_frameworkLayersInval);
-
- invalRect->setX(inval.x());
- invalRect->setY(inval.y());
- invalRect->setWidth(inval.width());
- invalRect->setHeight(inval.height());
-
- XLOG("invalRect(%d, %d, %d, %d)", inval.x(),
- inval.y(), inval.right(), inval.bottom());
- } else {
- resetFrameworkInval();
- }
-
-#ifdef MEASURES_PERF
- if (m_measurePerfs) {
- m_delayTimes[m_timeCounter++] = delta;
- if (m_timeCounter >= MAX_MEASURES_PERF)
- dumpMeasures();
- }
-#endif
-
- SkSafeUnref(baseForComposited);
- SkSafeUnref(baseLayer);
- return ret;
-}
-
-} // namespace WebCore
-
-#endif // USE(ACCELERATED_COMPOSITING)