summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform/graphics
diff options
context:
space:
mode:
authorNicolas Roard <nicolasroard@google.com>2011-12-01 07:43:52 -0800
committerAndroid Git Automerger <android-git-automerger@android.com>2011-12-01 07:43:52 -0800
commit931e90d171935ef706b6906c5867a51fc491a83d (patch)
tree4321841ab956b65cfe508bc824e7d0fc6eaaff15 /Source/WebCore/platform/graphics
parent6dd76bd83b84be93653706342d235c4377b40e62 (diff)
parentf1a221194f2b0d5fd82d2e98ced94f0553c45986 (diff)
downloadexternal_webkit-931e90d171935ef706b6906c5867a51fc491a83d.zip
external_webkit-931e90d171935ef706b6906c5867a51fc491a83d.tar.gz
external_webkit-931e90d171935ef706b6906c5867a51fc491a83d.tar.bz2
am f1a22119: Merge "Fix image layer codepath" into ics-mr1
* commit 'f1a221194f2b0d5fd82d2e98ced94f0553c45986': Fix image layer codepath
Diffstat (limited to 'Source/WebCore/platform/graphics')
-rw-r--r--Source/WebCore/platform/graphics/android/BaseTile.cpp2
-rw-r--r--Source/WebCore/platform/graphics/android/ClassTracker.cpp21
-rw-r--r--Source/WebCore/platform/graphics/android/GLWebViewState.cpp9
-rw-r--r--Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp28
-rw-r--r--Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h2
-rw-r--r--Source/WebCore/platform/graphics/android/ImageTexture.cpp214
-rw-r--r--Source/WebCore/platform/graphics/android/ImageTexture.h69
-rw-r--r--Source/WebCore/platform/graphics/android/ImagesManager.cpp108
-rw-r--r--Source/WebCore/platform/graphics/android/ImagesManager.h16
-rw-r--r--Source/WebCore/platform/graphics/android/LayerAndroid.cpp71
-rw-r--r--Source/WebCore/platform/graphics/android/LayerAndroid.h7
-rw-r--r--Source/WebCore/platform/graphics/android/PaintTileOperation.cpp12
-rw-r--r--Source/WebCore/platform/graphics/android/PaintTileOperation.h8
-rw-r--r--Source/WebCore/platform/graphics/android/PaintedSurface.h4
-rw-r--r--Source/WebCore/platform/graphics/android/TilePainter.h10
-rw-r--r--Source/WebCore/platform/graphics/android/TiledTexture.cpp14
-rw-r--r--Source/WebCore/platform/graphics/android/TiledTexture.h10
-rw-r--r--Source/WebCore/platform/graphics/android/TilesManager.cpp17
-rw-r--r--Source/WebCore/platform/graphics/android/TilesManager.h2
19 files changed, 421 insertions, 203 deletions
diff --git a/Source/WebCore/platform/graphics/android/BaseTile.cpp b/Source/WebCore/platform/graphics/android/BaseTile.cpp
index a331dfc..df96657 100644
--- a/Source/WebCore/platform/graphics/android/BaseTile.cpp
+++ b/Source/WebCore/platform/graphics/android/BaseTile.cpp
@@ -268,7 +268,7 @@ void BaseTile::draw(float transparency, SkRect& rect, float scale)
}
if (m_frontTexture->readyFor(this)) {
- if (isLayerTile())
+ if (isLayerTile() && m_painter && m_painter->transform())
TilesManager::instance()->shader()->drawLayerQuad(*m_painter->transform(),
rect, m_frontTexture->m_ownTextureId,
transparency, true);
diff --git a/Source/WebCore/platform/graphics/android/ClassTracker.cpp b/Source/WebCore/platform/graphics/android/ClassTracker.cpp
index 92d406c..eb810a8 100644
--- a/Source/WebCore/platform/graphics/android/ClassTracker.cpp
+++ b/Source/WebCore/platform/graphics/android/ClassTracker.cpp
@@ -27,6 +27,7 @@
#include "ClassTracker.h"
#include "LayerAndroid.h"
+#include "TilesManager.h"
#include <cutils/log.h>
#include <wtf/CurrentTime.h>
@@ -35,6 +36,9 @@
#undef XLOG
#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "ClassTracker", __VA_ARGS__)
+#define DEBUG_LAYERS
+#undef DEBUG_LAYERS
+
namespace WebCore {
ClassTracker* ClassTracker::instance()
@@ -66,7 +70,6 @@ void ClassTracker::decrement(String name)
m_classes.set(name, value - 1);
}
-
void ClassTracker::add(LayerAndroid* layer)
{
android::Mutex::Autolock lock(m_lock);
@@ -88,6 +91,21 @@ void ClassTracker::show()
iter->first.latin1().data(), iter->second);
}
XLOG("*** %d Layers ***", m_layers.size());
+ int nbTextures = 0;
+ int nbAllocatedTextures = 0;
+ int nbLayerTextures = 0;
+ int nbAllocatedLayerTextures = 0;
+ float textureSize = 256 * 256 * 4 / 1024.0 / 1024.0;
+ TilesManager::instance()->gatherTexturesNumbers(&nbTextures, &nbAllocatedTextures,
+ &nbLayerTextures, &nbAllocatedLayerTextures);
+ XLOG("*** textures: %d/%d (%.2f Mb), layer textures: %d/%d (%.2f Mb) : total used %.2f Mb",
+ nbAllocatedTextures, nbTextures,
+ nbAllocatedTextures * textureSize,
+ nbAllocatedLayerTextures, nbLayerTextures,
+ nbAllocatedLayerTextures * textureSize,
+ (nbAllocatedTextures + nbAllocatedLayerTextures) * textureSize);
+
+#ifdef DEBUG_LAYERS
for (unsigned int i = 0; i < m_layers.size(); i++) {
LayerAndroid* layer = m_layers[i];
XLOG("[%d/%d] layer %x (%.2f, %.2f) of type %d, refcount(%d) has texture %x has image ref %x (%x) root: %x parent: %x",
@@ -98,6 +116,7 @@ void ClassTracker::show()
layer->imageTexture(), (LayerAndroid*) layer->getRootLayer(),
(LayerAndroid*) layer->getParent());
}
+#endif
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
index 4820120..cf91c00 100644
--- a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
+++ b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
@@ -479,7 +479,7 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect,
// Upload any pending ImageTexture
// Return true if we still have some images to upload.
// TODO: upload as many textures as possible within a certain time limit
- bool ret = ImagesManager::instance()->uploadTextures();
+ bool ret = ImagesManager::instance()->prepareTextures(this);
if (scale < MIN_SCALE_WARNING || scale > MAX_SCALE_WARNING) {
XLOGC("WARNING, scale seems corrupted after update: %e", scale);
@@ -501,6 +501,13 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect,
if (!ret)
resetFrameworkInval();
+ int nbTexturesForImages = ImagesManager::instance()->nbTextures();
+ XLOG("*** We have %d textures for images, %d full, %d clipped, total %d / %d",
+ nbTexturesForImages, nbTexturesNeeded.full, nbTexturesNeeded.clipped,
+ nbTexturesNeeded.full + nbTexturesForImages,
+ nbTexturesNeeded.clipped + nbTexturesForImages);
+ nbTexturesNeeded.full += nbTexturesForImages;
+ nbTexturesNeeded.clipped += nbTexturesForImages;
ret |= setLayersRenderingMode(nbTexturesNeeded);
FloatRect extrasclip(0, 0, rect.width(), rect.height());
diff --git a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
index 44c9a2d..de9fcae 100644
--- a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
@@ -119,8 +119,8 @@ GraphicsLayerAndroid::GraphicsLayerAndroid(GraphicsLayerClient* client) :
m_needsRepaint(false),
m_needsNotifyClient(false),
m_haveContents(false),
- m_haveImage(false),
m_newImage(false),
+ m_image(0),
m_foregroundLayer(0),
m_foregroundClipLayer(0)
{
@@ -132,6 +132,9 @@ GraphicsLayerAndroid::GraphicsLayerAndroid(GraphicsLayerClient* client) :
GraphicsLayerAndroid::~GraphicsLayerAndroid()
{
+ if (m_image)
+ m_image->deref();
+
m_contentLayer->unref();
SkSafeUnref(m_foregroundLayer);
SkSafeUnref(m_foregroundClipLayer);
@@ -557,7 +560,7 @@ bool GraphicsLayerAndroid::repaint()
LOG("(%x) repaint(), gPaused(%d) m_needsRepaint(%d) m_haveContents(%d) ",
this, gPaused, m_needsRepaint, m_haveContents);
- if (!gPaused && m_haveContents && m_needsRepaint && !m_haveImage) {
+ if (!gPaused && m_haveContents && m_needsRepaint && !m_image) {
// with SkPicture, we request the entire layer's content.
IntRect layerBounds(0, 0, m_size.width(), m_size.height());
@@ -639,7 +642,7 @@ bool GraphicsLayerAndroid::repaint()
return true;
}
- if (m_needsRepaint && m_haveImage && m_newImage) {
+ if (m_needsRepaint && m_image && m_newImage) {
// We need to tell the GL thread that we will need to repaint the
// texture. Only do so if we effectively have a new image!
m_contentLayer->markAsDirty(m_dirtyRegion);
@@ -672,7 +675,7 @@ void GraphicsLayerAndroid::setNeedsDisplayInRect(const FloatRect& rect)
{
// rect is in the render object coordinates
- if (!m_haveImage && !drawsContent()) {
+ if (!m_image && !drawsContent()) {
LOG("(%x) setNeedsDisplay(%.2f,%.2f,%.2f,%.2f) doesn't have content, bypass...",
this, rect.x(), rect.y(), rect.width(), rect.height());
return;
@@ -836,14 +839,23 @@ void GraphicsLayerAndroid::resumeAnimations()
void GraphicsLayerAndroid::setContentsToImage(Image* image)
{
TLOG("(%x) setContentsToImage", this, image);
- if (image) {
+ if (image && image != m_image) {
+ image->ref();
+ if (m_image)
+ m_image->deref();
+ m_image = image;
+
+ SkBitmapRef* bitmap = image->nativeImageForCurrentFrame();
+ m_contentLayer->setContentsImage(bitmap);
+
m_haveContents = true;
- m_haveImage = true;
m_newImage = true;
- m_contentLayer->setContentsImage(image->nativeImageForCurrentFrame());
}
- if (m_haveImage && !image)
+ if (!image && m_image) {
m_contentLayer->setContentsImage(0);
+ m_image->deref();
+ m_image = 0;
+ }
setNeedsDisplay();
askForSync();
diff --git a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
index af8d7ce..358f674 100644
--- a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
@@ -145,8 +145,8 @@ private:
bool m_needsNotifyClient;
bool m_haveContents;
- bool m_haveImage;
bool m_newImage;
+ Image* m_image;
SkRegion m_dirtyRegion;
diff --git a/Source/WebCore/platform/graphics/android/ImageTexture.cpp b/Source/WebCore/platform/graphics/android/ImageTexture.cpp
index 96f7713..23e3899 100644
--- a/Source/WebCore/platform/graphics/android/ImageTexture.cpp
+++ b/Source/WebCore/platform/graphics/android/ImageTexture.cpp
@@ -27,8 +27,11 @@
#include "ImageTexture.h"
#include "ImagesManager.h"
+#include "LayerAndroid.h"
#include "SkDevice.h"
+#include "SkPicture.h"
#include "TilesManager.h"
+#include "TiledTexture.h"
#include <cutils/log.h>
#include <wtf/CurrentTime.h>
@@ -51,96 +54,201 @@
namespace WebCore {
-ImageTexture::ImageTexture(SkBitmapRef* img)
- : m_imageRef(img)
- , m_image(0)
- , m_textureId(0)
- , m_refCount(0)
+// CRC computation adapted from Tools/DumpRenderTree/CyclicRedundancyCheck.cpp
+static void makeCrcTable(unsigned crcTable[256])
+{
+ for (unsigned i = 0; i < 256; i++) {
+ unsigned c = i;
+ for (int k = 0; k < 8; k++) {
+ if (c & 1)
+ c = -306674912 ^ ((c >> 1) & 0x7fffffff);
+ else
+ c = c >> 1;
+ }
+ crcTable[i] = c;
+ }
+}
+
+unsigned computeCrc(uint8_t* buffer, size_t size)
+{
+ static unsigned crcTable[256];
+ static bool crcTableComputed = false;
+ if (!crcTableComputed) {
+ makeCrcTable(crcTable);
+ crcTableComputed = true;
+ }
+
+ unsigned crc = 0xffffffffL;
+ for (size_t i = 0; i < size; ++i)
+ crc = crcTable[(crc ^ buffer[i]) & 0xff] ^ ((crc >> 8) & 0x00ffffffL);
+ return crc ^ 0xffffffffL;
+}
+
+ImageTexture::ImageTexture(SkBitmap* bmp, unsigned crc)
+ : m_image(bmp)
+ , m_texture(0)
+ , m_layer(0)
+ , m_picture(0)
+ , m_crc(crc)
{
#ifdef DEBUG_COUNT
ClassTracker::instance()->increment("ImageTexture");
#endif
- if (!m_imageRef)
+ if (!m_image)
return;
- SkBitmap* bitmap = &m_imageRef->bitmap();
- m_image = new SkBitmap();
+ // NOTE: This constructor is called on the webcore thread
+
+ // Create a picture containing the image (needed for TiledTexture)
+ m_picture = new SkPicture();
+ SkCanvas* pcanvas = m_picture->beginRecording(m_image->width(), m_image->height());
+ pcanvas->clear(SkColorSetARGBInline(0, 0, 0, 0));
+ pcanvas->drawBitmap(*m_image, 0, 0);
+ m_picture->endRecording();
+}
+
+ImageTexture::~ImageTexture()
+{
+#ifdef DEBUG_COUNT
+ ClassTracker::instance()->decrement("ImageTexture");
+#endif
+ delete m_image;
+ delete m_texture;
+ SkSafeUnref(m_picture);
+}
+
+SkBitmap* ImageTexture::convertBitmap(SkBitmap* bitmap)
+{
+ SkBitmap* img = new SkBitmap();
int w = bitmap->width();
int h = bitmap->height();
- m_image->setConfig(SkBitmap::kARGB_8888_Config, w, h);
- m_image->allocPixels();
- SkDevice* device = new SkDevice(NULL, *m_image, false);
+
+ // Create a copy of the image
+ img->setConfig(SkBitmap::kARGB_8888_Config, w, h);
+ img->allocPixels();
+ SkDevice* device = new SkDevice(NULL, *img, false);
SkCanvas canvas;
canvas.setDevice(device);
device->unref();
SkRect dest;
dest.set(0, 0, w, h);
- m_image->setIsOpaque(false);
- m_image->eraseARGB(0, 0, 0, 0);
+ img->setIsOpaque(false);
+ img->eraseARGB(0, 0, 0, 0);
canvas.drawBitmapRect(*bitmap, 0, dest);
+
+ return img;
}
-ImageTexture::~ImageTexture()
+unsigned ImageTexture::computeCRC(const SkBitmap* bitmap)
{
-#ifdef DEBUG_COUNT
- ClassTracker::instance()->decrement("ImageTexture");
-#endif
- delete m_image;
+ if (!bitmap)
+ return 0;
+ bitmap->lockPixels();
+ uint8_t* img = static_cast<uint8_t*>(bitmap->getPixels());
+ unsigned crc = computeCrc(img, bitmap->getSize());
+ bitmap->unlockPixels();
+ return crc;
}
-void ImageTexture::prepareGL()
+bool ImageTexture::equalsCRC(unsigned crc)
{
- if (m_textureId)
- return;
-
- ImagesManager::instance()->scheduleTextureUpload(this);
+ return m_crc == crc;
}
-void ImageTexture::uploadGLTexture()
+int ImageTexture::nbTextures()
{
- if (m_textureId)
- return;
-
- glGenTextures(1, &m_textureId);
- GLUtils::createTextureWithBitmap(m_textureId, *m_image);
+ if (!hasContentToShow())
+ return 0;
+ if (!m_texture)
+ return 0;
+
+ // TODO: take in account the visible clip (need to maintain
+ // a list of the clients layer, etc.)
+ IntRect visibleArea(0, 0, m_image->width(), m_image->height());
+ int nbTextures = m_texture->nbTextures(visibleArea, 1.0);
+ XLOG("ImageTexture %p, %d x %d needs %d textures",
+ this, m_image->width(), m_image->height(),
+ nbTextures);
+ return nbTextures;
}
-void ImageTexture::drawGL(LayerAndroid* layer)
+bool ImageTexture::hasContentToShow()
{
- if (!layer)
- return;
- if (!m_textureId)
- return;
+ // Don't display 1x1 image -- no need to allocate a full texture for this
if (!m_image)
- return;
+ return false;
+ if (m_image->width() == 1 && m_image->height() == 1)
+ return false;
+ return true;
+}
- SkRect rect;
- rect.fLeft = 0;
- rect.fTop = 0;
- rect.fRight = layer->getSize().width();
- rect.fBottom = layer->getSize().height();
- TilesManager::instance()->shader()->drawLayerQuad(*layer->drawTransform(),
- rect, m_textureId,
- layer->drawOpacity(), true);
+bool ImageTexture::prepareGL(GLWebViewState* state)
+{
+ if (!hasContentToShow())
+ return false;
+
+ if (!m_texture && m_picture) {
+ m_texture = new TiledTexture(this);
+ SkRegion region;
+ region.setRect(0, 0, m_image->width(), m_image->height());
+ m_texture->update(region, m_picture);
+ }
+
+ if (!m_texture)
+ return false;
+
+ IntRect visibleArea(0, 0, m_image->width(), m_image->height());
+ m_texture->prepare(state, 1.0, true, true, visibleArea);
+ if (m_texture->ready()) {
+ m_texture->swapTiles();
+ return false;
+ }
+ return true;
}
-void ImageTexture::drawCanvas(SkCanvas* canvas, SkRect& rect)
+const TransformationMatrix* ImageTexture::transform()
{
- canvas->drawBitmapRect(*m_image, 0, rect);
+ if (!m_layer)
+ return 0;
+
+ FloatPoint p(0, 0);
+ p = m_layer->drawTransform()->mapPoint(p);
+ IntRect layerArea = m_layer->unclippedArea();
+ float scaleW = static_cast<float>(layerArea.width()) / static_cast<float>(m_image->width());
+ float scaleH = static_cast<float>(layerArea.height()) / static_cast<float>(m_image->height());
+ TransformationMatrix d = *(m_layer->drawTransform());
+ TransformationMatrix m;
+ m.scaleNonUniform(scaleW, scaleH);
+ m_layerMatrix = d.multiply(m);
+ return &m_layerMatrix;
}
-void ImageTexture::release()
+float ImageTexture::opacity()
{
- if (m_refCount >= 1)
- m_refCount--;
- if (!m_refCount)
- deleteTexture();
+ if (!m_layer)
+ return 1.0;
+ return m_layer->drawOpacity();
}
-void ImageTexture::deleteTexture()
+void ImageTexture::drawGL(LayerAndroid* layer)
+{
+ if (!layer)
+ return;
+ if (!hasContentToShow())
+ return;
+
+ // TiledTexture::draw() will call us back to know the
+ // transform and opacity, so we need to set m_layer
+ m_layer = layer;
+ if (m_texture)
+ m_texture->draw();
+ m_layer = 0;
+}
+
+void ImageTexture::drawCanvas(SkCanvas* canvas, SkRect& rect)
{
- if (m_textureId)
- glDeleteTextures(1, &m_textureId);
+ if (canvas && m_image)
+ canvas->drawBitmapRect(*m_image, 0, rect);
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/ImageTexture.h b/Source/WebCore/platform/graphics/android/ImageTexture.h
index cea79c3..6c6a075 100644
--- a/Source/WebCore/platform/graphics/android/ImageTexture.h
+++ b/Source/WebCore/platform/graphics/android/ImageTexture.h
@@ -29,57 +29,78 @@
#include "GLUtils.h"
#include "SkBitmap.h"
#include "SkBitmapRef.h"
+#include "SkPicture.h"
#include "SkRefCnt.h"
#include "LayerAndroid.h"
namespace WebCore {
class LayerAndroid;
+class TexturesResult;
+class TiledTexture;
/////////////////////////////////////////////////////////////////////////////////
// Image sharing codepath for layers
/////////////////////////////////////////////////////////////////////////////////
//
-// We receive an SkBitmapRef on the webcore thread; from this we create
-// an ImageTexture instance and keep it in TilesManager in a hashmap
-// (see TilesManager::addImage())
+// Layers containing only an image take a slightly different codepath;
+// GraphicsLayer::setContentsToImage() is called on the webcore thread,
+// passing an Image instance. We get the native image (an SkBitmap) and create
+// an ImageTexture instance with it (or increment the refcount of an existing
+// instance if the SkBitmap is similar to one already stored in ImagesManager,
+// i.e. if two GraphicsLayer share the same image).
//
-// The ImageTexture will recopy the pointed SkBitmap locally (so we can safely
-// use it on the texture generation thread), and just use the SkBitmapRef as a
-// key.
+// To detect if an image is similar, we compute and use a CRC. Each ImageTexture
+// is stored in ImagesManager using its CRC as a hash key.
+// Simply comparing the address is not enough -- different image could end up
+// at the same address (i.e. the image is deallocated then a new one is
+// reallocated at the old address)
//
-// Layers on the shared image path will ask TilesManager for the corresponding
-// ImageTexture, instead of using a PaintedSurface+TiledTexture.
-// When the ImageTexture is prepared for the first time, we directly upload
-// the bitmap to a texture.
+// Each ImageTexture's CRC being unique, LayerAndroid instances simply store that
+// and retain/release the corresponding ImageTexture (so that
+// queued painting request will work correctly and not crash...).
+// LayerAndroid running on the UI thread will get the corresponding
+// ImageTexture at draw time.
//
-// TODO: limit how many ImageTextures can be uploaded in one draw cycle
-// TODO: limit the size of ImageTextures (use a TiledTexture when needed)
+// ImageTexture recopy the original SkBitmap so that they can safely be used
+// on a different thread; it uses TiledTexture to allocate and paint the image,
+// so that we can share the same textures and limits as the rest of the layers.
//
/////////////////////////////////////////////////////////////////////////////////
-class ImageTexture {
+class ImageTexture : public SurfacePainter {
public:
- ImageTexture(SkBitmapRef* img);
+ ImageTexture(SkBitmap* bmp, unsigned crc);
virtual ~ImageTexture();
- void prepareGL();
- void uploadGLTexture();
+ bool prepareGL(GLWebViewState*);
void drawGL(LayerAndroid* painter);
void drawCanvas(SkCanvas*, SkRect&);
- void retain() { m_refCount++; }
- void release();
- unsigned int refCount() { return m_refCount; }
- SkBitmapRef* imageRef() { return m_imageRef; }
+ bool hasContentToShow();
SkBitmap* bitmap() { return m_image; }
+ unsigned imageCRC() { return m_crc; }
-private:
+ static SkBitmap* convertBitmap(SkBitmap* bitmap);
+
+ static unsigned computeCRC(const SkBitmap* bitmap);
+ bool equalsCRC(unsigned crc);
+
+ // methods used by TiledTexture
+ virtual const TransformationMatrix* transform();
+ virtual float opacity();
- void deleteTexture();
+ int nbTextures();
+
+ virtual SurfaceType type() { return SurfacePainter::ImageSurface; }
+
+private:
SkBitmapRef* m_imageRef;
SkBitmap* m_image;
- GLuint m_textureId;
- unsigned int m_refCount;
+ TiledTexture* m_texture;
+ LayerAndroid* m_layer;
+ SkPicture* m_picture;
+ TransformationMatrix m_layerMatrix;
+ unsigned m_crc;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/ImagesManager.cpp b/Source/WebCore/platform/graphics/android/ImagesManager.cpp
index 21f9fe9..65c41d1 100644
--- a/Source/WebCore/platform/graphics/android/ImagesManager.cpp
+++ b/Source/WebCore/platform/graphics/android/ImagesManager.cpp
@@ -26,6 +26,9 @@
#include "config.h"
#include "ImagesManager.h"
+#include "SkCanvas.h"
+#include "SkDevice.h"
+#include "SkRefCnt.h"
#include "ImageTexture.h"
#include <cutils/log.h>
@@ -59,71 +62,88 @@ ImagesManager* ImagesManager::instance()
ImagesManager* ImagesManager::gInstance = 0;
-void ImagesManager::addImage(SkBitmapRef* imgRef)
+ImageTexture* ImagesManager::setImage(SkBitmapRef* imgRef)
{
if (!imgRef)
- return;
+ return 0;
+
+ SkBitmap* bitmap = &imgRef->bitmap();
+ ImageTexture* image = 0;
+ SkBitmap* img = 0;
+ unsigned crc = 0;
+
+ img = ImageTexture::convertBitmap(bitmap);
+ crc = ImageTexture::computeCRC(img);
+
+ {
+ android::Mutex::Autolock lock(m_imagesLock);
+ if (m_images.contains(crc)) {
+ image = m_images.get(crc);
+ SkSafeRef(image);
+ return image;
+ }
+ }
+
+ // the image is not in the map, we add it
+
+ image = new ImageTexture(img, crc);
android::Mutex::Autolock lock(m_imagesLock);
- if (!m_images.contains(imgRef))
- m_images.set(imgRef, new ImageTexture(imgRef));
+ m_images.set(crc, image);
+
+ return image;
}
-void ImagesManager::removeImage(SkBitmapRef* imgRef)
+ImageTexture* ImagesManager::retainImage(unsigned imgCRC)
{
+ if (!imgCRC)
+ return 0;
+
android::Mutex::Autolock lock(m_imagesLock);
- if (!m_images.contains(imgRef))
- return;
+ ImageTexture* image = 0;
+ if (m_images.contains(imgCRC)) {
+ image = m_images.get(imgCRC);
+ SkSafeRef(image);
+ }
+ return image;
+}
- ImageTexture* image = m_images.get(imgRef);
- image->release();
+void ImagesManager::releaseImage(unsigned imgCRC)
+{
+ if (!imgCRC)
+ return;
- if (!image->refCount()) {
- m_images.remove(imgRef);
- delete image;
+ android::Mutex::Autolock lock(m_imagesLock);
+ if (m_images.contains(imgCRC)) {
+ ImageTexture* image = m_images.get(imgCRC);
+ if (image->getRefCnt() == 1)
+ m_images.remove(imgCRC);
+ SkSafeUnref(image);
}
}
-void ImagesManager::showImages()
+int ImagesManager::nbTextures()
{
- XLOGC("We have %d images", m_images.size());
- HashMap<SkBitmapRef*, ImageTexture*>::iterator end = m_images.end();
+ android::Mutex::Autolock lock(m_imagesLock);
+ HashMap<unsigned, ImageTexture*>::iterator end = m_images.end();
int i = 0;
- for (HashMap<SkBitmapRef*, ImageTexture*>::iterator it = m_images.begin(); it != end; ++it) {
- XLOGC("Image %x (%d/%d) has %d references", it->first, i,
- m_images.size(), it->second->refCount());
+ int nb = 0;
+ for (HashMap<unsigned, ImageTexture*>::iterator it = m_images.begin(); it != end; ++it) {
+ nb += it->second->nbTextures();
i++;
}
+ return nb;
}
-ImageTexture* ImagesManager::getTextureForImage(SkBitmapRef* img, bool retain)
+bool ImagesManager::prepareTextures(GLWebViewState* state)
{
+ bool ret = false;
android::Mutex::Autolock lock(m_imagesLock);
- ImageTexture* image = m_images.get(img);
- if (retain && image)
- image->retain();
- return image;
-}
-
-void ImagesManager::scheduleTextureUpload(ImageTexture* texture)
-{
- if (m_imagesToUpload.contains(texture))
- return;
-
- texture->retain();
- m_imagesToUpload.append(texture);
-}
-
-bool ImagesManager::uploadTextures()
-{
- // scheduleUpload and uploadTextures are called on the same thread
- if (!m_imagesToUpload.size())
- return false;
- ImageTexture* texture = m_imagesToUpload.last();
- texture->uploadGLTexture();
- m_imagesToUpload.removeLast();
- removeImage(texture->imageRef());
- return m_imagesToUpload.size();
+ HashMap<unsigned, ImageTexture*>::iterator end = m_images.end();
+ for (HashMap<unsigned, ImageTexture*>::iterator it = m_images.begin(); it != end; ++it) {
+ ret |= it->second->prepareGL(state);
+ }
+ return ret;
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/ImagesManager.h b/Source/WebCore/platform/graphics/android/ImagesManager.h
index 2fcb9fd..a3ea859 100644
--- a/Source/WebCore/platform/graphics/android/ImagesManager.h
+++ b/Source/WebCore/platform/graphics/android/ImagesManager.h
@@ -35,17 +35,18 @@
namespace WebCore {
class ImageTexture;
+class GLWebViewState;
class ImagesManager {
public:
static ImagesManager* instance();
- void addImage(SkBitmapRef* img);
- void removeImage(SkBitmapRef* img);
- ImageTexture* getTextureForImage(SkBitmapRef* img, bool retain = true);
- void showImages();
- void scheduleTextureUpload(ImageTexture* texture);
- bool uploadTextures();
+ ImageTexture* setImage(SkBitmapRef* imgRef);
+ ImageTexture* retainImage(unsigned imgCRC);
+ void releaseImage(unsigned imgCRC);
+
+ bool prepareTextures(GLWebViewState*);
+ int nbTextures();
private:
ImagesManager() {}
@@ -53,8 +54,7 @@ private:
static ImagesManager* gInstance;
android::Mutex m_imagesLock;
- HashMap<SkBitmapRef*, ImageTexture*> m_images;
- Vector<ImageTexture*> m_imagesToUpload;
+ HashMap<unsigned, ImageTexture*> m_images;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp
index 86991d5..1cd2b1a 100644
--- a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp
@@ -149,8 +149,7 @@ LayerAndroid::LayerAndroid(RenderLayer* owner) : Layer(),
m_recordingPicture(0),
m_uniqueId(++gUniqueId),
m_texture(0),
- m_imageRef(0),
- m_imageTexture(0),
+ m_imageCRC(0),
m_pictureUsed(0),
m_scale(1),
m_lastComputeTextureSize(0),
@@ -174,15 +173,15 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : Layer(layer),
m_isIframe(layer.m_isIframe),
m_uniqueId(layer.m_uniqueId),
m_texture(0),
- m_imageTexture(0),
m_owningLayer(layer.m_owningLayer),
m_type(LayerAndroid::UILayer),
m_hasText(true)
{
m_isFixed = layer.m_isFixed;
- m_imageRef = layer.m_imageRef;
- if (m_imageRef)
- ImagesManager::instance()->addImage(m_imageRef);
+ m_imageCRC = layer.m_imageCRC;
+ if (m_imageCRC)
+ ImagesManager::instance()->retainImage(m_imageCRC);
+
m_renderLayerPos = layer.m_renderLayerPos;
m_transform = layer.m_transform;
m_backfaceVisibility = layer.m_backfaceVisibility;
@@ -223,7 +222,7 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : Layer(layer),
m_hasText = layer.m_hasText;
#ifdef DEBUG_COUNT
- ClassTracker::instance()->increment("LayerAndroid - recopy (UI?)");
+ ClassTracker::instance()->increment("LayerAndroid - recopy (UI)");
ClassTracker::instance()->add(this);
#endif
}
@@ -252,8 +251,7 @@ LayerAndroid::LayerAndroid(SkPicture* picture) : Layer(),
m_recordingPicture(picture),
m_uniqueId(++gUniqueId),
m_texture(0),
- m_imageRef(0),
- m_imageTexture(0),
+ m_imageCRC(0),
m_scale(1),
m_lastComputeTextureSize(0),
m_owningLayer(0),
@@ -272,8 +270,9 @@ LayerAndroid::LayerAndroid(SkPicture* picture) : Layer(),
LayerAndroid::~LayerAndroid()
{
- if (m_imageTexture)
- ImagesManager::instance()->removeImage(m_imageTexture->imageRef());
+ if (m_imageCRC)
+ ImagesManager::instance()->releaseImage(m_imageCRC);
+
SkSafeUnref(m_recordingPicture);
m_animations.clear();
#ifdef DEBUG_COUNT
@@ -761,16 +760,14 @@ void LayerAndroid::updateGLPositionsAndScale(const TransformationMatrix& parentM
void LayerAndroid::setContentsImage(SkBitmapRef* img)
{
- m_imageRef = img;
- if (!img)
- return;
-
- ImagesManager::instance()->addImage(img);
+ ImageTexture* image = ImagesManager::instance()->setImage(img);
+ ImagesManager::instance()->releaseImage(m_imageCRC);
+ m_imageCRC = image ? image->imageCRC() : 0;
}
bool LayerAndroid::needsTexture()
{
- return m_imageRef || (m_recordingPicture
+ return m_imageCRC || (m_recordingPicture
&& m_recordingPicture->width() && m_recordingPicture->height());
}
@@ -841,10 +838,11 @@ void LayerAndroid::showLayer(int indent)
IntRect visible = visibleArea();
IntRect clip(m_clippingRect.x(), m_clippingRect.y(),
m_clippingRect.width(), m_clippingRect.height());
- XLOGC("%s [%d:0x%x] - %s - area (%d, %d, %d, %d) - visible (%d, %d, %d, %d) "
+ XLOGC("%s [%d:0x%x] - %s %s - area (%d, %d, %d, %d) - visible (%d, %d, %d, %d) "
"clip (%d, %d, %d, %d) %s %s prepareContext(%x), pic w: %d h: %d",
spaces, uniqueId(), m_owningLayer,
needsTexture() ? "needs a texture" : "no texture",
+ m_imageCRC ? "has an image" : "no image",
tr.x(), tr.y(), tr.width(), tr.height(),
visible.x(), visible.y(), visible.width(), visible.height(),
clip.x(), clip.y(), clip.width(), clip.height(),
@@ -983,11 +981,11 @@ bool LayerAndroid::updateWithLayer(LayerAndroid* layer)
m_opacity = layer->m_opacity;
m_transform = layer->m_transform;
- if (m_imageRef != layer->m_imageRef)
+ if (m_imageCRC != layer->m_imageCRC)
m_visible = false;
if ((m_recordingPicture != layer->m_recordingPicture)
- || (m_imageRef != layer->m_imageRef))
+ || (m_imageCRC != layer->m_imageCRC))
return true;
return false;
@@ -998,11 +996,7 @@ void LayerAndroid::obtainTextureForPainting(LayerAndroid* drawingLayer)
if (!needsTexture())
return;
- if (m_imageRef) {
- if (!m_imageTexture) {
- m_imageTexture = ImagesManager::instance()->getTextureForImage(m_imageRef);
- m_dirtyRegion.setEmpty();
- }
+ if (m_imageCRC) {
if (m_texture) {
m_texture->setDrawingLayer(0);
m_texture->clearPaintingLayer();
@@ -1019,8 +1013,8 @@ void LayerAndroid::obtainTextureForPainting(LayerAndroid* drawingLayer)
// pass the invalidated regions to the PaintedSurface
m_texture->setPaintingLayer(this, m_dirtyRegion);
- m_dirtyRegion.setEmpty();
}
+ m_dirtyRegion.setEmpty();
}
@@ -1062,9 +1056,6 @@ void LayerAndroid::prepare()
if (m_texture)
m_texture->prepare(m_state);
-
- if (m_imageTexture)
- m_imageTexture->prepareGL();
}
IntRect LayerAndroid::unclippedArea()
@@ -1148,9 +1139,12 @@ bool LayerAndroid::drawGL()
if (m_state->layersRenderingMode() < GLWebViewState::kScrollableAndFixedLayers) {
if (m_texture)
askScreenUpdate |= m_texture->draw();
-
- if (m_imageTexture)
- m_imageTexture->drawGL(this);
+ if (m_imageCRC) {
+ ImageTexture* imageTexture = ImagesManager::instance()->retainImage(m_imageCRC);
+ if (imageTexture)
+ imageTexture->drawGL(this);
+ ImagesManager::instance()->releaseImage(m_imageCRC);
+ }
}
// When the layer is dirty, the UI thread should be notified to redraw.
@@ -1248,16 +1242,15 @@ void LayerAndroid::onDraw(SkCanvas* canvas, SkScalar opacity)
if (canvasOpacity < 255)
canvas->setDrawFilter(new OpacityDrawFilter(canvasOpacity));
- if (m_imageRef) {
- if (!m_imageTexture) {
- m_imageTexture = ImagesManager::instance()->getTextureForImage(m_imageRef);
- m_dirtyRegion.setEmpty();
- }
- if (m_imageTexture) {
+ if (m_imageCRC) {
+ ImageTexture* imageTexture = ImagesManager::instance()->retainImage(m_imageCRC);
+ m_dirtyRegion.setEmpty();
+ if (imageTexture) {
SkRect dest;
dest.set(0, 0, getSize().width(), getSize().height());
- m_imageTexture->drawCanvas(canvas, dest);
+ imageTexture->drawCanvas(canvas, dest);
}
+ ImagesManager::instance()->releaseImage(m_imageCRC);
}
contentDraw(canvas);
}
diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.h b/Source/WebCore/platform/graphics/android/LayerAndroid.h
index 8b82b27..cc96fae 100644
--- a/Source/WebCore/platform/graphics/android/LayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/LayerAndroid.h
@@ -260,7 +260,7 @@ public:
/** This sets a content image -- calling it means we will use
the image directly when drawing the layer instead of using
the content painted by WebKit.
- Images are handled in TilesManager, as they can be shared
+ Images are handled in ImagesManager, as they can be shared
between layers.
*/
void setContentsImage(SkBitmapRef* img);
@@ -298,8 +298,6 @@ public:
bool updateWithTree(LayerAndroid*);
virtual bool updateWithLayer(LayerAndroid*);
- SkBitmapRef* imageRef() { return m_imageRef; }
- ImageTexture* imageTexture() { return m_imageTexture; }
int type() { return m_type; }
bool hasText() { return m_hasText; }
@@ -387,8 +385,7 @@ private:
int m_uniqueId;
PaintedSurface* m_texture;
- SkBitmapRef* m_imageRef;
- ImageTexture* m_imageTexture;
+ unsigned m_imageCRC;
unsigned int m_pictureUsed;
diff --git a/Source/WebCore/platform/graphics/android/PaintTileOperation.cpp b/Source/WebCore/platform/graphics/android/PaintTileOperation.cpp
index 5d06ea3..2d69706 100644
--- a/Source/WebCore/platform/graphics/android/PaintTileOperation.cpp
+++ b/Source/WebCore/platform/graphics/android/PaintTileOperation.cpp
@@ -25,12 +25,14 @@
#include "config.h"
#include "PaintTileOperation.h"
+#include "ImageTexture.h"
+#include "ImagesManager.h"
#include "LayerAndroid.h"
#include "PaintedSurface.h"
namespace WebCore {
-PaintTileOperation::PaintTileOperation(BaseTile* tile, PaintedSurface* surface)
+PaintTileOperation::PaintTileOperation(BaseTile* tile, SurfacePainter* surface)
: QueuedOperation(QueuedOperation::PaintTile, tile->page())
, m_tile(tile)
, m_surface(surface)
@@ -46,7 +48,13 @@ PaintTileOperation::~PaintTileOperation()
m_tile->setRepaintPending(false);
m_tile = 0;
}
- SkSafeUnref(m_surface);
+
+ if (m_surface && m_surface->type() == SurfacePainter::ImageSurface) {
+ ImageTexture* image = static_cast<ImageTexture*>(m_surface);
+ ImagesManager::instance()->releaseImage(image->imageCRC());
+ } else {
+ SkSafeUnref(m_surface);
+ }
}
bool PaintTileOperation::operator==(const QueuedOperation* operation)
diff --git a/Source/WebCore/platform/graphics/android/PaintTileOperation.h b/Source/WebCore/platform/graphics/android/PaintTileOperation.h
index fabc2f7..bc74d03 100644
--- a/Source/WebCore/platform/graphics/android/PaintTileOperation.h
+++ b/Source/WebCore/platform/graphics/android/PaintTileOperation.h
@@ -28,15 +28,17 @@
#include "BaseTile.h"
#include "QueuedOperation.h"
+#include "SkRefCnt.h"
namespace WebCore {
class LayerAndroid;
-class PaintedSurface;
+class SurfacePainter;
+class ImageTexture;
class PaintTileOperation : public QueuedOperation {
public:
- PaintTileOperation(BaseTile* tile, PaintedSurface* surface = 0);
+ PaintTileOperation(BaseTile* tile, SurfacePainter* surface = 0);
virtual ~PaintTileOperation();
virtual bool operator==(const QueuedOperation* operation);
virtual void run();
@@ -47,7 +49,7 @@ public:
private:
BaseTile* m_tile;
- PaintedSurface* m_surface;
+ SurfacePainter* m_surface;
};
class ScaleFilter : public OperationFilter {
diff --git a/Source/WebCore/platform/graphics/android/PaintedSurface.h b/Source/WebCore/platform/graphics/android/PaintedSurface.h
index b438111..b8ab7b8 100644
--- a/Source/WebCore/platform/graphics/android/PaintedSurface.h
+++ b/Source/WebCore/platform/graphics/android/PaintedSurface.h
@@ -43,7 +43,7 @@ namespace WebCore {
class DualTiledTexture;
-class PaintedSurface : public SkRefCnt {
+class PaintedSurface : public SurfacePainter {
public:
PaintedSurface();
virtual ~PaintedSurface();
@@ -71,10 +71,10 @@ public:
// TilePainter methods for TiledTexture
virtual const TransformationMatrix* transform();
+ virtual float opacity();
// used by TiledTexture
float scale() { return m_scale; }
- float opacity();
unsigned int pictureUsed() { return m_pictureUsed; }
private:
diff --git a/Source/WebCore/platform/graphics/android/TilePainter.h b/Source/WebCore/platform/graphics/android/TilePainter.h
index 91030cb..4d0f5dc 100644
--- a/Source/WebCore/platform/graphics/android/TilePainter.h
+++ b/Source/WebCore/platform/graphics/android/TilePainter.h
@@ -27,6 +27,7 @@
#define TilePainter_h
#include "TransformationMatrix.h"
+#include "SkRefCnt.h"
class SkCanvas;
@@ -41,6 +42,15 @@ public:
virtual const TransformationMatrix* transform() { return 0; }
};
+class SurfacePainter : public SkRefCnt {
+public:
+ virtual ~SurfacePainter() { }
+ virtual const TransformationMatrix* transform() { return 0; }
+ virtual float opacity() { return 1.0; }
+ enum SurfaceType { PaintedSurface, ImageSurface };
+ virtual SurfaceType type() { return PaintedSurface; }
+};
+
}
#endif // TilePainter_h
diff --git a/Source/WebCore/platform/graphics/android/TiledTexture.cpp b/Source/WebCore/platform/graphics/android/TiledTexture.cpp
index 91d6897..6711527 100644
--- a/Source/WebCore/platform/graphics/android/TiledTexture.cpp
+++ b/Source/WebCore/platform/graphics/android/TiledTexture.cpp
@@ -204,6 +204,7 @@ void TiledTexture::prepareTile(bool repaint, int x, int y)
if (tile->isDirty() || !tile->frontTexture())
tile->reserveTexture();
+
bool hasPicture = m_paintingPicture != 0; // safely read on UI thread, since only UI thread writes
if (tile->backTexture() && tile->isDirty() && !tile->isRepaintPending() && hasPicture) {
PaintTileOperation *operation = new PaintTileOperation(tile, m_surface);
@@ -229,6 +230,9 @@ int TiledTexture::nbTextures(IntRect& area, float scale)
bool TiledTexture::draw()
{
+ if (!m_surface)
+ return true;
+
XLOG("TT %p draw", this);
#ifdef DEBUG
@@ -257,8 +261,8 @@ bool TiledTexture::draw()
rect.fTop = tile->y() * tileHeight;
rect.fRight = rect.fLeft + tileWidth;
rect.fBottom = rect.fTop + tileHeight;
- XLOG("- [%d], { painter %x vs %x }, tile %x %d,%d at scale %.2f vs %.2f [ready: %d] dirty: %d",
- i, this, tile->painter(), tile, tile->x(), tile->y(),
+ XLOG("- [%d], { painter %x vs %x }, tile %x (layer tile: %d) %d,%d at scale %.2f vs %.2f [ready: %d] dirty: %d",
+ i, this, tile->painter(), tile, tile->isLayerTile(), tile->x(), tile->y(),
tile->scale(), m_scale, tile->isTileReady(), tile->isDirty());
tile->draw(m_surface->opacity(), rect, m_scale);
#ifdef DEBUG
@@ -283,7 +287,7 @@ bool TiledTexture::paint(BaseTile* tile, SkCanvas* canvas, unsigned int* picture
return false;
}
- XLOG("TT %p painting with picture %p", this, picture);
+ XLOG("TT %p painting tile %d, %d with picture %p", this, tile->x(), tile->y(), picture);
canvas->drawPicture(*picture);
@@ -294,6 +298,8 @@ bool TiledTexture::paint(BaseTile* tile, SkCanvas* canvas, unsigned int* picture
const TransformationMatrix* TiledTexture::transform()
{
+ if (!m_surface)
+ return 0;
return m_surface->transform();
}
@@ -323,7 +329,7 @@ bool TiledTexture::owns(BaseTileTexture* texture)
return false;
}
-DualTiledTexture::DualTiledTexture(PaintedSurface* surface)
+DualTiledTexture::DualTiledTexture(SurfacePainter* surface)
{
m_textureA = new TiledTexture(surface);
m_textureB = new TiledTexture(surface);
diff --git a/Source/WebCore/platform/graphics/android/TiledTexture.h b/Source/WebCore/platform/graphics/android/TiledTexture.h
index b761880..444ab14 100644
--- a/Source/WebCore/platform/graphics/android/TiledTexture.h
+++ b/Source/WebCore/platform/graphics/android/TiledTexture.h
@@ -39,11 +39,9 @@ class SkCanvas;
namespace WebCore {
-class PaintedSurface;
-
class TiledTexture : public TilePainter {
public:
- TiledTexture(PaintedSurface* surface)
+ TiledTexture(SurfacePainter* surface)
: m_paintingPicture(0)
, m_surface(surface)
, m_prevTileX(0)
@@ -82,8 +80,6 @@ public:
float scale() { return m_scale; }
bool ready();
- PaintedSurface* surface() { return m_surface; }
-
int nbTextures(IntRect& area, float scale);
private:
@@ -95,7 +91,7 @@ private:
android::Mutex m_paintingPictureSync;
SkPicture* m_paintingPicture;
- PaintedSurface* m_surface;
+ SurfacePainter* m_surface;
Vector<BaseTile*> m_tiles;
// tile coordinates in viewport, set in prepare()
@@ -112,7 +108,7 @@ private:
class DualTiledTexture {
public:
- DualTiledTexture(PaintedSurface* surface);
+ DualTiledTexture(SurfacePainter* surface);
~DualTiledTexture();
void prepare(GLWebViewState* state, float scale, bool repaint,
bool startFastSwap, IntRect& area);
diff --git a/Source/WebCore/platform/graphics/android/TilesManager.cpp b/Source/WebCore/platform/graphics/android/TilesManager.cpp
index 219435d..30bd8d0 100644
--- a/Source/WebCore/platform/graphics/android/TilesManager.cpp
+++ b/Source/WebCore/platform/graphics/android/TilesManager.cpp
@@ -189,6 +189,23 @@ void TilesManager::deallocateTexturesVector(unsigned long long sparedDrawCount,
dealloc, max, maxLayer);
}
+void TilesManager::gatherTexturesNumbers(int* nbTextures, int* nbAllocatedTextures,
+ int* nbLayerTextures, int* nbAllocatedLayerTextures)
+{
+ *nbTextures = m_textures.size();
+ for (unsigned int i = 0; i < m_textures.size(); i++) {
+ BaseTileTexture* texture = m_textures[i];
+ if (texture->m_ownTextureId)
+ *nbAllocatedTextures += 1;
+ }
+ *nbLayerTextures = m_tilesTextures.size();
+ for (unsigned int i = 0; i < m_tilesTextures.size(); i++) {
+ BaseTileTexture* texture = m_tilesTextures[i];
+ if (texture->m_ownTextureId)
+ *nbAllocatedLayerTextures += 1;
+ }
+}
+
void TilesManager::printTextures()
{
#ifdef DEBUG
diff --git a/Source/WebCore/platform/graphics/android/TilesManager.h b/Source/WebCore/platform/graphics/android/TilesManager.h
index 0c3e900..9782fbb 100644
--- a/Source/WebCore/platform/graphics/android/TilesManager.h
+++ b/Source/WebCore/platform/graphics/android/TilesManager.h
@@ -88,6 +88,8 @@ public:
void gatherLayerTextures();
void gatherTextures();
bool layerTexturesRemain() { return m_layerTexturesRemain; }
+ void gatherTexturesNumbers(int* nbTextures, int* nbAllocatedTextures,
+ int* nbLayerTextures, int* nbAllocatedLayerTextures);
BaseTileTexture* getAvailableTexture(BaseTile* owner);