blob: 685ca437ecc6827d00ab6d29edd449e6870957e2 [file] [log] [blame]
/*
* 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.
*/
#ifndef BaseTile_h
#define BaseTile_h
#if USE(ACCELERATED_COMPOSITING)
#include "BaseRenderer.h"
#include "SkRect.h"
#include "SkRegion.h"
#include "TextureOwner.h"
#include "TilePainter.h"
#include <utils/threads.h>
namespace WebCore {
class TextureInfo;
class TiledPage;
class BaseTileTexture;
class GLWebViewState;
/**
* An individual tile that is used to construct part of a webpage's BaseLayer of
* content. Each tile is assigned to a TiledPage and is responsible for drawing
* and displaying their section of the page. The lifecycle of a tile is:
*
* 1. Each tile is created on the main GL thread and assigned to a specific
* location within a TiledPage.
* 2. When needed the tile is passed to the background thread where it paints
* the BaseLayer's most recent PictureSet to a bitmap which is then uploaded
* to the GPU.
* 3. After the bitmap is uploaded to the GPU the main GL thread then uses the
* tile's draw() function to display the tile to the screen.
* 4. Steps 2-3 are repeated as necessary.
* 5. The tile is destroyed when the user navigates to a new page.
*
*/
class BaseTile : public TextureOwner {
public:
// eventually, m_dirty might be rolled into the state machine, but note
// that a tile that's continually marked dirty from animation should still
// progress through the state machine and be drawn periodically (esp. for
// layers)
// /-> TransferredUnvalidated (TQ interrupts paint) -\ (TQ & paint done)
// Unpainted -> PaintingStarted -- -> ReadyToSwap -> UpToDate
// ^ \-> ValidatedUntransferred (paint finish before TQ) -/
// |
// \--... (From any state when marked dirty. should usually come from UpToDate if the updates are locked)
//
enum TextureState{
// back texture is completely unpainted
Unpainted = 0,
// has started painting, but haven't been transferred or validated
PaintingStarted = 1,
// back texture painted, transferred before validating in PaintBitmap()
TransferredUnvalidated = 2,
// back texture painted, validated before transferring in TransferQueue
ValidatedUntransferred = 3,
// back texture has been blitted, will be swapped when next available
ReadyToSwap = 4,
// has been swapped, is ready to draw, all is well
UpToDate = 5,
};
BaseTile(bool isLayerTile = false);
~BaseTile();
bool isLayerTile() { return m_isLayerTile; }
void setContents(TilePainter* painter, int x, int y, float scale);
void setPage(TiledPage* page) { m_page = page; }
void reserveTexture();
bool isTileReady();
void draw(float transparency, SkRect& rect, float scale);
// the only thread-safe function called by the background thread
void paintBitmap();
bool intersectWithRect(int x, int y, int tileWidth, int tileHeight,
float scale, const SkRect& dirtyRect,
SkRect& realTileRect);
bool isTileVisible(const IntRect& viewTileBounds);
void markAsDirty(const unsigned int pictureCount,
const SkRegion& dirtyArea);
bool isDirty();
bool isRepaintPending();
void setRepaintPending(bool pending);
float scale() const { return m_scale; }
TextureState textureState() const { return m_state; }
int x() const { return m_x; }
int y() const { return m_y; }
BaseTileTexture* frontTexture() { return m_frontTexture; }
BaseTileTexture* backTexture() { return m_backTexture; }
// only used for prioritization - the higher, the more relevant the tile is
unsigned long long drawCount() { return m_drawCount; }
void discardTextures();
void discardBackTexture();
bool swapTexturesIfNeeded();
void backTextureTransfer();
void backTextureTransferFail();
void setGLWebViewState(GLWebViewState* state) { m_glWebViewState = state; }
// TextureOwner implementation
virtual bool removeTexture(BaseTileTexture* texture);
virtual TiledPage* page() { return m_page; }
virtual GLWebViewState* state() { return m_glWebViewState; }
TilePainter* painter() { return m_painter; }
private:
void validatePaint();
GLWebViewState* m_glWebViewState;
TilePainter* m_painter;
int m_x;
int m_y;
TiledPage* m_page;
// The remaining variables can be updated throughout the lifetime of the object
BaseTileTexture* m_frontTexture;
BaseTileTexture* m_backTexture;
float m_scale;
// used to signal that the that the tile is out-of-date and needs to be
// redrawn in the backTexture
bool m_dirty;
// currently only for debugging, to be used for tracking down dropped repaints
bool m_deferredDirty;
// used to signal that a repaint is pending
bool m_repaintPending;
// stores the id of the latest picture from webkit that caused this tile to
// become dirty. A tile is no longer dirty when it has been painted with a
// picture that is newer than this value.
unsigned int m_lastDirtyPicture;
// store the dirty region
SkRegion* m_dirtyArea;
bool* m_fullRepaint;
int m_maxBufferNumber;
int m_currentDirtyAreaIndex;
// flag used to know if we have a texture that was painted at least once
bool m_isTexturePainted;
// This mutex serves two purposes. (1) It ensures that certain operations
// happen atomically and (2) it makes sure those operations are synchronized
// across all threads and cores.
android::Mutex m_atomicSync;
BaseRenderer* m_renderer;
bool m_isLayerTile;
// the most recent GL draw before this tile was prepared. used for
// prioritization and caching. tiles with old drawcounts and textures they
// own are used for new tiles and rendering
unsigned long long m_drawCount;
// Tracks the state of painting for the tile. High level overview:
// 1) Unpainted - until paint starts (and if marked dirty, in most cases)
// 2) PaintingStarted - until paint completes
// 3) TransferredUnvalidated - if transferred first
// or ValidatedUntransferred - if validated first
// 4) ReadyToSwap - if painted and transferred, but not swapped
// 5) UpToDate - until marked dirty again
TextureState m_state;
};
} // namespace WebCore
#endif // USE(ACCELERATED_COMPOSITING)
#endif // BaseTile_h