summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/WebCore/platform/graphics/android/CanvasLayer.cpp71
-rw-r--r--Source/WebCore/platform/graphics/android/CanvasTexture.cpp33
-rw-r--r--Source/WebCore/platform/graphics/android/CanvasTexture.h2
-rw-r--r--Source/WebCore/platform/graphics/android/GLUtils.cpp7
4 files changed, 75 insertions, 38 deletions
diff --git a/Source/WebCore/platform/graphics/android/CanvasLayer.cpp b/Source/WebCore/platform/graphics/android/CanvasLayer.cpp
index 52bdaaa..fea429f 100644
--- a/Source/WebCore/platform/graphics/android/CanvasLayer.cpp
+++ b/Source/WebCore/platform/graphics/android/CanvasLayer.cpp
@@ -70,30 +70,36 @@ CanvasLayer::CanvasLayer(const CanvasLayer& layer)
// We are making a copy for the UI, sync the interesting bits
m_contentRect = layer.contentRect();
m_offsetFromRenderer = layer.offsetFromRenderer();
- m_texture->setSize(m_contentRect.size());
bool previousState = m_texture->hasValidTexture();
- // Attempt to upload to a surface texture
- if (!m_texture->uploadImageBuffer(layer.m_canvas->buffer())) {
- // Blargh, no surface texture - fall back to software
+ if (!previousState && layer.m_dirtyCanvas.isEmpty()) {
+ // We were previously in software and don't have anything new to draw,
+ // so stay in software
m_bitmap = layer.bitmap();
SkSafeRef(m_bitmap);
- // Merge the canvas invals with the layer's invals to repaint the needed
- // tiles.
- SkRegion::Iterator iter(layer.m_dirtyCanvas);
- const IntPoint& offset = m_contentRect.location();
- for (; !iter.done(); iter.next()) {
- SkIRect diff = iter.rect();
- diff.fLeft += offset.x();
- diff.fRight += offset.x();
- diff.fTop += offset.y();
- diff.fBottom += offset.y();
- m_dirtyRegion.op(diff, SkRegion::kUnion_Op);
+ } else {
+ // Attempt to upload to a surface texture
+ if (!m_texture->uploadImageBuffer(layer.m_canvas->buffer())) {
+ // Blargh, no surface texture or ImageBuffer - fall back to software
+ m_bitmap = layer.bitmap();
+ SkSafeRef(m_bitmap);
+ // Merge the canvas invals with the layer's invals to repaint the needed
+ // tiles.
+ SkRegion::Iterator iter(layer.m_dirtyCanvas);
+ const IntPoint& offset = m_contentRect.location();
+ for (; !iter.done(); iter.next()) {
+ SkIRect diff = iter.rect();
+ diff.fLeft += offset.x();
+ diff.fRight += offset.x();
+ diff.fTop += offset.y();
+ diff.fBottom += offset.y();
+ m_dirtyRegion.op(diff, SkRegion::kUnion_Op);
+ }
+ }
+ if (previousState != m_texture->hasValidTexture()) {
+ // Need to do a full inval of the canvas content as we are mode switching
+ m_dirtyRegion.op(m_contentRect.x(), m_contentRect.y(),
+ m_contentRect.maxX(), m_contentRect.maxY(), SkRegion::kUnion_Op);
}
- }
- if (previousState != m_texture->hasValidTexture()) {
- // Need to do a full inval of the canvas content as we are mode switching
- m_dirtyRegion.op(m_contentRect.x(), m_contentRect.y(),
- m_contentRect.maxX(), m_contentRect.maxY(), SkRegion::kUnion_Op);
}
}
@@ -111,17 +117,26 @@ void CanvasLayer::init()
void CanvasLayer::canvasChanged(HTMLCanvasElement*, const FloatRect& changedRect)
{
- SkIRect irect = SkIRect::MakeXYWH(changedRect.x(), changedRect.y(),
- changedRect.width(), changedRect.height());
- m_dirtyCanvas.op(irect, SkRegion::kUnion_Op);
+ if (!m_texture->hasValidTexture()) {
+ // We only need to track invals if we aren't using a SurfaceTexture.
+ // If we drop out of hwa, we will do a full inval anyway
+ SkIRect irect = SkIRect::MakeXYWH(changedRect.x(), changedRect.y(),
+ changedRect.width(), changedRect.height());
+ m_dirtyCanvas.op(irect, SkRegion::kUnion_Op);
+ }
owningLayer()->compositor()->scheduleLayerFlush();
}
void CanvasLayer::canvasResized(HTMLCanvasElement*)
{
const IntSize& size = m_canvas->size();
- SkIRect irect = SkIRect::MakeWH(size.width(), size.height());
- m_dirtyCanvas.op(irect, SkRegion::kUnion_Op);
+ m_dirtyCanvas.setRect(0, 0, size.width(), size.height());
+ // If we are smaller than one tile, don't bother using a surface texture
+ if (size.width() <= TilesManager::layerTileWidth()
+ && size.height() <= TilesManager::layerTileHeight())
+ m_texture->setSize(IntSize());
+ else
+ m_texture->setSize(size);
}
void CanvasLayer::canvasDestroyed(HTMLCanvasElement*)
@@ -146,6 +161,12 @@ SkBitmapRef* CanvasLayer::bitmap() const
IntRect CanvasLayer::contentRect() const
{
+ if (!m_canvas
+ || !m_canvas->renderer()
+ || !m_canvas->renderer()->style()
+ || !m_canvas->inDocument()
+ || m_canvas->renderer()->style()->visibility() != VISIBLE)
+ return IntRect();
return m_canvas->renderBox()->contentBoxRect();
}
diff --git a/Source/WebCore/platform/graphics/android/CanvasTexture.cpp b/Source/WebCore/platform/graphics/android/CanvasTexture.cpp
index ca520fd..e4b2bc6 100644
--- a/Source/WebCore/platform/graphics/android/CanvasTexture.cpp
+++ b/Source/WebCore/platform/graphics/android/CanvasTexture.cpp
@@ -72,7 +72,7 @@ bool CanvasTexture::setHwAccelerated(bool hwAccelerated)
m_useHwAcceleration = hwAccelerated;
if (!m_ANW.get())
return false;
- destroySurfaceTexture();
+ destroySurfaceTextureLocked();
return true;
}
@@ -87,15 +87,15 @@ void CanvasTexture::setSize(const IntSize& size)
return;
m_size = size;
if (m_ANW.get()) {
- if (!useSurfaceTexture()) {
- m_ANW.clear();
- m_surfaceTexture->abandon();
- m_surfaceTexture.clear();
- } else {
+ if (useSurfaceTexture()) {
int result = native_window_set_buffers_dimensions(m_ANW.get(),
m_size.width(), m_size.height());
GLUtils::checkSurfaceTextureError("native_window_set_buffers_dimensions", result);
+ if (result != NO_ERROR)
+ m_useHwAcceleration = false; // On error, drop out of HWA
}
+ if (!useSurfaceTexture())
+ destroySurfaceTextureLocked();
}
}
@@ -112,9 +112,16 @@ SurfaceTextureClient* CanvasTexture::nativeWindow()
m_ANW = new android::SurfaceTextureClient(m_surfaceTexture);
int result = native_window_set_buffers_format(m_ANW.get(), HAL_PIXEL_FORMAT_RGBA_8888);
GLUtils::checkSurfaceTextureError("native_window_set_buffers_format", result);
- result = native_window_set_buffers_dimensions(m_ANW.get(),
- m_size.width(), m_size.height());
- GLUtils::checkSurfaceTextureError("native_window_set_buffers_dimensions", result);
+ if (result == NO_ERROR) {
+ result = native_window_set_buffers_dimensions(m_ANW.get(),
+ m_size.width(), m_size.height());
+ GLUtils::checkSurfaceTextureError("native_window_set_buffers_dimensions", result);
+ }
+ if (result != NO_ERROR) {
+ m_useHwAcceleration = false;
+ destroySurfaceTextureLocked();
+ return 0;
+ }
return m_ANW.get();
}
@@ -124,11 +131,15 @@ bool CanvasTexture::uploadImageBuffer(ImageBuffer* imageBuffer)
SurfaceTextureClient* anw = nativeWindow();
if (!anw)
return false;
+ // Size mismatch, early abort (will fall back to software)
+ if (imageBuffer->size() != m_size)
+ return false;
GraphicsContext* gc = imageBuffer ? imageBuffer->context() : 0;
if (!gc)
return false;
const SkBitmap& bitmap = android_gc2canvas(gc)->getDevice()->accessBitmap(false);
- GLUtils::updateSharedSurfaceTextureWithBitmap(anw, bitmap);
+ if (!GLUtils::updateSharedSurfaceTextureWithBitmap(anw, bitmap))
+ return false;
m_hasValidTexture = true;
return true;
}
@@ -174,7 +185,7 @@ bool CanvasTexture::updateTexImage()
* Called by both threads
********************************************/
-void CanvasTexture::destroySurfaceTexture()
+void CanvasTexture::destroySurfaceTextureLocked()
{
if (m_ANW.get()) {
m_ANW.clear();
diff --git a/Source/WebCore/platform/graphics/android/CanvasTexture.h b/Source/WebCore/platform/graphics/android/CanvasTexture.h
index 8875af7..98962a0 100644
--- a/Source/WebCore/platform/graphics/android/CanvasTexture.h
+++ b/Source/WebCore/platform/graphics/android/CanvasTexture.h
@@ -69,7 +69,7 @@ private:
/********************************************
* Called by both threads
********************************************/
- void destroySurfaceTexture();
+ void destroySurfaceTextureLocked();
/********************************************
* Called by WebKit thread
diff --git a/Source/WebCore/platform/graphics/android/GLUtils.cpp b/Source/WebCore/platform/graphics/android/GLUtils.cpp
index 9c5a079..fb69deb 100644
--- a/Source/WebCore/platform/graphics/android/GLUtils.cpp
+++ b/Source/WebCore/platform/graphics/android/GLUtils.cpp
@@ -525,8 +525,13 @@ bool GLUtils::updateSharedSurfaceTextureWithBitmap(ANativeWindow* anw, const SkB
ANativeWindow_Buffer buffer;
if (ANativeWindow_lock(anw, &buffer, 0))
return false;
- if (buffer.width < bitmap.width() || buffer.height < bitmap.height())
+ if (buffer.width < bitmap.width() || buffer.height < bitmap.height()) {
+ ALOGW("bitmap (%dx%d) too large for buffer (%dx%d)!",
+ bitmap.width(), bitmap.height(),
+ buffer.width, buffer.height);
+ ANativeWindow_unlockAndPost(anw);
return false;
+ }
uint8_t* img = (uint8_t*)buffer.bits;
int row;
int bpp = 4; // Now we only deal with RGBA8888 format.