Loading libs/hwui/Android.mk +2 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ hwui_src_files := \ font/Font.cpp \ renderstate/Blend.cpp \ renderstate/MeshState.cpp \ renderstate/OffscreenBufferPool.cpp \ renderstate/PixelBufferState.cpp \ renderstate/RenderState.cpp \ renderstate/Scissor.cpp \ Loading Loading @@ -216,6 +217,7 @@ LOCAL_SRC_FILES += \ unit_tests/LayerUpdateQueueTests.cpp \ unit_tests/LinearAllocatorTests.cpp \ unit_tests/PathParserTests.cpp \ unit_tests/OffscreenBufferPoolTests.cpp \ unit_tests/StringUtilsTests.cpp ifeq (true, $(HWUI_NEW_OPS)) Loading libs/hwui/BakedOpRenderer.cpp +6 −82 Original line number Diff line number Diff line Loading @@ -19,98 +19,22 @@ #include "Caches.h" #include "Glop.h" #include "GlopBuilder.h" #include "VertexBuffer.h" #include "renderstate/OffscreenBufferPool.h" #include "renderstate/RenderState.h" #include "utils/FatVector.h" #include "utils/GLUtils.h" #include "VertexBuffer.h" namespace android { namespace uirenderer { //////////////////////////////////////////////////////////////////////////////// // OffscreenBuffer //////////////////////////////////////////////////////////////////////////////// OffscreenBuffer::OffscreenBuffer(RenderState& renderState, Caches& caches, uint32_t textureWidth, uint32_t textureHeight, uint32_t viewportWidth, uint32_t viewportHeight) : renderState(renderState) , viewportWidth(viewportWidth) , viewportHeight(viewportHeight) , texture(caches) { texture.width = textureWidth; texture.height = textureHeight; caches.textureState().activateTexture(0); glGenTextures(1, &texture.id); caches.textureState().bindTexture(GL_TEXTURE_2D, texture.id); texture.setWrap(GL_CLAMP_TO_EDGE, false, false, GL_TEXTURE_2D); // not setting filter on texture, since it's set when rendering, based on transform glPixelStorei(GL_UNPACK_ALIGNMENT, 4); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture.width, texture.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); } void OffscreenBuffer::updateMeshFromRegion() { // avoid T-junctions as they cause artifacts in between the resultant // geometry when complex transforms occur. // TODO: generate the safeRegion only if necessary based on rendering transform Region safeRegion = Region::createTJunctionFreeRegion(region); size_t count; const android::Rect* rects = safeRegion.getArray(&count); const float texX = 1.0f / float(viewportWidth); const float texY = 1.0f / float(viewportHeight); FatVector<TextureVertex, 64> meshVector(count * 4); // uses heap if more than 64 vertices needed TextureVertex* mesh = &meshVector[0]; for (size_t i = 0; i < count; i++) { const android::Rect* r = &rects[i]; const float u1 = r->left * texX; const float v1 = (viewportHeight - r->top) * texY; const float u2 = r->right * texX; const float v2 = (viewportHeight - r->bottom) * texY; TextureVertex::set(mesh++, r->left, r->top, u1, v1); TextureVertex::set(mesh++, r->right, r->top, u2, v1); TextureVertex::set(mesh++, r->left, r->bottom, u1, v2); TextureVertex::set(mesh++, r->right, r->bottom, u2, v2); } elementCount = count * 6; renderState.meshState().genOrUpdateMeshBuffer(&vbo, sizeof(TextureVertex) * count * 4, &meshVector[0], GL_DYNAMIC_DRAW); // TODO: GL_STATIC_DRAW if savelayer } OffscreenBuffer::~OffscreenBuffer() { texture.deleteTexture(); renderState.meshState().deleteMeshBuffer(vbo); elementCount = 0; vbo = 0; } //////////////////////////////////////////////////////////////////////////////// // BakedOpRenderer //////////////////////////////////////////////////////////////////////////////// OffscreenBuffer* BakedOpRenderer::createOffscreenBuffer(RenderState& renderState, uint32_t width, uint32_t height) { // TODO: get from cache! return new OffscreenBuffer(renderState, Caches::getInstance(), width, height, width, height); } void BakedOpRenderer::destroyOffscreenBuffer(OffscreenBuffer* offscreenBuffer) { // TODO: return texture/offscreenbuffer to cache! delete offscreenBuffer; } OffscreenBuffer* BakedOpRenderer::startTemporaryLayer(uint32_t width, uint32_t height) { OffscreenBuffer* buffer = createOffscreenBuffer(mRenderState, width, height); LOG_ALWAYS_FATAL_IF(mRenderTarget.offscreenBuffer, "already has layer..."); OffscreenBuffer* buffer = mRenderState.layerPool().get(mRenderState, width, height); startRepaintLayer(buffer); return buffer; } Loading Loading @@ -357,7 +281,7 @@ void BakedOpDispatcher::onLayerOp(BakedOpRenderer& renderer, const LayerOp& op, renderer.renderGlop(state, glop); if (op.destroy) { BakedOpRenderer::destroyOffscreenBuffer(buffer); renderer.renderState().layerPool().putOrDelete(buffer); } } Loading libs/hwui/BakedOpRenderer.h +0 −31 Original line number Diff line number Diff line Loading @@ -28,33 +28,6 @@ struct Glop; class Layer; class RenderState; /** * Lightweight alternative to Layer. Owns the persistent state of an offscreen render target, and * encompasses enough information to draw it back on screen (minus paint properties, which are held * by LayerOp). */ class OffscreenBuffer { public: OffscreenBuffer(RenderState& renderState, Caches& caches, uint32_t textureWidth, uint32_t textureHeight, uint32_t viewportWidth, uint32_t viewportHeight); ~OffscreenBuffer(); // must be called prior to rendering, to construct/update vertex buffer void updateMeshFromRegion(); RenderState& renderState; uint32_t viewportWidth; uint32_t viewportHeight; Texture texture; // Portion of offscreen buffer that has been drawn to. Used to minimize drawing area when // drawing back to screen / parent FBO. Region region; GLsizei elementCount = 0; GLuint vbo = 0; }; /** * Main rendering manager for a collection of work - one frame + any contained FBOs. * Loading @@ -72,10 +45,6 @@ public: , mOpaque(opaque) { } static OffscreenBuffer* createOffscreenBuffer(RenderState& renderState, uint32_t width, uint32_t height); static void destroyOffscreenBuffer(OffscreenBuffer*); RenderState& renderState() { return mRenderState; } Caches& caches() { return mCaches; } Loading libs/hwui/DisplayListCanvas.h +9 −8 Original line number Diff line number Diff line Loading @@ -17,6 +17,14 @@ #ifndef ANDROID_HWUI_DISPLAY_LIST_RENDERER_H #define ANDROID_HWUI_DISPLAY_LIST_RENDERER_H #include "Canvas.h" #include "CanvasState.h" #include "DisplayList.h" #include "RenderNode.h" #include "ResourceCache.h" #include "SkiaCanvasProxy.h" #include "utils/Macros.h" #include <SkDrawFilter.h> #include <SkMatrix.h> #include <SkPaint.h> Loading @@ -25,13 +33,6 @@ #include <SkTLazy.h> #include <cutils/compiler.h> #include "Canvas.h" #include "CanvasState.h" #include "DisplayList.h" #include "SkiaCanvasProxy.h" #include "RenderNode.h" #include "ResourceCache.h" namespace android { namespace uirenderer { Loading Loading @@ -66,7 +67,7 @@ public: virtual ~DisplayListCanvas(); void reset(int width, int height); __attribute__((warn_unused_result)) DisplayList* finishRecording(); WARN_UNUSED_RESULT DisplayList* finishRecording(); // ---------------------------------------------------------------------------- // HWUI Canvas state operations Loading libs/hwui/LayerCache.cpp +8 −13 Original line number Diff line number Diff line Loading @@ -14,14 +14,15 @@ * limitations under the License. */ #include <GLES2/gl2.h> #include <utils/Log.h> #include "LayerCache.h" #include "Caches.h" #include "LayerCache.h" #include "Properties.h" #include <utils/Log.h> #include <GLES2/gl2.h> namespace android { namespace uirenderer { Loading @@ -29,15 +30,9 @@ namespace uirenderer { // Constructors/destructor /////////////////////////////////////////////////////////////////////////////// LayerCache::LayerCache(): mSize(0), mMaxSize(MB(DEFAULT_LAYER_CACHE_SIZE)) { char property[PROPERTY_VALUE_MAX]; if (property_get(PROPERTY_LAYER_CACHE_SIZE, property, nullptr) > 0) { INIT_LOGD(" Setting layer cache size to %sMB", property); setMaxSize(MB(atof(property))); } else { INIT_LOGD(" Using default layer cache size of %.2fMB", DEFAULT_LAYER_CACHE_SIZE); } } LayerCache::LayerCache() : mSize(0) , mMaxSize(Properties::layerPoolSize) {} LayerCache::~LayerCache() { clear(); Loading Loading
libs/hwui/Android.mk +2 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ hwui_src_files := \ font/Font.cpp \ renderstate/Blend.cpp \ renderstate/MeshState.cpp \ renderstate/OffscreenBufferPool.cpp \ renderstate/PixelBufferState.cpp \ renderstate/RenderState.cpp \ renderstate/Scissor.cpp \ Loading Loading @@ -216,6 +217,7 @@ LOCAL_SRC_FILES += \ unit_tests/LayerUpdateQueueTests.cpp \ unit_tests/LinearAllocatorTests.cpp \ unit_tests/PathParserTests.cpp \ unit_tests/OffscreenBufferPoolTests.cpp \ unit_tests/StringUtilsTests.cpp ifeq (true, $(HWUI_NEW_OPS)) Loading
libs/hwui/BakedOpRenderer.cpp +6 −82 Original line number Diff line number Diff line Loading @@ -19,98 +19,22 @@ #include "Caches.h" #include "Glop.h" #include "GlopBuilder.h" #include "VertexBuffer.h" #include "renderstate/OffscreenBufferPool.h" #include "renderstate/RenderState.h" #include "utils/FatVector.h" #include "utils/GLUtils.h" #include "VertexBuffer.h" namespace android { namespace uirenderer { //////////////////////////////////////////////////////////////////////////////// // OffscreenBuffer //////////////////////////////////////////////////////////////////////////////// OffscreenBuffer::OffscreenBuffer(RenderState& renderState, Caches& caches, uint32_t textureWidth, uint32_t textureHeight, uint32_t viewportWidth, uint32_t viewportHeight) : renderState(renderState) , viewportWidth(viewportWidth) , viewportHeight(viewportHeight) , texture(caches) { texture.width = textureWidth; texture.height = textureHeight; caches.textureState().activateTexture(0); glGenTextures(1, &texture.id); caches.textureState().bindTexture(GL_TEXTURE_2D, texture.id); texture.setWrap(GL_CLAMP_TO_EDGE, false, false, GL_TEXTURE_2D); // not setting filter on texture, since it's set when rendering, based on transform glPixelStorei(GL_UNPACK_ALIGNMENT, 4); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture.width, texture.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); } void OffscreenBuffer::updateMeshFromRegion() { // avoid T-junctions as they cause artifacts in between the resultant // geometry when complex transforms occur. // TODO: generate the safeRegion only if necessary based on rendering transform Region safeRegion = Region::createTJunctionFreeRegion(region); size_t count; const android::Rect* rects = safeRegion.getArray(&count); const float texX = 1.0f / float(viewportWidth); const float texY = 1.0f / float(viewportHeight); FatVector<TextureVertex, 64> meshVector(count * 4); // uses heap if more than 64 vertices needed TextureVertex* mesh = &meshVector[0]; for (size_t i = 0; i < count; i++) { const android::Rect* r = &rects[i]; const float u1 = r->left * texX; const float v1 = (viewportHeight - r->top) * texY; const float u2 = r->right * texX; const float v2 = (viewportHeight - r->bottom) * texY; TextureVertex::set(mesh++, r->left, r->top, u1, v1); TextureVertex::set(mesh++, r->right, r->top, u2, v1); TextureVertex::set(mesh++, r->left, r->bottom, u1, v2); TextureVertex::set(mesh++, r->right, r->bottom, u2, v2); } elementCount = count * 6; renderState.meshState().genOrUpdateMeshBuffer(&vbo, sizeof(TextureVertex) * count * 4, &meshVector[0], GL_DYNAMIC_DRAW); // TODO: GL_STATIC_DRAW if savelayer } OffscreenBuffer::~OffscreenBuffer() { texture.deleteTexture(); renderState.meshState().deleteMeshBuffer(vbo); elementCount = 0; vbo = 0; } //////////////////////////////////////////////////////////////////////////////// // BakedOpRenderer //////////////////////////////////////////////////////////////////////////////// OffscreenBuffer* BakedOpRenderer::createOffscreenBuffer(RenderState& renderState, uint32_t width, uint32_t height) { // TODO: get from cache! return new OffscreenBuffer(renderState, Caches::getInstance(), width, height, width, height); } void BakedOpRenderer::destroyOffscreenBuffer(OffscreenBuffer* offscreenBuffer) { // TODO: return texture/offscreenbuffer to cache! delete offscreenBuffer; } OffscreenBuffer* BakedOpRenderer::startTemporaryLayer(uint32_t width, uint32_t height) { OffscreenBuffer* buffer = createOffscreenBuffer(mRenderState, width, height); LOG_ALWAYS_FATAL_IF(mRenderTarget.offscreenBuffer, "already has layer..."); OffscreenBuffer* buffer = mRenderState.layerPool().get(mRenderState, width, height); startRepaintLayer(buffer); return buffer; } Loading Loading @@ -357,7 +281,7 @@ void BakedOpDispatcher::onLayerOp(BakedOpRenderer& renderer, const LayerOp& op, renderer.renderGlop(state, glop); if (op.destroy) { BakedOpRenderer::destroyOffscreenBuffer(buffer); renderer.renderState().layerPool().putOrDelete(buffer); } } Loading
libs/hwui/BakedOpRenderer.h +0 −31 Original line number Diff line number Diff line Loading @@ -28,33 +28,6 @@ struct Glop; class Layer; class RenderState; /** * Lightweight alternative to Layer. Owns the persistent state of an offscreen render target, and * encompasses enough information to draw it back on screen (minus paint properties, which are held * by LayerOp). */ class OffscreenBuffer { public: OffscreenBuffer(RenderState& renderState, Caches& caches, uint32_t textureWidth, uint32_t textureHeight, uint32_t viewportWidth, uint32_t viewportHeight); ~OffscreenBuffer(); // must be called prior to rendering, to construct/update vertex buffer void updateMeshFromRegion(); RenderState& renderState; uint32_t viewportWidth; uint32_t viewportHeight; Texture texture; // Portion of offscreen buffer that has been drawn to. Used to minimize drawing area when // drawing back to screen / parent FBO. Region region; GLsizei elementCount = 0; GLuint vbo = 0; }; /** * Main rendering manager for a collection of work - one frame + any contained FBOs. * Loading @@ -72,10 +45,6 @@ public: , mOpaque(opaque) { } static OffscreenBuffer* createOffscreenBuffer(RenderState& renderState, uint32_t width, uint32_t height); static void destroyOffscreenBuffer(OffscreenBuffer*); RenderState& renderState() { return mRenderState; } Caches& caches() { return mCaches; } Loading
libs/hwui/DisplayListCanvas.h +9 −8 Original line number Diff line number Diff line Loading @@ -17,6 +17,14 @@ #ifndef ANDROID_HWUI_DISPLAY_LIST_RENDERER_H #define ANDROID_HWUI_DISPLAY_LIST_RENDERER_H #include "Canvas.h" #include "CanvasState.h" #include "DisplayList.h" #include "RenderNode.h" #include "ResourceCache.h" #include "SkiaCanvasProxy.h" #include "utils/Macros.h" #include <SkDrawFilter.h> #include <SkMatrix.h> #include <SkPaint.h> Loading @@ -25,13 +33,6 @@ #include <SkTLazy.h> #include <cutils/compiler.h> #include "Canvas.h" #include "CanvasState.h" #include "DisplayList.h" #include "SkiaCanvasProxy.h" #include "RenderNode.h" #include "ResourceCache.h" namespace android { namespace uirenderer { Loading Loading @@ -66,7 +67,7 @@ public: virtual ~DisplayListCanvas(); void reset(int width, int height); __attribute__((warn_unused_result)) DisplayList* finishRecording(); WARN_UNUSED_RESULT DisplayList* finishRecording(); // ---------------------------------------------------------------------------- // HWUI Canvas state operations Loading
libs/hwui/LayerCache.cpp +8 −13 Original line number Diff line number Diff line Loading @@ -14,14 +14,15 @@ * limitations under the License. */ #include <GLES2/gl2.h> #include <utils/Log.h> #include "LayerCache.h" #include "Caches.h" #include "LayerCache.h" #include "Properties.h" #include <utils/Log.h> #include <GLES2/gl2.h> namespace android { namespace uirenderer { Loading @@ -29,15 +30,9 @@ namespace uirenderer { // Constructors/destructor /////////////////////////////////////////////////////////////////////////////// LayerCache::LayerCache(): mSize(0), mMaxSize(MB(DEFAULT_LAYER_CACHE_SIZE)) { char property[PROPERTY_VALUE_MAX]; if (property_get(PROPERTY_LAYER_CACHE_SIZE, property, nullptr) > 0) { INIT_LOGD(" Setting layer cache size to %sMB", property); setMaxSize(MB(atof(property))); } else { INIT_LOGD(" Using default layer cache size of %.2fMB", DEFAULT_LAYER_CACHE_SIZE); } } LayerCache::LayerCache() : mSize(0) , mMaxSize(Properties::layerPoolSize) {} LayerCache::~LayerCache() { clear(); Loading