summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform/graphics
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/platform/graphics')
-rw-r--r--Source/WebCore/platform/graphics/android/FontAndroid.cpp47
-rw-r--r--Source/WebCore/platform/graphics/android/FontPlatformData.h2
-rw-r--r--Source/WebCore/platform/graphics/android/FontPlatformDataAndroid.cpp11
-rw-r--r--Source/WebCore/platform/graphics/android/GLWebViewState.cpp18
-rw-r--r--Source/WebCore/platform/graphics/android/GLWebViewState.h12
-rw-r--r--Source/WebCore/platform/graphics/android/TiledPage.cpp34
-rw-r--r--Source/WebCore/platform/graphics/android/TilesManager.cpp24
-rw-r--r--Source/WebCore/platform/graphics/android/TilesManager.h8
-rw-r--r--Source/WebCore/platform/graphics/android/TransferQueue.cpp64
9 files changed, 73 insertions, 147 deletions
diff --git a/Source/WebCore/platform/graphics/android/FontAndroid.cpp b/Source/WebCore/platform/graphics/android/FontAndroid.cpp
index 332e571..b56e37c 100644
--- a/Source/WebCore/platform/graphics/android/FontAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/FontAndroid.cpp
@@ -427,7 +427,6 @@ public:
private:
void setupFontForScriptRun();
- void setupComplexFont(const char* fontName, const FontPlatformData& platformData);
HB_FontRec* allocHarfbuzzFont();
void deleteGlyphArrays();
void createGlyphArrays(int);
@@ -466,7 +465,6 @@ private:
// each word break we accumulate error. This is the
// number of pixels that we are behind so far.
unsigned m_letterSpacing; // pixels to be added after each glyph.
- FontPlatformData* m_complexPlatformData;
};
@@ -481,7 +479,6 @@ TextRunWalker::TextRunWalker(const TextRun& run, unsigned startingX, const Font*
, m_padPerWordBreak(0)
, m_padError(0)
, m_letterSpacing(0)
- , m_complexPlatformData(0)
{
// Do not use |run| inside this constructor. Use |m_run| instead.
@@ -510,7 +507,6 @@ TextRunWalker::~TextRunWalker()
fastFree(m_item.font);
deleteGlyphArrays();
delete[] m_item.log_clusters;
- delete m_complexPlatformData;
}
bool TextRunWalker::isWordBreak(unsigned index, bool isRTL)
@@ -624,48 +620,15 @@ void TextRunWalker::setWordAndLetterSpacing(int wordSpacingAdjustment,
setLetterSpacingAdjustment(letterSpacingAdjustment);
}
-void TextRunWalker::setupComplexFont(const char* filename,
- const FontPlatformData& platformData)
-{
- delete m_complexPlatformData;
-
- SkTypeface* typeface = SkTypeface::CreateFromFile(filename);
- m_complexPlatformData = new FontPlatformData(platformData, typeface);
- SkSafeUnref(typeface);
- m_item.face = m_complexPlatformData->harfbuzzFace();
- m_item.font->userData = m_complexPlatformData;
-}
-
void TextRunWalker::setupFontForScriptRun()
{
- const FontData* fontData = m_font->glyphDataForCharacter(m_run[0], false).fontData;
+ const FontData* fontData = m_font->glyphDataForCharacter(
+ m_item.string[m_item.item.pos], false).fontData;
const FontPlatformData& platformData =
fontData->fontDataForCharacter(' ')->platformData();
-
- if (m_item.item.script == HB_Script_Devanagari) {
- setupComplexFont("/system/fonts/Lohit_Hindi.ttf", platformData);
- } else if (m_item.item.script == HB_Script_Thai) {
- setupComplexFont("/system/fonts/DroidSansThai.ttf", platformData);
- } else if (m_item.item.script == HB_Script_Arabic) {
- setupComplexFont("/system/fonts/DroidNaskh-Regular.ttf", platformData);
- } else if (m_item.item.script == HB_Script_Hebrew) {
- switch (platformData.typeface()->style()) {
- case SkTypeface::kBold:
- case SkTypeface::kBoldItalic:
- setupComplexFont("/system/fonts/DroidSansHebrew-Bold.ttf", platformData);
- break;
- case SkTypeface::kNormal:
- case SkTypeface::kItalic:
- default:
- setupComplexFont("/system/fonts/DroidSansHebrew-Regular.ttf", platformData);
- break;
- }
- } else {
- // HB_Script_Common; includes Ethiopic
- m_item.face = platformData.harfbuzzFace();
- void* opaquePlatformData = const_cast<FontPlatformData*>(&platformData);
- m_item.font->userData = opaquePlatformData;
- }
+ m_item.face = platformData.harfbuzzFace();
+ void* opaquePlatformData = const_cast<FontPlatformData*>(&platformData);
+ m_item.font->userData = opaquePlatformData;
}
HB_FontRec* TextRunWalker::allocHarfbuzzFont()
diff --git a/Source/WebCore/platform/graphics/android/FontPlatformData.h b/Source/WebCore/platform/graphics/android/FontPlatformData.h
index 56ce6e9..3313aca 100644
--- a/Source/WebCore/platform/graphics/android/FontPlatformData.h
+++ b/Source/WebCore/platform/graphics/android/FontPlatformData.h
@@ -55,7 +55,6 @@ public:
FontPlatformData(SkTypeface*, float textSize, bool fakeBold, bool fakeItalic);
FontPlatformData(const FontPlatformData& src, float textSize);
FontPlatformData(float size, bool syntheticBold, bool syntheticOblique);
- FontPlatformData(const FontPlatformData& src, SkTypeface* typeface);
~FontPlatformData();
@@ -88,7 +87,6 @@ public:
#endif
HB_FaceRec_* harfbuzzFace() const;
- SkTypeface* typeface() const { return mTypeface; }
private:
class RefCountedHarfbuzzFace : public RefCounted<RefCountedHarfbuzzFace> {
diff --git a/Source/WebCore/platform/graphics/android/FontPlatformDataAndroid.cpp b/Source/WebCore/platform/graphics/android/FontPlatformDataAndroid.cpp
index 1c3c5d9..337a94d 100644
--- a/Source/WebCore/platform/graphics/android/FontPlatformDataAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/FontPlatformDataAndroid.cpp
@@ -127,17 +127,6 @@ FontPlatformData::FontPlatformData(float size, bool bold, bool oblique)
trace(5);
}
-FontPlatformData::FontPlatformData(const FontPlatformData& src, SkTypeface* tf)
- : mTypeface(tf), mTextSize(src.mTextSize), mFakeBold(src.mFakeBold), mFakeItalic(src.mFakeItalic)
-{
- if (hashTableDeletedFontValue() != mTypeface) {
- SkSafeRef(mTypeface);
- }
-
- inc_count();
- trace(6);
-}
-
FontPlatformData::~FontPlatformData()
{
dec_count();
diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
index 4bc83ef..53d32f7 100644
--- a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
+++ b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
@@ -83,6 +83,8 @@ GLWebViewState::GLWebViewState(android::Mutex* buttonMutex)
, m_focusRingTexture(-1)
, m_goingDown(true)
, m_goingLeft(false)
+ , m_expandedTileBoundsX(0)
+ , m_expandedTileBoundsY(0)
{
m_viewport.setEmpty();
m_previousViewport.setEmpty();
@@ -426,12 +428,11 @@ void GLWebViewState::swapPages()
int GLWebViewState::baseContentWidth()
{
- return m_currentBaseLayer ? m_currentBaseLayer->getWidth() : 0;
-
+ return m_currentBaseLayer ? m_currentBaseLayer->content()->width() : 0;
}
int GLWebViewState::baseContentHeight()
{
- return m_currentBaseLayer ? m_currentBaseLayer->getHeight() : 0;
+ return m_currentBaseLayer ? m_currentBaseLayer->content()->height() : 0;
}
void GLWebViewState::setViewport(SkRect& viewport, float scale)
@@ -455,8 +456,8 @@ void GLWebViewState::setViewport(SkRect& viewport, float scale)
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;
+ int maxTextureCount = (m_viewportTileBounds.width() + TILE_PREFETCH_DISTANCE * 2 + 1) *
+ (m_viewportTileBounds.height() + TILE_PREFETCH_DISTANCE * 2 + 1) * 2;
TilesManager::instance()->setMaxTextureCount(maxTextureCount);
m_tiledPageA->updateBaseTileSize();
m_tiledPageB->updateBaseTileSize();
@@ -532,6 +533,13 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect,
return false;
}
+ float viewWidth = (viewport.fRight - viewport.fLeft) * TILE_PREFETCH_RATIO;
+ float viewHeight = (viewport.fBottom - viewport.fTop) * TILE_PREFETCH_RATIO;
+ bool useHorzPrefetch = viewWidth < baseContentWidth();
+ bool useVertPrefetch = viewHeight < baseContentHeight();
+ m_expandedTileBoundsX = (useHorzPrefetch) ? TILE_PREFETCH_DISTANCE : 0;
+ m_expandedTileBoundsY = (useVertPrefetch) ? TILE_PREFETCH_DISTANCE : 0;
+
XLOG("drawGL, rect(%d, %d, %d, %d), viewport(%.2f, %.2f, %.2f, %.2f)",
rect.x(), rect.y(), rect.width(), rect.height(),
viewport.fLeft, viewport.fTop, viewport.fRight, viewport.fBottom);
diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.h b/Source/WebCore/platform/graphics/android/GLWebViewState.h
index 82b6f12..f3cbf74 100644
--- a/Source/WebCore/platform/graphics/android/GLWebViewState.h
+++ b/Source/WebCore/platform/graphics/android/GLWebViewState.h
@@ -42,6 +42,12 @@
// #define MEASURES_PERF
#define MAX_MEASURES_PERF 2000
+// Prefetch and render 2 tiles ahead of the scroll
+#define TILE_PREFETCH_DISTANCE 2
+
+// ratio of content to view required for prefetching to enable
+#define TILE_PREFETCH_RATIO 1.2
+
namespace WebCore {
class BaseLayerAndroid;
@@ -248,6 +254,9 @@ public:
m_goingLeft = goingLeft;
}
+ int expandedTileBoundsX() { return m_expandedTileBoundsX; }
+ int expandedTileBoundsY() { return m_expandedTileBoundsY; }
+
private:
void inval(const IntRect& rect); // caller must hold m_baseLayerLock
void invalRegion(const SkRegion& region);
@@ -308,6 +317,9 @@ private:
bool m_goingDown;
bool m_goingLeft;
+
+ int m_expandedTileBoundsX;
+ int m_expandedTileBoundsY;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/TiledPage.cpp b/Source/WebCore/platform/graphics/android/TiledPage.cpp
index 0facc99..a69f9d1 100644
--- a/Source/WebCore/platform/graphics/android/TiledPage.cpp
+++ b/Source/WebCore/platform/graphics/android/TiledPage.cpp
@@ -259,25 +259,21 @@ void TiledPage::prepare(bool goingDown, bool goingLeft, const SkIRect& tileBound
int lastTileX = tileBounds.fRight - 1;
int lastTileY = tileBounds.fBottom - 1;
- const int baseContentHeight = m_glWebViewState->baseContentHeight();
- const int baseContentWidth = m_glWebViewState->baseContentWidth();
-
// Expand number of tiles to allow tiles outside of viewport to be prepared for
// smoother scrolling.
int nTilesToPrepare = nbTilesWidth * nbTilesHeight;
int nMaxTilesPerPage = m_baseTileSize / 2;
- int expandX = TilesManager::instance()->expandedTileBoundsX();
- int expandY = TilesManager::instance()->expandedTileBoundsY();
- if (nTilesToPrepare + (nbTilesHeight * expandX * 2) <= nMaxTilesPerPage) {
- firstTileX -= expandX;
- lastTileX += expandX;
- nbTilesWidth += expandX * 2;
- }
- if (nTilesToPrepare + (nbTilesWidth * expandY * 2) <= nMaxTilesPerPage) {
- firstTileY -= expandY;
- lastTileY += expandY;
- nbTilesHeight += expandY * 2;
- }
+ int expandX = m_glWebViewState->expandedTileBoundsX();
+ int expandY = m_glWebViewState->expandedTileBoundsY();
+
+ firstTileX -= expandX;
+ lastTileX += expandX;
+ nbTilesWidth += expandX * 2;
+
+ firstTileY -= expandY;
+ lastTileY += expandY;
+ nbTilesHeight += expandY * 2;
+
m_expandedTileBounds.fLeft = firstTileX;
m_expandedTileBounds.fTop = firstTileY;
m_expandedTileBounds.fRight = lastTileX;
@@ -318,10 +314,10 @@ void TiledPage::draw(float transparency, const SkIRect& tileBounds)
const float tileHeight = TilesManager::tileHeight() * m_invScale;
SkIRect actualTileBounds = tileBounds;
- actualTileBounds.fTop -= TilesManager::instance()->expandedTileBoundsY();
- actualTileBounds.fBottom += TilesManager::instance()->expandedTileBoundsY();
- actualTileBounds.fLeft -= TilesManager::instance()->expandedTileBoundsX();
- actualTileBounds.fRight += TilesManager::instance()->expandedTileBoundsX();
+ actualTileBounds.fTop -= m_glWebViewState->expandedTileBoundsY();
+ actualTileBounds.fBottom += m_glWebViewState->expandedTileBoundsY();
+ actualTileBounds.fLeft -= m_glWebViewState->expandedTileBoundsX();
+ actualTileBounds.fRight += m_glWebViewState->expandedTileBoundsX();
for (int j = 0; j < m_baseTileSize; j++) {
BaseTile& tile = m_baseTiles[j];
diff --git a/Source/WebCore/platform/graphics/android/TilesManager.cpp b/Source/WebCore/platform/graphics/android/TilesManager.cpp
index bbed2fb..d7c7952 100644
--- a/Source/WebCore/platform/graphics/android/TilesManager.cpp
+++ b/Source/WebCore/platform/graphics/android/TilesManager.cpp
@@ -58,19 +58,8 @@
#endif // DEBUG
-// Important: We need at least twice as much textures as is needed to cover
-// one viewport, otherwise the allocation may stall.
-// We need n textures for one TiledPage, and another n textures for the
-// second page used when scaling.
-// In our case, we use 300x300 textures. On the tablet, this equates to
-// at least 24 textures. That is consuming almost 50MB GPU memory.
-// 24*300*300*4(bpp)*2(pages)*3(triple buffering in Surface Texture) = 49.4MB
-// In order to avoid OOM issue, we limit the bounds number to 0 for now.
-// TODO: We should either dynamically change the outer bound by detecting the
-// HW limit or save further in the GPU memory consumption.
-#define EXPANDED_TILE_BOUNDS_X 0
-#define EXPANDED_TILE_BOUNDS_Y 0
-#define MAX_TEXTURE_ALLOCATION 3+(6+EXPANDED_TILE_BOUNDS_X*2)*(4+EXPANDED_TILE_BOUNDS_Y*2)*2
+// Number of tiles for base layer
+#define MAX_TEXTURE_ALLOCATION 51
#define TILE_WIDTH 256
#define TILE_HEIGHT 256
#define LAYER_TILE_WIDTH 256
@@ -101,7 +90,6 @@ int TilesManager::getMaxTextureAllocation()
TilesManager::TilesManager()
: m_layersMemoryUsage(0)
, m_maxTextureCount(0)
- , m_expandedTileBounds(false)
, m_generatorReady(false)
, m_showVisualIndicator(false)
, m_invertedScreen(false)
@@ -369,14 +357,6 @@ float TilesManager::layerTileHeight()
return LAYER_TILE_HEIGHT;
}
-int TilesManager::expandedTileBoundsX() {
- return m_expandedTileBounds ? EXPANDED_TILE_BOUNDS_X : 0;
-}
-
-int TilesManager::expandedTileBoundsY() {
- return m_expandedTileBounds ? EXPANDED_TILE_BOUNDS_Y : 0;
-}
-
void TilesManager::registerGLWebViewState(GLWebViewState* state)
{
m_glWebViewStateMap.set(state, m_drawRegistrationCount);
diff --git a/Source/WebCore/platform/graphics/android/TilesManager.h b/Source/WebCore/platform/graphics/android/TilesManager.h
index c7a2381..a383a2e 100644
--- a/Source/WebCore/platform/graphics/android/TilesManager.h
+++ b/Source/WebCore/platform/graphics/android/TilesManager.h
@@ -108,18 +108,11 @@ public:
static float tileHeight();
static float layerTileWidth();
static float layerTileHeight();
- int expandedTileBoundsX();
- int expandedTileBoundsY();
void registerGLWebViewState(GLWebViewState* state);
void unregisterGLWebViewState(GLWebViewState* state);
void allocateTiles();
- void setExpandedTileBounds(bool enabled)
- {
- m_expandedTileBounds = enabled;
- }
-
bool getShowVisualIndicator()
{
return m_showVisualIndicator;
@@ -193,7 +186,6 @@ private:
unsigned int m_layersMemoryUsage;
int m_maxTextureCount;
- bool m_expandedTileBounds;
bool m_generatorReady;
diff --git a/Source/WebCore/platform/graphics/android/TransferQueue.cpp b/Source/WebCore/platform/graphics/android/TransferQueue.cpp
index 1a377f2..8b4b596 100644
--- a/Source/WebCore/platform/graphics/android/TransferQueue.cpp
+++ b/Source/WebCore/platform/graphics/android/TransferQueue.cpp
@@ -297,50 +297,38 @@ void TransferQueue::updateQueueWithBitmap(const TileRenderInfo* renderInfo,
renderInfo->x, renderInfo->y);
return;
}
- // Dequeue the Surface Texture.
- sp<ANativeWindow> ANW = m_ANW;
- if (!ANW.get()) {
+
+ // a) Dequeue the Surface Texture and write into the buffer
+ if (!m_ANW.get()) {
XLOG("ERROR: ANW is null");
return;
}
- ANativeWindowBuffer* anb;
-
- int status = ANW->dequeueBuffer(ANW.get(), &anb);
- GLUtils::checkSurfaceTextureError("dequeueBuffer", status);
- // a) Update surface texture
- sp<android::GraphicBuffer> buf(new android::GraphicBuffer(anb, false));
- status |= ANW->lockBuffer(ANW.get(), buf->getNativeBuffer()); // Mutex Lock
- GLUtils::checkSurfaceTextureError("lockBuffer", status);
-
- // Fill the buffer with the content of the bitmap
- uint8_t* img = 0;
- status |= buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
- GLUtils::checkSurfaceTextureError("lock", status);
-
- if (status == NO_ERROR) {
- int row, col;
- int bpp = 4; // Now we only deal with RGBA8888 format.
- int width = TilesManager::instance()->tileWidth();
- int height = TilesManager::instance()->tileHeight();
- if (!x && !y && bitmap.width() == width && bitmap.height() == height) {
- bitmap.lockPixels();
- uint8_t* bitmapOrigin = static_cast<uint8_t*>(bitmap.getPixels());
- // Copied line by line since we need to handle the offsets and stride.
- for (row = 0 ; row < bitmap.height(); row ++) {
- uint8_t* dst = &(img[(buf->getStride() * (row + x) + y) * bpp]);
- uint8_t* src = &(bitmapOrigin[bitmap.width() * row * bpp]);
- memcpy(dst, src, bpp * bitmap.width());
- }
- bitmap.unlockPixels();
- } else {
- // TODO: implement the partial invalidate here!
- XLOG("ERROR: don't expect to get here yet before we support partial inval");
+
+ ANativeWindow_Buffer buffer;
+ if (ANativeWindow_lock(m_ANW.get(), &buffer, 0))
+ return;
+
+ uint8_t* img = (uint8_t*)buffer.bits;
+ int row, col;
+ int bpp = 4; // Now we only deal with RGBA8888 format.
+ int width = TilesManager::instance()->tileWidth();
+ int height = TilesManager::instance()->tileHeight();
+ if (!x && !y && bitmap.width() == width && bitmap.height() == height) {
+ bitmap.lockPixels();
+ uint8_t* bitmapOrigin = static_cast<uint8_t*>(bitmap.getPixels());
+ // Copied line by line since we need to handle the offsets and stride.
+ for (row = 0 ; row < bitmap.height(); row ++) {
+ uint8_t* dst = &(img[(buffer.stride * (row + x) + y) * bpp]);
+ uint8_t* src = &(bitmapOrigin[bitmap.width() * row * bpp]);
+ memcpy(dst, src, bpp * bitmap.width());
}
+ bitmap.unlockPixels();
+ } else {
+ // TODO: implement the partial invalidate here!
+ XLOG("ERROR: don't expect to get here yet before we support partial inval");
}
- buf->unlock();
- status = ANW->queueBuffer(ANW.get(), buf->getNativeBuffer());
- GLUtils::checkSurfaceTextureError("queueBuffer", status);
+ ANativeWindow_unlockAndPost(m_ANW.get());
// b) After update the Surface Texture, now udpate the transfer queue info.
addItemInTransferQueue(renderInfo);