1 /* 2 * Copyright 2011, 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 #define LOG_TAG "PaintTileOperation" 27 #define LOG_NDEBUG 1 28 29 #include "config.h" 30 #include "PaintTileOperation.h" 31 32 #include "AndroidLog.h" 33 #include "ClassTracker.h" 34 #include "GLWebViewState.h" 35 #include "ImageTexture.h" 36 #include "ImagesManager.h" 37 #include "LayerAndroid.h" 38 #include "TexturesGenerator.h" 39 #include "TilesManager.h" 40 41 namespace WebCore { 42 43 PaintTileOperation::PaintTileOperation(Tile* tile, TilePainter* painter, 44 GLWebViewState* state, bool isLowResPrefetch) 45 : m_tile(tile) 46 , m_painter(painter) 47 , m_state(state) 48 , m_isLowResPrefetch(isLowResPrefetch) 49 { 50 if (m_tile) 51 m_tile->setRepaintPending(true); 52 SkSafeRef(m_painter); 53 #ifdef DEBUG_COUNT 54 ClassTracker::instance()->increment("PaintTileOperation"); 55 #endif 56 } 57 58 PaintTileOperation::~PaintTileOperation() 59 { 60 if (m_tile) { 61 m_tile->setRepaintPending(false); 62 m_tile = 0; 63 } 64 65 if (m_painter && m_painter->type() == TilePainter::Image) { 66 ImageTexture* image = static_cast<ImageTexture*>(m_painter); 67 ImagesManager::instance()->releaseImage(image->imageCRC()); 68 } else { 69 SkSafeUnref(m_painter); 70 } 71 #ifdef DEBUG_COUNT 72 ClassTracker::instance()->decrement("PaintTileOperation"); 73 #endif 74 } 75 76 bool PaintTileOperation::operator==(const QueuedOperation* operation) 77 { 78 const PaintTileOperation* op = static_cast<const PaintTileOperation*>(operation); 79 return op->m_tile == m_tile; 80 } 81 82 void PaintTileOperation::run() 83 { 84 TRACE_METHOD(); 85 86 if (m_tile) { 87 m_tile->paintBitmap(m_painter); 88 m_tile->setRepaintPending(false); 89 m_tile = 0; 90 } 91 } 92 93 int PaintTileOperation::priority() 94 { 95 if (!m_tile) 96 return -1; 97 98 int priority = 200000; 99 100 // prioritize low res while scrolling, otherwise set priority above gDeferPriorityCutoff 101 if (m_isLowResPrefetch) 102 priority = m_state->isScrolling() ? 0 : TexturesGenerator::gDeferPriorityCutoff; 103 104 // prioritize higher draw count 105 unsigned long long currentDraw = TilesManager::instance()->getDrawGLCount(); 106 unsigned long long drawDelta = currentDraw - m_tile->drawCount(); 107 priority += 100000 * (int)std::min(drawDelta, (unsigned long long)1000); 108 109 // prioritize unpainted tiles, within the same drawCount 110 if (m_tile->frontTexture()) 111 priority += 50000; 112 113 // for base tiles, prioritize based on position 114 if (!m_tile->isLayerTile()) { 115 bool goingDown = m_state->goingDown(); 116 priority += m_tile->x(); 117 118 if (goingDown) 119 priority += 100000 - (1 + m_tile->y()) * 1000; 120 else 121 priority += m_tile->y() * 1000; 122 } 123 124 return priority; 125 } 126 127 void PaintTileOperation::updatePainter(TilePainter* painter) 128 { 129 if (m_painter == painter) 130 return; 131 132 SkSafeRef(painter); 133 SkSafeUnref(m_painter); 134 m_painter = painter; 135 } 136 137 } 138