diff options
Diffstat (limited to 'Source')
14 files changed, 524 insertions, 238 deletions
diff --git a/Source/WebCore/Android.mk b/Source/WebCore/Android.mk index 638bcb9..efdfc42 100644 --- a/Source/WebCore/Android.mk +++ b/Source/WebCore/Android.mk @@ -662,6 +662,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ platform/graphics/android/PatternAndroid.cpp \ platform/graphics/android/PlatformGraphicsContext.cpp \ platform/graphics/android/PerformanceMonitor.cpp \ + platform/graphics/android/RasterRenderer.cpp \ platform/graphics/android/ScrollableLayerAndroid.cpp \ platform/graphics/android/SharedBufferStream.cpp \ platform/graphics/android/ShaderProgram.cpp \ diff --git a/Source/WebCore/platform/graphics/android/BaseTile.cpp b/Source/WebCore/platform/graphics/android/BaseTile.cpp index bbf1532..4515083 100644 --- a/Source/WebCore/platform/graphics/android/BaseTile.cpp +++ b/Source/WebCore/platform/graphics/android/BaseTile.cpp @@ -29,23 +29,16 @@ #if USE(ACCELERATED_COMPOSITING) #include "GLUtils.h" -#include "SkBitmap.h" -#include "SkBitmapRef.h" -#include "SkCanvas.h" -#include "SkPicture.h" +#include "TextureInfo.h" #include "TilesManager.h" -#include <EGL/egl.h> -#include <EGL/eglext.h> -#include <GLES2/gl2.h> -#include <GLES2/gl2ext.h> #include <cutils/atomic.h> -#include <wtf/text/CString.h> #ifdef DEBUG #include <cutils/log.h> #include <wtf/CurrentTime.h> +#include <wtf/text/CString.h> #undef XLOG #define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "BaseTile", __VA_ARGS__) @@ -59,20 +52,6 @@ namespace WebCore { -static const String TAG_CREATE_BITMAP = "create_bitmap"; -static const String TAG_RECORD_PICTURE = "record_picture"; -static const String TAG_DRAW_PICTURE = "draw_picture"; -static const String TAG_UPDATE_TEXTURE = "update_texture"; -static const String TAG_RESET_BITMAP = "reset_bitmap"; -#define TAG_COUNT 5 -static const String TAGS[] = { - TAG_CREATE_BITMAP, - TAG_RECORD_PICTURE, - TAG_DRAW_PICTURE, - TAG_UPDATE_TEXTURE, - TAG_RESET_BITMAP -}; - BaseTile::BaseTile() : m_page(0) , m_x(-1) @@ -238,7 +217,8 @@ void BaseTile::draw(float transparency, SkRect& rect, float scale) if (m_texture->readyFor(this)) { XLOG("draw tile %d, %d, %.2f with texture %x", x(), y(), scale, m_texture); TilesManager::instance()->shader()->drawQuad(rect, textureInfo->m_textureId, - transparency); + transparency, + textureInfo->getTextureTarget()); } m_texture->consumerRelease(); } @@ -265,38 +245,6 @@ bool BaseTile::isTileReady() return false; } -void BaseTile::drawTileInfo(SkCanvas* canvas, - BackedDoubleBufferedTexture* texture, - int x, int y, float scale, - int pictureCount) -{ - SkPaint paint; - char str[256]; - snprintf(str, 256, "(%d,%d) %.2f, tl%x tx%x p%x c%x", - x, y, scale, this, texture, m_page, pictureCount); - paint.setARGB(255, 0, 0, 0); - canvas->drawText(str, strlen(str), 0, 10, paint); - paint.setARGB(255, 255, 0, 0); - canvas->drawText(str, strlen(str), 0, 11, paint); - float total = 0; - for (int i = 0; i < TAG_COUNT; i++) { - float tagDuration = m_perfMon.getAverageDuration(TAGS[i]); - total += tagDuration; - snprintf(str, 256, "%s: %.2f", TAGS[i].utf8().data(), tagDuration); - paint.setARGB(255, 0, 0, 0); - int textY = (i * 12) + 25; - canvas->drawText(str, strlen(str), 0, textY, paint); - paint.setARGB(255, 255, 0, 0); - canvas->drawText(str, strlen(str), 0, textY + 1, paint); - } - snprintf(str, 256, "total: %.2f", total); - paint.setARGB(255, 0, 0, 0); - int textY = (TAG_COUNT * 12) + 30; - canvas->drawText(str, strlen(str), 0, textY, paint); - paint.setARGB(255, 255, 0, 0); - canvas->drawText(str, strlen(str), 0, textY + 1, paint); -} - // This is called from the texture generation thread void BaseTile::paintBitmap() { @@ -330,73 +278,89 @@ void BaseTile::paintBitmap() } SkSize size = texture->getSize(); - float tileWidth = size.width(); - float tileHeight = size.height(); - - const float invScale = 1 / scale; - float w = tileWidth * invScale; - float h = tileHeight * invScale; + const float tileWidth = size.width(); + const float tileHeight = size.height(); - SkCanvas* canvas; unsigned int pictureCount = 0; SkRegion::Iterator cliperator(dirtyArea); bool fullRepaint = false; - if (((m_currentDirtyArea == &m_dirtyAreaA) && m_fullRepaintA) || - ((m_currentDirtyArea == &m_dirtyAreaB) && m_fullRepaintB)) + // TODO: Implement the partial invalidate in Surface Texture Mode + if (((m_currentDirtyArea == &m_dirtyAreaA) && m_fullRepaintA) + || ((m_currentDirtyArea == &m_dirtyAreaB) && m_fullRepaintB) + || !GLUtils::textureExist(textureInfo, texture->bitmap()) + || textureInfo->getSharedTextureMode() == SurfaceTextureMode) { fullRepaint = true; + } - if (fullRepaint) { - SkIRect rect; - pictureCount = paintPartialBitmap(rect, 0, 0, scale, texture, - textureInfo, tiledPage, true); - } else { + if (!fullRepaint) { while (!cliperator.done()) { SkRect dirtyRect; dirtyRect.set(cliperator.rect()); - float left = x * tileWidth; - float top = y * tileHeight; - // compute the rect to corresponds to pixels SkRect realTileRect; - realTileRect.fLeft = left; - realTileRect.fTop = top; - realTileRect.fRight = left + tileWidth; - realTileRect.fBottom = top + tileHeight; + realTileRect.fLeft = x * tileWidth; + realTileRect.fTop = y * tileHeight; + realTileRect.fRight = realTileRect.fLeft + tileWidth; + realTileRect.fBottom = realTileRect.fTop + tileHeight; // scale the dirtyRect for intersect computation. SkRect realDirtyRect = SkRect::MakeWH(dirtyRect.width() * scale, dirtyRect.height() * scale); realDirtyRect.offset(dirtyRect.fLeft * scale, dirtyRect.fTop * scale); + // set realTileRect to the intersection of itself and the dirty rect if (!realTileRect.intersect(realDirtyRect)) { cliperator.next(); continue; } - realTileRect.fLeft = floorf(realTileRect.fLeft); - realTileRect.fTop = floorf(realTileRect.fTop); - realTileRect.fRight = ceilf(realTileRect.fRight); - realTileRect.fBottom = ceilf(realTileRect.fBottom); - + // initialize finalRealRect to the rounded values of realTileRect SkIRect finalRealRect; - finalRealRect.fLeft = static_cast<int>(realTileRect.fLeft) % static_cast<int>(tileWidth); - finalRealRect.fTop = static_cast<int>(realTileRect.fTop) % static_cast<int>(tileHeight); - finalRealRect.fRight = finalRealRect.fLeft + realTileRect.width(); - finalRealRect.fBottom = finalRealRect.fTop + realTileRect.height(); + realTileRect.roundOut(&finalRealRect); + + // stash the int values of the current width and height + const int iWidth = finalRealRect.width(); + const int iHeight = finalRealRect.height(); + + if (iWidth == tileWidth || iHeight == tileHeight) { + fullRepaint = true; + break; + } + + // translate the rect into tile space coordinates + finalRealRect.fLeft = finalRealRect.fLeft % static_cast<int>(tileWidth); + finalRealRect.fTop = finalRealRect.fTop % static_cast<int>(tileHeight); + finalRealRect.fRight = finalRealRect.fLeft + iWidth; + finalRealRect.fBottom = finalRealRect.fTop + iHeight; // the canvas translate can be recomputed accounting for the scale - float tx = - realTileRect.fLeft / scale; - float ty = - realTileRect.fTop / scale; + float tx = realTileRect.fLeft / scale; + float ty = realTileRect.fTop / scale; - pictureCount = paintPartialBitmap(finalRealRect, tx, ty, scale, texture, - textureInfo, tiledPage); + pictureCount = m_renderer.renderContent(x, y, finalRealRect, + tx, ty, scale, texture, + textureInfo, tiledPage, + fullRepaint); cliperator.next(); } } + + if (fullRepaint) { + SkIRect rect; + rect.set(0, 0, tileWidth, tileHeight); + float tx = x * tileWidth / scale; + float ty = y * tileHeight / scale; + + pictureCount = m_renderer.renderContent(x, y, rect, + tx, ty, scale, texture, + textureInfo, tiledPage, + fullRepaint); + } + XLOG("%x update texture %x for tile %d, %d scale %.2f (m_scale: %.2f)", this, textureInfo, x, y, scale, m_scale); m_atomicSync.lock(); @@ -421,7 +385,9 @@ void BaseTile::paintBitmap() if (m_scale != scale) m_dirty = true; - if (!fullRepaint) + if (fullRepaint) + m_currentDirtyArea->setEmpty(); + else m_currentDirtyArea->op(dirtyArea, SkRegion::kDifference_Op); if (!m_currentDirtyArea->isEmpty()) @@ -441,101 +407,6 @@ void BaseTile::paintBitmap() m_atomicSync.unlock(); } -int BaseTile::paintPartialBitmap(SkIRect r, float ptx, float pty, - float scale, BackedDoubleBufferedTexture* texture, - TextureInfo* textureInfo, - TiledPage* tiledPage, bool fullRepaint) -{ - SkIRect rect = r; - float tx = ptx; - float ty = pty; - // TODO: Implement the partial invalidate in Surface Texture Mode - if (!GLUtils::textureExist(textureInfo, texture->bitmap()) - || textureInfo->getSharedTextureMode() == SurfaceTextureMode) { - fullRepaint = true; - } - - if ((rect.width() > TilesManager::instance()->tileWidth()) || - (rect.height() > TilesManager::instance()->tileHeight())) - fullRepaint = true; - - if (fullRepaint) { - rect.set(0, 0, TilesManager::instance()->tileWidth(), - TilesManager::instance()->tileHeight()); - tx = - x() * TilesManager::instance()->tileWidth() / scale; - ty = - y() * TilesManager::instance()->tileHeight() / scale; - } - bool visualIndicator = TilesManager::instance()->getShowVisualIndicator(); - bool measurePerf = fullRepaint && visualIndicator; - - if (measurePerf) - m_perfMon.start(TAG_CREATE_BITMAP); - SkBitmap bitmap; - bitmap.setConfig(SkBitmap::kARGB_8888_Config, rect.width(), rect.height()); - bitmap.allocPixels(); - bitmap.eraseColor(0); - - SkCanvas canvas(bitmap); - canvas.drawARGB(255, 255, 255, 255); - - if (measurePerf) { - m_perfMon.stop(TAG_CREATE_BITMAP); - m_perfMon.start(TAG_RECORD_PICTURE); - } - SkPicture picture; - SkCanvas* nCanvas = picture.beginRecording(rect.width(), rect.height()); - nCanvas->scale(scale, scale); - nCanvas->translate(tx, ty); - int pictureCount = tiledPage->paintBaseLayerContent(nCanvas); - picture.endRecording(); - - if (measurePerf) { - m_perfMon.stop(TAG_RECORD_PICTURE); - m_perfMon.start(TAG_DRAW_PICTURE); - } - if (visualIndicator) - canvas.save(); - picture.draw(&canvas); - if (visualIndicator) - canvas.restore(); - if (measurePerf) { - m_perfMon.stop(TAG_DRAW_PICTURE); - } - - if (visualIndicator) { - int color = 20 + pictureCount % 100; - canvas.drawARGB(color, 0, 255, 0); - - SkPaint paint; - paint.setARGB(128, 255, 0, 0); - paint.setStrokeWidth(3); - canvas.drawLine(0, 0, rect.width(), rect.height(), paint); - paint.setARGB(128, 0, 255, 0); - canvas.drawLine(0, rect.height(), rect.width(), 0, paint); - paint.setARGB(128, 0, 0, 255); - canvas.drawLine(0, 0, rect.width(), 0, paint); - canvas.drawLine(rect.width(), 0, rect.width(), rect.height(), paint); - - drawTileInfo(&canvas, texture, x(), y(), scale, pictureCount); - } - - if (measurePerf) - m_perfMon.start(TAG_UPDATE_TEXTURE); - GLUtils::paintTextureWithBitmap(textureInfo, &bitmap, rect.fLeft, rect.fTop, texture); - if (measurePerf) - m_perfMon.stop(TAG_UPDATE_TEXTURE); - - if (measurePerf) - m_perfMon.start(TAG_RESET_BITMAP); - - bitmap.reset(); - - if (measurePerf) - m_perfMon.stop(TAG_RESET_BITMAP); - - return pictureCount; -} - } // namespace WebCore #endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/android/BaseTile.h b/Source/WebCore/platform/graphics/android/BaseTile.h index a48378b..f58a598 100644 --- a/Source/WebCore/platform/graphics/android/BaseTile.h +++ b/Source/WebCore/platform/graphics/android/BaseTile.h @@ -28,22 +28,16 @@ #if USE(ACCELERATED_COMPOSITING) -#include "HashMap.h" -#include "PerformanceMonitor.h" -#include "TextureInfo.h" -#include "SkBitmap.h" -#include "SkCanvas.h" +#include "RasterRenderer.h" #include "SkRect.h" #include "SkRegion.h" #include "TextureOwner.h" -#include <EGL/egl.h> -#include <EGL/eglext.h> -#include <GLES2/gl2.h> #include <utils/threads.h> namespace WebCore { +class TextureInfo; class TiledPage; class BackedDoubleBufferedTexture; @@ -84,9 +78,6 @@ public: TextureInfo* textureInfo, TiledPage* tiledPage, bool fullRepaint = false); - void drawTileInfo(SkCanvas* canvas, - BackedDoubleBufferedTexture* texture, - int x, int y, float scale, int pictureCount); void markAsDirty(const unsigned int pictureCount, const SkRegion& dirtyArea); @@ -144,8 +135,7 @@ private: // across all threads and cores. android::Mutex m_atomicSync; - // Performance tracking - PerformanceMonitor m_perfMon; + RasterRenderer m_renderer; }; } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp index 67456a3..74b246f 100644 --- a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp @@ -962,7 +962,8 @@ bool LayerAndroid::drawGL(GLWebViewState* glWebViewState, SkMatrix& matrix) //TODO determine when drawing if the alpha value is used. TilesManager::instance()->shader()->drawLayerQuad(drawTransform(), bounds, textureInfo->m_textureId, - m_drawOpacity, true); + m_drawOpacity, true, + textureInfo->getTextureTarget()); } if (!ready) m_dirty = true; diff --git a/Source/WebCore/platform/graphics/android/MediaLayer.cpp b/Source/WebCore/platform/graphics/android/MediaLayer.cpp index 1ba6d46..3d1fe12 100644 --- a/Source/WebCore/platform/graphics/android/MediaLayer.cpp +++ b/Source/WebCore/platform/graphics/android/MediaLayer.cpp @@ -119,7 +119,8 @@ bool MediaLayer::drawGL(GLWebViewState* glWebViewState, SkMatrix& matrix) textureInfo->m_internalFormat == GL_ALPHA; TilesManager::instance()->shader()->drawLayerQuad(m, mediaBounds, textureInfo->m_textureId, - 1.0f, forceBlending); + 1.0f, forceBlending, + textureInfo->getTextureTarget()); } m_bufferedTexture->consumerRelease(); } diff --git a/Source/WebCore/platform/graphics/android/RasterRenderer.cpp b/Source/WebCore/platform/graphics/android/RasterRenderer.cpp new file mode 100644 index 0000000..04eae7c --- /dev/null +++ b/Source/WebCore/platform/graphics/android/RasterRenderer.cpp @@ -0,0 +1,197 @@ +/* + * Copyright 2011, 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. + */ + + +#include "config.h" +#include "RasterRenderer.h" + +#if USE(ACCELERATED_COMPOSITING) + +#include "GLUtils.h" +#include "SkBitmap.h" +#include "SkBitmapRef.h" +#include "SkCanvas.h" +#include "SkPicture.h" +#include "TilesManager.h" + +#include <EGL/egl.h> +#include <EGL/eglext.h> +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> + +#include <wtf/text/CString.h> + +#ifdef DEBUG + +#include <cutils/log.h> +#include <wtf/CurrentTime.h> + +#undef XLOG +#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "RasterRenderer", __VA_ARGS__) + +#else + +#undef XLOG +#define XLOG(...) + +#endif // DEBUG + +namespace WebCore { + +static const String TAG_CREATE_BITMAP = "create_bitmap"; +static const String TAG_DRAW_PICTURE = "draw_picture"; +static const String TAG_UPDATE_TEXTURE = "update_texture"; +static const String TAG_RESET_BITMAP = "reset_bitmap"; +#define TAG_COUNT 4 +static const String TAGS[] = { + TAG_CREATE_BITMAP, + TAG_DRAW_PICTURE, + TAG_UPDATE_TEXTURE, + TAG_RESET_BITMAP +}; + +RasterRenderer::RasterRenderer() +{ +#ifdef DEBUG_COUNT + ClassTracker::instance()->increment("RasterRenderer"); +#endif +} + +RasterRenderer::~RasterRenderer() +{ +#ifdef DEBUG_COUNT + ClassTracker::instance()->decrement("RasterRenderer"); +#endif +} + +void RasterRenderer::drawTileInfo(SkCanvas* canvas, + BackedDoubleBufferedTexture* texture, + TiledPage* tiledPage, + int x, int y, float scale, + int pictureCount) +{ + SkPaint paint; + char str[256]; + snprintf(str, 256, "(%d,%d) %.2f, tl%x tx%x p%x c%d", + x, y, scale, this, texture, tiledPage, pictureCount); + paint.setARGB(255, 0, 0, 0); + canvas->drawText(str, strlen(str), 0, 10, paint); + paint.setARGB(255, 255, 0, 0); + canvas->drawText(str, strlen(str), 0, 11, paint); + float total = 0; + for (int i = 0; i < TAG_COUNT; i++) { + float tagDuration = m_perfMon.getAverageDuration(TAGS[i]); + total += tagDuration; + snprintf(str, 256, "%s: %.2f", TAGS[i].utf8().data(), tagDuration); + paint.setARGB(255, 0, 0, 0); + int textY = (i * 12) + 25; + canvas->drawText(str, strlen(str), 0, textY, paint); + paint.setARGB(255, 255, 0, 0); + canvas->drawText(str, strlen(str), 0, textY + 1, paint); + } + snprintf(str, 256, "total: %.2f", total); + paint.setARGB(255, 0, 0, 0); + int textY = (TAG_COUNT * 12) + 30; + canvas->drawText(str, strlen(str), 0, textY, paint); + paint.setARGB(255, 255, 0, 0); + canvas->drawText(str, strlen(str), 0, textY + 1, paint); +} + +int RasterRenderer::renderContent(int x, int y, SkIRect rect, float tx, float ty, + float scale, BackedDoubleBufferedTexture* texture, + TextureInfo* textureInfo, + TiledPage* tiledPage, bool fullRepaint) +{ + bool visualIndicator = TilesManager::instance()->getShowVisualIndicator(); + bool measurePerf = fullRepaint && visualIndicator; + +#ifdef DEBUG + visualIndicator = true; + measurePerf = true; +#endif + + if (measurePerf) + m_perfMon.start(TAG_CREATE_BITMAP); + SkBitmap bitmap; + bitmap.setConfig(SkBitmap::kARGB_8888_Config, rect.width(), rect.height()); + bitmap.allocPixels(); + bitmap.eraseColor(0); + + SkCanvas canvas(bitmap); + canvas.drawARGB(255, 255, 255, 255); + + if (measurePerf) { + m_perfMon.stop(TAG_CREATE_BITMAP); + m_perfMon.start(TAG_DRAW_PICTURE); + } + if (visualIndicator) + canvas.save(); + + canvas.scale(scale, scale); + canvas.translate(-tx, -ty); + int pictureCount = tiledPage->paintBaseLayerContent(&canvas); + + if (measurePerf) { + m_perfMon.stop(TAG_DRAW_PICTURE); + } + if (visualIndicator) { + canvas.restore(); + + int color = 20 + pictureCount % 100; + canvas.drawARGB(color, 0, 255, 0); + + SkPaint paint; + paint.setARGB(128, 255, 0, 0); + paint.setStrokeWidth(3); + canvas.drawLine(0, 0, rect.width(), rect.height(), paint); + paint.setARGB(128, 0, 255, 0); + canvas.drawLine(0, rect.height(), rect.width(), 0, paint); + paint.setARGB(128, 0, 0, 255); + canvas.drawLine(0, 0, rect.width(), 0, paint); + canvas.drawLine(rect.width(), 0, rect.width(), rect.height(), paint); + + drawTileInfo(&canvas, texture, tiledPage, x, y, scale, pictureCount); + } + + if (measurePerf) + m_perfMon.start(TAG_UPDATE_TEXTURE); + GLUtils::paintTextureWithBitmap(textureInfo, &bitmap, rect.fLeft, rect.fTop, texture); + if (measurePerf) + m_perfMon.stop(TAG_UPDATE_TEXTURE); + + if (measurePerf) + m_perfMon.start(TAG_RESET_BITMAP); + + bitmap.reset(); + + if (measurePerf) + m_perfMon.stop(TAG_RESET_BITMAP); + + return pictureCount; +} + +} // namespace WebCore + +#endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/android/RasterRenderer.h b/Source/WebCore/platform/graphics/android/RasterRenderer.h new file mode 100644 index 0000000..88832f6 --- /dev/null +++ b/Source/WebCore/platform/graphics/android/RasterRenderer.h @@ -0,0 +1,70 @@ +/* + * Copyright 2011, 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 RasterRenderer_h +#define RasterRenderer_h + +#if USE(ACCELERATED_COMPOSITING) + +#include "PerformanceMonitor.h" +#include "SkRect.h" + +class SkCanvas; + +namespace WebCore { + +class BackedDoubleBufferedTexture; +class TextureInfo; +class TiledPage; + +/** + * + */ +class RasterRenderer { +public: + RasterRenderer(); + ~RasterRenderer(); + + void drawTileInfo(SkCanvas* canvas, + BackedDoubleBufferedTexture* texture, + TiledPage* tiledPage, + int x, int y, float scale, int pictureCount); + + int renderContent(int x, int y, SkIRect rect, float tx, float ty, + float scale, BackedDoubleBufferedTexture* texture, + TextureInfo* textureInfo, + TiledPage* tiledPage, + bool fullRepaint); + +private: + + // Performance tracking + PerformanceMonitor m_perfMon; +}; + +} // namespace WebCore + +#endif // USE(ACCELERATED_COMPOSITING) +#endif // RasterRenderer_h diff --git a/Source/WebCore/platform/graphics/android/ShaderProgram.cpp b/Source/WebCore/platform/graphics/android/ShaderProgram.cpp index 635130b..655af0e 100644 --- a/Source/WebCore/platform/graphics/android/ShaderProgram.cpp +++ b/Source/WebCore/platform/graphics/android/ShaderProgram.cpp @@ -32,6 +32,7 @@ #include "GLUtils.h" #include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> #include <cutils/log.h> #include <wtf/CurrentTime.h> #include <wtf/text/CString.h> @@ -51,7 +52,6 @@ static const char gVertexShader[] = "}\n"; static const char gFragmentShader[] = - "#extension GL_OES_EGL_image_external : require\n" "precision mediump float;\n" "varying vec2 v_texCoord; \n" "uniform float alpha; \n" @@ -80,6 +80,33 @@ static const char gVideoFragmentShader[] = " gl_FragColor = texture2D(s_yuvTexture, v_texCoord);\n" "}\n"; +// In the long run, the gSurfaceTextureOESFragmentShader is the official way of +// doing Surface Texture for RGBA format. +// Now since the driver is not ready for it yet, we had to support both to be +// ready for the switch. +// TODO: remove SurfaceTexture2D support after switching to OES method. +static const char gSurfaceTexture2DFragmentShader[] = + "#extension GL_OES_EGL_image_external : require\n" + "precision mediump float;\n" + "varying vec2 v_texCoord; \n" + "uniform float alpha; \n" + "uniform sampler2D s_texture; \n" + "void main() {\n" + " gl_FragColor = texture2D(s_texture, v_texCoord); \n" + " gl_FragColor *= alpha; " + "}\n"; + +static const char gSurfaceTextureOESFragmentShader[] = + "#extension GL_OES_EGL_image_external : require\n" + "precision mediump float;\n" + "varying vec2 v_texCoord; \n" + "uniform float alpha; \n" + "uniform samplerExternalOES s_texture; \n" + "void main() {\n" + " gl_FragColor = texture2D(s_texture, v_texCoord); \n" + " gl_FragColor *= alpha; " + "}\n"; + GLuint ShaderProgram::loadShader(GLenum shaderType, const char* pSource) { GLuint shader = glCreateShader(shaderType); @@ -157,21 +184,41 @@ void ShaderProgram::init() { m_program = createProgram(gVertexShader, gFragmentShader); m_videoProgram = createProgram(gVideoVertexShader, gVideoFragmentShader); - if (m_program == -1 || m_videoProgram == -1) + m_surfTex2DProgram = + createProgram(gVertexShader, gSurfaceTexture2DFragmentShader); + m_surfTexOESProgram = + createProgram(gVertexShader, gSurfaceTextureOESFragmentShader); + + if (m_program == -1 + || m_videoProgram == -1 + || m_surfTex2DProgram == -1 + || m_surfTexOESProgram == -1) return; m_hProjectionMatrix = glGetUniformLocation(m_program, "projectionMatrix"); m_hAlpha = glGetUniformLocation(m_program, "alpha"); m_hTexSampler = glGetUniformLocation(m_program, "s_texture"); - m_hPosition = glGetAttribLocation(m_program, "vPosition"); - m_hVideoProjectionMatrix = glGetUniformLocation(m_videoProgram, "projectionMatrix"); + m_hVideoProjectionMatrix = + glGetUniformLocation(m_videoProgram, "projectionMatrix"); m_hVideoTextureMatrix = glGetUniformLocation(m_videoProgram, "textureMatrix"); m_hVideoTexSampler = glGetUniformLocation(m_videoProgram, "s_yuvTexture"); - m_hVideoPosition = glGetAttribLocation(m_program, "vPosition"); + m_hST2DProjectionMatrix = + glGetUniformLocation(m_surfTex2DProgram, "projectionMatrix"); + m_hST2DAlpha = glGetUniformLocation(m_surfTex2DProgram, "alpha"); + m_hST2DTexSampler = glGetUniformLocation(m_surfTex2DProgram, "s_texture"); + m_hST2DPosition = glGetAttribLocation(m_surfTex2DProgram, "vPosition"); + + m_hSTOESProjectionMatrix = + glGetUniformLocation(m_surfTexOESProgram, "projectionMatrix"); + m_hSTOESAlpha = glGetUniformLocation(m_surfTexOESProgram, "alpha"); + m_hSTOESTexSampler = glGetUniformLocation(m_surfTexOESProgram, "s_texture"); + m_hSTOESPosition = glGetAttribLocation(m_surfTexOESProgram, "vPosition"); + + const GLfloat coord[] = { 0.0f, 0.0f, // C 1.0f, 0.0f, // D @@ -182,6 +229,8 @@ void ShaderProgram::init() glGenBuffers(1, m_textureBuffer); glBindBuffer(GL_ARRAY_BUFFER, m_textureBuffer[0]); glBufferData(GL_ARRAY_BUFFER, 2 * 4 * sizeof(GLfloat), coord, GL_STATIC_DRAW); + + GLUtils::checkGlError("init"); } void ShaderProgram::resetBlending() @@ -232,21 +281,51 @@ void ShaderProgram::setProjectionMatrix(SkRect& geometry) glUniformMatrix4fv(m_hProjectionMatrix, 1, GL_FALSE, projectionMatrix); } -void ShaderProgram::drawQuad(SkRect& geometry, int textureId, float opacity) +void ShaderProgram::drawQuadInternal(SkRect& geometry, + GLint textureId, + float opacity, + GLint program, + GLint texSampler, + GLenum textureTarget, + GLint position, + GLint alpha) { + glUseProgram(program); setProjectionMatrix(geometry); glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, textureId); + glUniform1i(texSampler, 0); + glBindTexture(textureTarget, textureId); + glTexParameteri(textureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(textureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glBindBuffer(GL_ARRAY_BUFFER, m_textureBuffer[0]); - glEnableVertexAttribArray(m_hPosition); - glVertexAttribPointer(m_hPosition, 2, GL_FLOAT, GL_FALSE, 0, 0); - glUniform1f(alpha(), opacity); + glEnableVertexAttribArray(position); + glVertexAttribPointer(position, 2, GL_FLOAT, GL_FALSE, 0, 0); + glUniform1f(alpha, opacity); setBlendingState(opacity < 1.0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); +} +void ShaderProgram::drawQuad(SkRect& geometry, int textureId, float opacity, + GLenum textureTarget) +{ + if (textureTarget == GL_TEXTURE_2D) { + drawQuadInternal(geometry, textureId, opacity, m_program, + m_hTexSampler, GL_TEXTURE_2D, + m_hPosition, alpha()); + } else if (textureTarget == GL_TEXTURE_EXTERNAL_OES) { + drawQuadInternal(geometry, textureId, opacity, m_surfTexOESProgram, + m_hSTOESTexSampler, GL_TEXTURE_EXTERNAL_OES, + m_hSTOESPosition, m_hSTOESAlpha); + } else if (!textureTarget) { + drawQuadInternal(geometry, textureId, opacity, m_surfTex2DProgram, + m_hST2DTexSampler, GL_TEXTURE_2D, + m_hST2DPosition, m_hST2DAlpha); + } GLUtils::checkGlError("drawQuad"); } @@ -373,9 +452,34 @@ float ShaderProgram::zValue(const TransformationMatrix& drawMatrix, float w, flo return result.z(); } +void ShaderProgram::drawLayerQuadInternal(const GLfloat* projectionMatrix, + int textureId, float opacity, + GLenum textureTarget, GLint program, + GLint matrix, GLint texSample, + GLint position, GLint alpha) +{ + glUseProgram(program); + glUniformMatrix4fv(matrix, 1, GL_FALSE, projectionMatrix); + + glActiveTexture(GL_TEXTURE0); + glUniform1i(texSample, 0); + glBindTexture(textureTarget, textureId); + glTexParameteri(textureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(textureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + + glBindBuffer(GL_ARRAY_BUFFER, m_textureBuffer[0]); + glEnableVertexAttribArray(position); + glVertexAttribPointer(position, 2, GL_FLOAT, GL_FALSE, 0, 0); + glUniform1f(alpha, opacity); +} + + void ShaderProgram::drawLayerQuad(const TransformationMatrix& drawMatrix, SkRect& geometry, int textureId, float opacity, - bool forceBlending) + bool forceBlending, GLenum textureTarget) { TransformationMatrix modifiedDrawMatrix = drawMatrix; @@ -386,18 +490,27 @@ void ShaderProgram::drawLayerQuad(const TransformationMatrix& drawMatrix, GLfloat projectionMatrix[16]; GLUtils::toGLMatrix(projectionMatrix, renderMatrix); - glUniformMatrix4fv(m_hProjectionMatrix, 1, GL_FALSE, projectionMatrix); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, textureId); - - glBindBuffer(GL_ARRAY_BUFFER, m_textureBuffer[0]); - glEnableVertexAttribArray(m_hPosition); - glVertexAttribPointer(m_hPosition, 2, GL_FLOAT, GL_FALSE, 0, 0); - glUniform1f(alpha(), opacity); + if (textureTarget == GL_TEXTURE_2D) { + drawLayerQuadInternal(projectionMatrix, textureId, opacity, + GL_TEXTURE_2D, m_program, + m_hProjectionMatrix, m_hTexSampler, + m_hPosition, alpha()); + } else if (textureTarget == GL_TEXTURE_EXTERNAL_OES) { + drawLayerQuadInternal(projectionMatrix, textureId, opacity, + GL_TEXTURE_EXTERNAL_OES, m_surfTexOESProgram, + m_hSTOESProjectionMatrix, m_hSTOESTexSampler, + m_hSTOESPosition, m_hSTOESAlpha); + } else if (!textureTarget) { + drawLayerQuadInternal(projectionMatrix, textureId, opacity, + GL_TEXTURE_2D, m_surfTex2DProgram, + m_hST2DProjectionMatrix, m_hST2DTexSampler, + m_hST2DPosition, m_hST2DAlpha); + } setBlendingState(forceBlending || opacity < 1.0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + GLUtils::checkGlError("drawLayerQuad"); } void ShaderProgram::drawVideoLayerQuad(const TransformationMatrix& drawMatrix, @@ -418,6 +531,7 @@ void ShaderProgram::drawVideoLayerQuad(const TransformationMatrix& drawMatrix, glUniformMatrix4fv(m_hVideoTextureMatrix, 1, GL_FALSE, textureMatrix); glActiveTexture(GL_TEXTURE0); + glUniform1i(m_hVideoTexSampler, 0); glBindTexture(GL_TEXTURE_EXTERNAL_OES, textureId); glBindBuffer(GL_ARRAY_BUFFER, m_textureBuffer[0]); @@ -426,9 +540,6 @@ void ShaderProgram::drawVideoLayerQuad(const TransformationMatrix& drawMatrix, setBlendingState(false); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - // switch back to our normal rendering program - glUseProgram(m_program); } } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/ShaderProgram.h b/Source/WebCore/platform/graphics/android/ShaderProgram.h index 55afe4f..2577fb0 100644 --- a/Source/WebCore/platform/graphics/android/ShaderProgram.h +++ b/Source/WebCore/platform/graphics/android/ShaderProgram.h @@ -38,11 +38,25 @@ class ShaderProgram { // Drawing void setViewport(SkRect& viewport); - void drawQuad(SkRect& geometry, int textureId, float opacity); float zValue(const TransformationMatrix& drawMatrix, float w, float h); + + // For drawQuad and drawLayerQuad, they can handle 3 cases for now: + // 1) textureTarget == GL_TEXTURE_2D + // Normal texture in GL_TEXTURE_2D target. + // 2) textureTarget == GL_TEXTURE_EXTERNAL_OES + // Surface texture in GL_TEXTURE_EXTERNAL_OES target. + // 3) textureTarget == 0 (Will be deprecated soon) + // Surface texture in GL_TEXTURE_2D target. + // + // TODO: Shrink the support modes into 2 (1 and 2) after media framework + // support Surface texture in GL_TEXTURE_EXTERNAL_OES target on all + // platforms. + void drawQuad(SkRect& geometry, int textureId, float opacity, + GLenum textureTarget = GL_TEXTURE_2D); void drawLayerQuad(const TransformationMatrix& drawMatrix, - SkRect& geometry, int textureId, float opacity, - bool forceBlending = false); + SkRect& geometry, int textureId, float opacity, + bool forceBlending = false, + GLenum textureTarget = GL_TEXTURE_2D); void drawVideoLayerQuad(const TransformationMatrix& drawMatrix, float* textureMatrix, SkRect& geometry, int textureId); void setViewRect(const IntRect& viewRect); @@ -71,10 +85,21 @@ class ShaderProgram { void setBlendingState(bool enableBlending); + void drawQuadInternal(SkRect& geometry, GLint textureId, float opacity, + GLint program, GLint texSampler, GLenum textureTarget, + GLint position, GLint alpha); + + void drawLayerQuadInternal(const GLfloat* projectionMatrix, int textureId, + float opacity, GLenum textureTarget, GLint program, + GLint matrix, GLint texSample, + GLint position, GLint alpha); + bool m_blendingEnabled; int m_program; int m_videoProgram; + int m_surfTex2DProgram; + int m_surfTexOESProgram; TransformationMatrix m_projectionMatrix; GLuint m_textureBuffer[1]; @@ -96,6 +121,16 @@ class ShaderProgram { int m_hVideoTextureMatrix; int m_hVideoTexSampler; + GLint m_hST2DProjectionMatrix; + GLint m_hST2DAlpha; + GLint m_hST2DTexSampler; + GLint m_hST2DPosition; + + GLint m_hSTOESProjectionMatrix; + GLint m_hSTOESAlpha; + GLint m_hSTOESTexSampler; + GLint m_hSTOESPosition; + // attribs GLint m_hPosition; GLint m_hVideoPosition; diff --git a/Source/WebCore/platform/graphics/android/SharedTexture.cpp b/Source/WebCore/platform/graphics/android/SharedTexture.cpp index ecd9f54..4f52107 100644 --- a/Source/WebCore/platform/graphics/android/SharedTexture.cpp +++ b/Source/WebCore/platform/graphics/android/SharedTexture.cpp @@ -78,6 +78,7 @@ SharedTexture::~SharedTexture() else if (m_sharedTextureMode == SurfaceTextureMode) { m_sourceTexture->m_surfaceTexture.clear(); m_sourceTexture->m_ANW.clear(); + GLUtils::deleteTexture(&m_sourceTexture->m_textureId); } delete m_sourceTexture; delete m_targetTexture; @@ -198,14 +199,6 @@ TextureInfo* SharedTexture::lockTarget() // Note that the source and targe are the same when using Surface Texture. if (m_sharedTextureMode == SurfaceTextureMode) { m_sourceTexture->m_surfaceTexture->updateTexImage(); - - // Surface Texture requires the filter to be non mipmap - glBindTexture(GL_TEXTURE_2D, m_sourceTexture->m_textureId); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - return m_sourceTexture; } diff --git a/Source/WebCore/platform/graphics/android/TextureInfo.cpp b/Source/WebCore/platform/graphics/android/TextureInfo.cpp index ce132c8..849e6fc 100644 --- a/Source/WebCore/platform/graphics/android/TextureInfo.cpp +++ b/Source/WebCore/platform/graphics/android/TextureInfo.cpp @@ -25,6 +25,7 @@ #include "config.h" #include "TextureInfo.h" + #include "WebCoreJni.h" #include <JNIUtility.h> @@ -62,4 +63,17 @@ bool TextureInfo::operator==(const TextureInfo& otherTexture) return otherTexture.m_textureId == m_textureId && equalsAttributes(&otherTexture); } +GLenum TextureInfo::getTextureTarget() +{ + if (m_surfaceTexture.get()) { + GLenum target = m_surfaceTexture->getCurrentTextureTarget(); + // TODO: remove this translation when TEXTURE_2D+RGBA surface texture + // support is deprecated. + if (target == GL_TEXTURE_2D) + return 0; + return target; + } + return GL_TEXTURE_2D; +} + } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/TextureInfo.h b/Source/WebCore/platform/graphics/android/TextureInfo.h index dfc3092..252d288 100644 --- a/Source/WebCore/platform/graphics/android/TextureInfo.h +++ b/Source/WebCore/platform/graphics/android/TextureInfo.h @@ -58,6 +58,7 @@ public: void copyAttributes(const TextureInfo* sourceTexture); SharedTextureMode getSharedTextureMode() { return m_sharedTextureMode; } + GLenum getTextureTarget(); bool operator==(const TextureInfo& otherTexture); GLuint m_textureId; diff --git a/Source/WebCore/rendering/RenderBlockLineLayout.cpp b/Source/WebCore/rendering/RenderBlockLineLayout.cpp index e464022..8eee581 100644 --- a/Source/WebCore/rendering/RenderBlockLineLayout.cpp +++ b/Source/WebCore/rendering/RenderBlockLineLayout.cpp @@ -777,7 +777,7 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintLogica EFloat cssfloat = style()->floating(); const int lineHeight = style()->computedLineHeight(); const int fontSize = style()->fontSize(); - doTextWrap = autowrap && !positioned && !style()->hasBorder() && + doTextWrap = autowrap && !positioned && (fontSize <= lineHeight) && !style()->hasBackground() && (((dir == LTR && cssfloat != FRIGHT) || (dir == RTL && cssfloat != FLEFT)) && @@ -812,7 +812,7 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintLogica else { #ifdef ANDROID_LAYOUT // ignore text wrap for textField or menuList - if (doTextWrap && (o->isTextField() || o->isMenuList())) + if (doTextWrap && (o->isTextField() || o->isMenuList() || o->isFloating())) doTextWrap = false; #endif if (o->isFloating()) diff --git a/Source/WebKit/android/nav/WebView.cpp b/Source/WebKit/android/nav/WebView.cpp index 236c07b..e0bb6b4 100644 --- a/Source/WebKit/android/nav/WebView.cpp +++ b/Source/WebKit/android/nav/WebView.cpp @@ -482,7 +482,8 @@ bool drawGL(WebCore::IntRect& viewRect, WebCore::IntRect* invalRect, WebCore::In m_glWebViewState->resetRings(); if (extra) { if (extra == &m_ring) { - m_glWebViewState->setRings(m_ring.rings(), m_ring.m_isPressed); + if (root == m_ring.m_frame) + m_glWebViewState->setRings(m_ring.rings(), m_ring.m_isPressed); } else { LayerAndroid mainPicture(m_navPictureUI); PictureSet* content = m_baseLayer->content(); |