diff options
author | Chris Craik <ccraik@google.com> | 2015-01-27 15:46:35 -0800 |
---|---|---|
committer | Chris Craik <ccraik@google.com> | 2015-01-28 16:32:39 -0800 |
commit | 96a5c4c7bab6718524de7253da8309143ab48bef (patch) | |
tree | c984108195579a6da2aa8ccadded7ec46104d4a4 | |
parent | 06a8a121b0dc02bea7977c4112eb4319fd1a133f (diff) | |
download | frameworks_base-96a5c4c7bab6718524de7253da8309143ab48bef.zip frameworks_base-96a5c4c7bab6718524de7253da8309143ab48bef.tar.gz frameworks_base-96a5c4c7bab6718524de7253da8309143ab48bef.tar.bz2 |
Move more GL state management to RenderState and its directory
Change-Id: Ic68584e1c08dc64be2ad43450cb6caa1de834fdc
25 files changed, 683 insertions, 497 deletions
diff --git a/libs/hwui/Android.common.mk b/libs/hwui/Android.common.mk index 5079852..7c1a724 100644 --- a/libs/hwui/Android.common.mk +++ b/libs/hwui/Android.common.mk @@ -7,8 +7,11 @@ LOCAL_CLANG_CFLAGS += \ LOCAL_SRC_FILES := \ font/CacheTexture.cpp \ font/Font.cpp \ + renderstate/MeshState.cpp \ + renderstate/PixelBufferState.cpp \ renderstate/RenderState.cpp \ renderstate/Scissor.cpp \ + renderstate/Stencil.cpp \ renderthread/CanvasContext.cpp \ renderthread/DrawFrameTask.cpp \ renderthread/EglManager.cpp \ @@ -63,7 +66,6 @@ LOCAL_SRC_FILES := \ SkiaShader.cpp \ Snapshot.cpp \ SpotShadow.cpp \ - Stencil.cpp \ TessellationCache.cpp \ Texture.cpp \ TextureCache.cpp \ diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp index 20dd21c..dee0dcd 100644 --- a/libs/hwui/Caches.cpp +++ b/libs/hwui/Caches.cpp @@ -29,12 +29,10 @@ #include <utils/String8.h> namespace android { - -using namespace uirenderer; -ANDROID_SINGLETON_STATIC_INSTANCE(Caches); - namespace uirenderer { +Caches* Caches::sInstance = nullptr; + /////////////////////////////////////////////////////////////////////////////// // Macros /////////////////////////////////////////////////////////////////////////////// @@ -49,8 +47,12 @@ namespace uirenderer { // Constructors/destructor /////////////////////////////////////////////////////////////////////////////// -Caches::Caches(): Singleton<Caches>(), - mExtensions(Extensions::getInstance()), mInitialized(false), mRenderState(nullptr) { +Caches::Caches(RenderState& renderState) + : patchCache(renderState) + , mRenderState(&renderState) + , mExtensions(Extensions::getInstance()) + , mInitialized(false) { + INIT_LOGD("Creating OpenGL renderer caches"); init(); initFont(); initConstraints(); @@ -60,7 +62,8 @@ Caches::Caches(): Singleton<Caches>(), initTempProperties(); mDebugLevel = readDebugLevel(); - ALOGD("Enabling debug mode %d", mDebugLevel); + ALOGD_IF(mDebugLevel != kDebugDisabled, + "Enabling debug mode %d", mDebugLevel); } bool Caches::init() { @@ -68,25 +71,10 @@ bool Caches::init() { ATRACE_NAME("Caches::init"); - glGenBuffers(1, &meshBuffer); - glBindBuffer(GL_ARRAY_BUFFER, meshBuffer); - glBufferData(GL_ARRAY_BUFFER, sizeof(gMeshVertices), gMeshVertices, GL_STATIC_DRAW); - - mCurrentBuffer = meshBuffer; - mCurrentIndicesBuffer = 0; - mCurrentPositionPointer = this; - mCurrentPositionStride = 0; - mCurrentTexCoordsPointer = this; - mCurrentPixelBuffer = 0; - - mTexCoordsArrayEnabled = false; - glActiveTexture(gTextureUnits[0]); mTextureUnit = 0; mRegionMesh = nullptr; - mMeshIndices = 0; - mShadowStripsIndices = 0; blend = false; lastSrcMode = GL_ZERO; lastDstMode = GL_ZERO; @@ -98,11 +86,12 @@ bool Caches::init() { debugOverdraw = false; debugStencilClip = kStencilHide; - patchCache.init(*this); + patchCache.init(); mInitialized = true; resetBoundTextures(); + mPixelBufferState.reset(new PixelBufferState()); return true; } @@ -216,17 +205,8 @@ bool Caches::initProperties() { void Caches::terminate() { if (!mInitialized) return; - - glDeleteBuffers(1, &meshBuffer); - mCurrentBuffer = 0; - - glDeleteBuffers(1, &mMeshIndices); - mMeshIndices = 0; mRegionMesh.release(); - glDeleteBuffers(1, &mShadowStripsIndices); - mShadowStripsIndices = 0; - fboCache.clear(); programCache.clear(); @@ -236,6 +216,8 @@ void Caches::terminate() { clearGarbage(); + mPixelBufferState.release(); + mInitialized = false; } @@ -366,155 +348,9 @@ void Caches::flush(FlushMode mode) { } /////////////////////////////////////////////////////////////////////////////// -// VBO -/////////////////////////////////////////////////////////////////////////////// - -bool Caches::bindMeshBuffer() { - return bindMeshBuffer(meshBuffer); -} - -bool Caches::bindMeshBuffer(const GLuint buffer) { - if (mCurrentBuffer != buffer) { - glBindBuffer(GL_ARRAY_BUFFER, buffer); - mCurrentBuffer = buffer; - return true; - } - return false; -} - -bool Caches::unbindMeshBuffer() { - if (mCurrentBuffer) { - glBindBuffer(GL_ARRAY_BUFFER, 0); - mCurrentBuffer = 0; - return true; - } - return false; -} - -bool Caches::bindIndicesBufferInternal(const GLuint buffer) { - if (mCurrentIndicesBuffer != buffer) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer); - mCurrentIndicesBuffer = buffer; - return true; - } - return false; -} - -bool Caches::bindQuadIndicesBuffer() { - if (!mMeshIndices) { - std::unique_ptr<uint16_t[]> regionIndices(new uint16_t[gMaxNumberOfQuads * 6]); - for (uint32_t i = 0; i < gMaxNumberOfQuads; i++) { - uint16_t quad = i * 4; - int index = i * 6; - regionIndices[index ] = quad; // top-left - regionIndices[index + 1] = quad + 1; // top-right - regionIndices[index + 2] = quad + 2; // bottom-left - regionIndices[index + 3] = quad + 2; // bottom-left - regionIndices[index + 4] = quad + 1; // top-right - regionIndices[index + 5] = quad + 3; // bottom-right - } - - glGenBuffers(1, &mMeshIndices); - bool force = bindIndicesBufferInternal(mMeshIndices); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, gMaxNumberOfQuads * 6 * sizeof(uint16_t), - regionIndices.get(), GL_STATIC_DRAW); - return force; - } - - return bindIndicesBufferInternal(mMeshIndices); -} - -bool Caches::bindShadowIndicesBuffer() { - if (!mShadowStripsIndices) { - std::unique_ptr<uint16_t[]> shadowIndices(new uint16_t[MAX_SHADOW_INDEX_COUNT]); - ShadowTessellator::generateShadowIndices(shadowIndices.get()); - glGenBuffers(1, &mShadowStripsIndices); - bool force = bindIndicesBufferInternal(mShadowStripsIndices); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, MAX_SHADOW_INDEX_COUNT * sizeof(uint16_t), - shadowIndices.get(), GL_STATIC_DRAW); - return force; - } - - return bindIndicesBufferInternal(mShadowStripsIndices); -} - -bool Caches::unbindIndicesBuffer() { - if (mCurrentIndicesBuffer) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - mCurrentIndicesBuffer = 0; - return true; - } - return false; -} - -/////////////////////////////////////////////////////////////////////////////// -// PBO -/////////////////////////////////////////////////////////////////////////////// - -bool Caches::bindPixelBuffer(const GLuint buffer) { - if (mCurrentPixelBuffer != buffer) { - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer); - mCurrentPixelBuffer = buffer; - return true; - } - return false; -} - -bool Caches::unbindPixelBuffer() { - if (mCurrentPixelBuffer) { - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - mCurrentPixelBuffer = 0; - return true; - } - return false; -} - -/////////////////////////////////////////////////////////////////////////////// -// Meshes and textures +// Textures /////////////////////////////////////////////////////////////////////////////// -void Caches::bindPositionVertexPointer(bool force, const GLvoid* vertices, GLsizei stride) { - if (force || vertices != mCurrentPositionPointer || stride != mCurrentPositionStride) { - GLuint slot = currentProgram->position; - glVertexAttribPointer(slot, 2, GL_FLOAT, GL_FALSE, stride, vertices); - mCurrentPositionPointer = vertices; - mCurrentPositionStride = stride; - } -} - -void Caches::bindTexCoordsVertexPointer(bool force, const GLvoid* vertices, GLsizei stride) { - if (force || vertices != mCurrentTexCoordsPointer || stride != mCurrentTexCoordsStride) { - GLuint slot = currentProgram->texCoords; - glVertexAttribPointer(slot, 2, GL_FLOAT, GL_FALSE, stride, vertices); - mCurrentTexCoordsPointer = vertices; - mCurrentTexCoordsStride = stride; - } -} - -void Caches::resetVertexPointers() { - mCurrentPositionPointer = this; - mCurrentTexCoordsPointer = this; -} - -void Caches::resetTexCoordsVertexPointer() { - mCurrentTexCoordsPointer = this; -} - -void Caches::enableTexCoordsVertexArray() { - if (!mTexCoordsArrayEnabled) { - glEnableVertexAttribArray(Program::kBindingTexCoords); - mCurrentTexCoordsPointer = this; - mTexCoordsArrayEnabled = true; - } -} - -void Caches::disableTexCoordsVertexArray() { - if (mTexCoordsArrayEnabled) { - glDisableVertexAttribArray(Program::kBindingTexCoords); - mTexCoordsArrayEnabled = false; - } -} - void Caches::activeTexture(GLuint textureUnit) { if (mTextureUnit != textureUnit) { glActiveTexture(gTextureUnits[textureUnit]); @@ -614,7 +450,7 @@ void Caches::unregisterFunctors(uint32_t functorCount) { TextureVertex* Caches::getRegionMesh() { // Create the mesh, 2 triangles and 4 vertices per rectangle in the region if (!mRegionMesh) { - mRegionMesh.reset(new TextureVertex[gMaxNumberOfQuads * 4]); + mRegionMesh.reset(new TextureVertex[kMaxNumberOfQuads * 4]); } return mRegionMesh.get(); diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h index fb75dd3..8d23833 100644 --- a/libs/hwui/Caches.h +++ b/libs/hwui/Caches.h @@ -21,7 +21,27 @@ #define LOG_TAG "OpenGLRenderer" #endif + +#include "AssetAtlas.h" +#include "Dither.h" +#include "Extensions.h" +#include "FboCache.h" +#include "GradientCache.h" +#include "LayerCache.h" +#include "PatchCache.h" +#include "ProgramCache.h" +#include "PathCache.h" +#include "RenderBufferCache.h" +#include "renderstate/PixelBufferState.h" +#include "ResourceCache.h" +#include "TessellationCache.h" +#include "TextDropShadowCache.h" +#include "TextureCache.h" +#include "thread/TaskProcessor.h" +#include "thread/TaskManager.h" + #include <vector> +#include <memory> #include <GLES3/gl3.h> @@ -33,25 +53,6 @@ #include <SkPath.h> -#include "thread/TaskProcessor.h" -#include "thread/TaskManager.h" - -#include "AssetAtlas.h" -#include "Extensions.h" -#include "TextureCache.h" -#include "LayerCache.h" -#include "RenderBufferCache.h" -#include "GradientCache.h" -#include "PatchCache.h" -#include "ProgramCache.h" -#include "PathCache.h" -#include "TessellationCache.h" -#include "TextDropShadowCache.h" -#include "FboCache.h" -#include "ResourceCache.h" -#include "Stencil.h" -#include "Dither.h" - namespace android { namespace uirenderer { @@ -64,29 +65,6 @@ class GammaFontRenderer; // GL ES 2.0 defines that at least 16 texture units must be supported #define REQUIRED_TEXTURE_UNITS_COUNT 3 -// Maximum number of quads that pre-allocated meshes can draw -static const uint32_t gMaxNumberOfQuads = 2048; - -// Generates simple and textured vertices -#define FV(x, y, u, v) { x, y, u, v } - -// This array is never used directly but used as a memcpy source in the -// OpenGLRenderer constructor -static const TextureVertex gMeshVertices[] = { - FV(0.0f, 0.0f, 0.0f, 0.0f), - FV(1.0f, 0.0f, 1.0f, 0.0f), - FV(0.0f, 1.0f, 0.0f, 1.0f), - FV(1.0f, 1.0f, 1.0f, 1.0f) -}; -static const GLsizei gMeshStride = sizeof(TextureVertex); -static const GLsizei gVertexStride = sizeof(Vertex); -static const GLsizei gAlphaVertexStride = sizeof(AlphaVertex); -static const GLsizei gMeshTextureOffset = 2 * sizeof(float); -static const GLsizei gVertexAlphaOffset = 2 * sizeof(float); -static const GLsizei gVertexAAWidthOffset = 2 * sizeof(float); -static const GLsizei gVertexAALengthOffset = 3 * sizeof(float); -static const GLsizei gMeshCount = 4; - // Must define as many texture units as specified by REQUIRED_TEXTURE_UNITS_COUNT static const GLenum gTextureUnits[] = { GL_TEXTURE0, @@ -95,28 +73,31 @@ static const GLenum gTextureUnits[] = { }; /////////////////////////////////////////////////////////////////////////////// -// Debug -/////////////////////////////////////////////////////////////////////////////// - -struct CacheLogger { - CacheLogger() { - INIT_LOGD("Creating OpenGL renderer caches"); - } -}; // struct CacheLogger - -/////////////////////////////////////////////////////////////////////////////// // Caches /////////////////////////////////////////////////////////////////////////////// class RenderNode; class RenderState; -class ANDROID_API Caches: public Singleton<Caches> { - Caches(); +class ANDROID_API Caches { +public: + static Caches& createInstance(RenderState& renderState) { + LOG_ALWAYS_FATAL_IF(sInstance, "double create of Caches attempted"); + sInstance = new Caches(renderState); + return *sInstance; + } - friend class Singleton<Caches>; + static Caches& getInstance() { + LOG_ALWAYS_FATAL_IF(!sInstance, "instance not yet created"); + return *sInstance; + } - CacheLogger mLogger; + static bool hasInstance() { + return sInstance != 0; + } +private: + Caches(RenderState& renderState); + static Caches* sInstance; public: enum FlushMode { @@ -135,8 +116,6 @@ public: */ bool initProperties(); - void setRenderState(RenderState* renderState) { mRenderState = renderState; } - /** * Flush the cache. * @@ -175,59 +154,6 @@ public: */ void deleteLayerDeferred(Layer* layer); - /** - * Binds the VBO used to render simple textured quads. - */ - bool bindMeshBuffer(); - - /** - * Binds the specified VBO if needed. - */ - bool bindMeshBuffer(const GLuint buffer); - - /** - * Unbinds the VBO used to render simple textured quads. - */ - bool unbindMeshBuffer(); - - /** - * Binds a global indices buffer that can draw up to - * gMaxNumberOfQuads quads. - */ - bool bindQuadIndicesBuffer(); - bool bindShadowIndicesBuffer(); - bool unbindIndicesBuffer(); - - /** - * Binds the specified buffer as the current GL unpack pixel buffer. - */ - bool bindPixelBuffer(const GLuint buffer); - - /** - * Resets the current unpack pixel buffer to 0 (default value.) - */ - bool unbindPixelBuffer(); - - /** - * Binds an attrib to the specified float vertex pointer. - * Assumes a stride of gMeshStride and a size of 2. - */ - void bindPositionVertexPointer(bool force, const GLvoid* vertices, GLsizei stride = gMeshStride); - - /** - * Binds an attrib to the specified float vertex pointer. - * Assumes a stride of gMeshStride and a size of 2. - */ - void bindTexCoordsVertexPointer(bool force, const GLvoid* vertices, GLsizei stride = gMeshStride); - - /** - * Resets the vertex pointers. - */ - void resetVertexPointers(); - void resetTexCoordsVertexPointer(); - - void enableTexCoordsVertexArray(); - void disableTexCoordsVertexArray(); /** * Activate the specified texture unit. The texture unit must @@ -300,9 +226,6 @@ public: bool drawDeferDisabled; bool drawReorderDisabled; - // VBO to draw with - GLuint meshBuffer; - // Misc GLint maxTextureSize; @@ -333,7 +256,6 @@ public: TaskManager tasks; Dither dither; - Stencil stencil; bool gpuPixelBuffersEnabled; @@ -356,6 +278,8 @@ public: int propertyAmbientShadowStrength; int propertySpotShadowStrength; + PixelBufferState& pixelBuffer() { return *mPixelBufferState; } + private: enum OverdrawColorSet { kColorSet_Default = 0, @@ -367,8 +291,6 @@ private: void initConstraints(); void initStaticProperties(); - bool bindIndicesBufferInternal(const GLuint buffer); - static void eventMarkNull(GLsizei length, const GLchar* marker) { } static void startMarkNull(GLsizei length, const GLchar* marker) { } static void endMarkNull() { } @@ -381,15 +303,9 @@ private: if (label) *label = '\0'; } - GLuint mCurrentBuffer; - GLuint mCurrentIndicesBuffer; - GLuint mCurrentPixelBuffer; - const void* mCurrentPositionPointer; - GLsizei mCurrentPositionStride; - const void* mCurrentTexCoordsPointer; - GLsizei mCurrentTexCoordsStride; + RenderState* mRenderState; - bool mTexCoordsArrayEnabled; + std::unique_ptr<PixelBufferState> mPixelBufferState; // TODO: move to RenderState GLuint mTextureUnit; @@ -398,10 +314,6 @@ private: // Used to render layers std::unique_ptr<TextureVertex[]> mRegionMesh; - // Global index buffer - GLuint mMeshIndices; - GLuint mShadowStripsIndices; - mutable Mutex mGarbageLock; Vector<Layer*> mLayerGarbage; @@ -414,8 +326,6 @@ private: GLuint mBoundTextures[REQUIRED_TEXTURE_UNITS_COUNT]; OverdrawColorSet mOverdrawDebugColorSet; - - RenderState* mRenderState; }; // class Caches }; // namespace uirenderer diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp index a0bc7b0..193474f 100644 --- a/libs/hwui/FontRenderer.cpp +++ b/libs/hwui/FontRenderer.cpp @@ -14,7 +14,17 @@ * limitations under the License. */ -#define LOG_TAG "OpenGLRenderer" +#include "FontRenderer.h" + +#include "Caches.h" +#include "Debug.h" +#include "Extensions.h" +#include "OpenGLRenderer.h" +#include "PixelBuffer.h" +#include "Rect.h" +#include "renderstate/RenderState.h" +#include "utils/Blur.h" +#include "utils/Timing.h" #include <SkGlyph.h> #include <SkUtils.h> @@ -27,17 +37,6 @@ #include <RenderScript.h> #endif -#include "utils/Blur.h" -#include "utils/Timing.h" - -#include "Caches.h" -#include "Debug.h" -#include "Extensions.h" -#include "FontRenderer.h" -#include "OpenGLRenderer.h" -#include "PixelBuffer.h" -#include "Rect.h" - namespace android { namespace uirenderer { @@ -47,9 +46,7 @@ namespace uirenderer { /////////////////////////////////////////////////////////////////////////////// // TextSetupFunctor /////////////////////////////////////////////////////////////////////////////// -status_t TextSetupFunctor::operator ()(int what, void* data) { - Data* typedData = reinterpret_cast<Data*>(data); - GLenum glyphFormat = typedData ? typedData->glyphFormat : GL_ALPHA; +status_t TextSetupFunctor::setup(GLenum glyphFormat) { renderer->setupDraw(); renderer->setupDrawTextGamma(paint); @@ -397,7 +394,7 @@ void FontRenderer::cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyp CacheTexture* FontRenderer::createCacheTexture(int width, int height, GLenum format, bool allocate) { - CacheTexture* cacheTexture = new CacheTexture(width, height, format, gMaxNumberOfQuads); + CacheTexture* cacheTexture = new CacheTexture(width, height, format, kMaxNumberOfQuads); if (allocate) { Caches::getInstance().activeTexture(0); @@ -473,7 +470,7 @@ void FontRenderer::checkTextureUpdate() { checkTextureUpdateForCache(caches, mRGBACacheTextures, resetPixelStore, lastTextureId); // Unbind any PBO we might have used to update textures - caches.unbindPixelBuffer(); + caches.pixelBuffer().unbind(); // Reset to default unpack row length to avoid affecting texture // uploads in other parts of the renderer @@ -485,26 +482,29 @@ void FontRenderer::checkTextureUpdate() { } void FontRenderer::issueDrawCommand(Vector<CacheTexture*>& cacheTextures) { - Caches& caches = Caches::getInstance(); + if (!mFunctor) return; + + Caches& caches = mFunctor->renderer->getCaches(); + RenderState& renderState = mFunctor->renderer->renderState(); + bool first = true; - bool force = false; + bool forceRebind = false; for (uint32_t i = 0; i < cacheTextures.size(); i++) { CacheTexture* texture = cacheTextures[i]; if (texture->canDraw()) { if (first) { if (mFunctor) { - TextSetupFunctor::Data functorData(texture->getFormat()); - (*mFunctor)(0, &functorData); + mFunctor->setup(texture->getFormat()); } checkTextureUpdate(); - caches.bindQuadIndicesBuffer(); + renderState.meshState().bindQuadIndicesBuffer(); if (!mDrawn) { // If returns true, a VBO was bound and we must // rebind our vertex attrib pointers even if // they have the same values as the current pointers - force = caches.unbindMeshBuffer(); + forceRebind = renderState.meshState().unbindMeshBuffer(); } caches.activeTexture(0); @@ -515,14 +515,16 @@ void FontRenderer::issueDrawCommand(Vector<CacheTexture*>& cacheTextures) { texture->setLinearFiltering(mLinearFiltering, false); TextureVertex* mesh = texture->mesh(); - caches.bindPositionVertexPointer(force, &mesh[0].x); - caches.bindTexCoordsVertexPointer(force, &mesh[0].u); - force = false; + MeshState& meshState = renderState.meshState(); + Program* program = caches.currentProgram; + meshState.bindPositionVertexPointer(program, forceRebind, &mesh[0].x); + meshState.bindTexCoordsVertexPointer(program, forceRebind, &mesh[0].u); glDrawElements(GL_TRIANGLES, texture->meshElementCount(), GL_UNSIGNED_SHORT, texture->indices()); texture->resetMesh(); + forceRebind = false; } } } @@ -647,7 +649,7 @@ FontRenderer::DropShadow FontRenderer::renderDropShadow(const SkPaint* paint, co Font::BITMAP, dataBuffer, paddedWidth, paddedHeight, nullptr, positions); // Unbind any PBO we might have used - Caches::getInstance().unbindPixelBuffer(); + Caches::getInstance().pixelBuffer().unbind(); blurImage(&dataBuffer, paddedWidth, paddedHeight, radius); } @@ -661,7 +663,7 @@ FontRenderer::DropShadow FontRenderer::renderDropShadow(const SkPaint* paint, co return image; } -void FontRenderer::initRender(const Rect* clip, Rect* bounds, Functor* functor) { +void FontRenderer::initRender(const Rect* clip, Rect* bounds, TextSetupFunctor* functor) { checkInit(); mDrawn = false; @@ -689,7 +691,7 @@ void FontRenderer::endPrecaching() { bool FontRenderer::renderPosText(const SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex, uint32_t len, int numGlyphs, int x, int y, - const float* positions, Rect* bounds, Functor* functor, bool forceFinish) { + const float* positions, Rect* bounds, TextSetupFunctor* functor, bool forceFinish) { if (!mCurrentFont) { ALOGE("No font set"); return false; @@ -707,7 +709,7 @@ bool FontRenderer::renderPosText(const SkPaint* paint, const Rect* clip, const c bool FontRenderer::renderTextOnPath(const SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex, uint32_t len, int numGlyphs, const SkPath* path, - float hOffset, float vOffset, Rect* bounds, Functor* functor) { + float hOffset, float vOffset, Rect* bounds, TextSetupFunctor* functor) { if (!mCurrentFont) { ALOGE("No font set"); return false; diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h index 668ee64..cb63684 100644 --- a/libs/hwui/FontRenderer.h +++ b/libs/hwui/FontRenderer.h @@ -17,7 +17,12 @@ #ifndef ANDROID_HWUI_FONT_RENDERER_H #define ANDROID_HWUI_FONT_RENDERER_H -#include <utils/Functor.h> +#include "font/FontUtil.h" +#include "font/CacheTexture.h" +#include "font/CachedGlyphInfo.h" +#include "font/Font.h" +#include "utils/SortedList.h" + #include <utils/LruCache.h> #include <utils/Vector.h> #include <utils/StrongPointer.h> @@ -26,12 +31,6 @@ #include <GLES2/gl2.h> -#include "font/FontUtil.h" -#include "font/CacheTexture.h" -#include "font/CachedGlyphInfo.h" -#include "font/Font.h" -#include "utils/SortedList.h" - #ifdef ANDROID_ENABLE_RENDERSCRIPT #include "RenderScript.h" namespace RSC { @@ -47,26 +46,20 @@ namespace uirenderer { class OpenGLRenderer; -/////////////////////////////////////////////////////////////////////////////// -// TextSetupFunctor -/////////////////////////////////////////////////////////////////////////////// -class TextSetupFunctor: public Functor { +class TextSetupFunctor { public: - struct Data { - Data(GLenum glyphFormat) : glyphFormat(glyphFormat) { - } - - GLenum glyphFormat; - }; - TextSetupFunctor(OpenGLRenderer* renderer, float x, float y, bool pureTranslate, - int alpha, SkXfermode::Mode mode, const SkPaint* paint): Functor(), - renderer(renderer), x(x), y(y), pureTranslate(pureTranslate), - alpha(alpha), mode(mode), paint(paint) { + int alpha, SkXfermode::Mode mode, const SkPaint* paint) + : renderer(renderer) + , x(x) + , y(y) + , pureTranslate(pureTranslate) + , alpha(alpha) + , mode(mode) + , paint(paint) { } - ~TextSetupFunctor() { } - status_t operator ()(int what, void* data) override; + status_t setup(GLenum glyphFormat); OpenGLRenderer* renderer; float x; @@ -77,10 +70,6 @@ public: const SkPaint* paint; }; -/////////////////////////////////////////////////////////////////////////////// -// FontRenderer -/////////////////////////////////////////////////////////////////////////////// - class FontRenderer { public: FontRenderer(); @@ -101,22 +90,14 @@ public: // bounds is an out parameter bool renderPosText(const SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex, uint32_t len, int numGlyphs, int x, int y, const float* positions, - Rect* bounds, Functor* functor, bool forceFinish = true); + Rect* bounds, TextSetupFunctor* functor, bool forceFinish = true); // bounds is an out parameter bool renderTextOnPath(const SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex, uint32_t len, int numGlyphs, const SkPath* path, - float hOffset, float vOffset, Rect* bounds, Functor* functor); + float hOffset, float vOffset, Rect* bounds, TextSetupFunctor* functor); struct DropShadow { - DropShadow() { }; - - DropShadow(const DropShadow& dropShadow): - width(dropShadow.width), height(dropShadow.height), - image(dropShadow.image), penX(dropShadow.penX), - penY(dropShadow.penY) { - } - uint32_t width; uint32_t height; uint8_t* image; @@ -152,7 +133,7 @@ private: void flushAllAndInvalidate(); void checkInit(); - void initRender(const Rect* clip, Rect* bounds, Functor* functor); + void initRender(const Rect* clip, Rect* bounds, TextSetupFunctor* functor); void finishRender(); void issueDrawCommand(Vector<CacheTexture*>& cacheTextures); @@ -193,7 +174,7 @@ private: bool mUploadTexture; - Functor* mFunctor; + TextSetupFunctor* mFunctor; const Rect* mClip; Rect* mBounds; bool mDrawn; diff --git a/libs/hwui/GradientCache.h b/libs/hwui/GradientCache.h index 9176c76..1714e6d 100644 --- a/libs/hwui/GradientCache.h +++ b/libs/hwui/GradientCache.h @@ -17,6 +17,8 @@ #ifndef ANDROID_HWUI_GRADIENT_CACHE_H #define ANDROID_HWUI_GRADIENT_CACHE_H +#include <memory> + #include <GLES3/gl3.h> #include <SkShader.h> diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 0844cb6..42b246c 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -152,7 +152,7 @@ OpenGLRenderer::OpenGLRenderer(RenderState& renderState) memset(&mDrawModifiers, 0, sizeof(mDrawModifiers)); mDrawModifiers.mOverrideLayerAlpha = 1.0f; - memcpy(mMeshVertices, gMeshVertices, sizeof(gMeshVertices)); + memcpy(mMeshVertices, kMeshVertices, sizeof(kMeshVertices)); } OpenGLRenderer::~OpenGLRenderer() { @@ -436,22 +436,22 @@ void OpenGLRenderer::renderOverdraw() { clip->bottom - clip->top); // 1x overdraw - mCaches.stencil.enableDebugTest(2); + mRenderState.stencil().enableDebugTest(2); drawColor(mCaches.getOverdrawColor(1), SkXfermode::kSrcOver_Mode); // 2x overdraw - mCaches.stencil.enableDebugTest(3); + mRenderState.stencil().enableDebugTest(3); drawColor(mCaches.getOverdrawColor(2), SkXfermode::kSrcOver_Mode); // 3x overdraw - mCaches.stencil.enableDebugTest(4); + mRenderState.stencil().enableDebugTest(4); drawColor(mCaches.getOverdrawColor(3), SkXfermode::kSrcOver_Mode); // 4x overdraw and higher - mCaches.stencil.enableDebugTest(4, true); + mRenderState.stencil().enableDebugTest(4, true); drawColor(mCaches.getOverdrawColor(4), SkXfermode::kSrcOver_Mode); - mCaches.stencil.disable(); + mRenderState.stencil().disable(); } } @@ -894,7 +894,7 @@ void OpenGLRenderer::composeLayer(const Snapshot& removed, const Snapshot& resto layer->setAlpha(255); } - mCaches.unbindMeshBuffer(); + mRenderState.meshState().unbindMeshBuffer(); mCaches.activeTexture(0); @@ -963,7 +963,7 @@ void OpenGLRenderer::drawTextureLayer(Layer* layer, const Rect& rect) { setupDrawTextureTransformUniforms(layer->getTexTransform()); setupDrawMesh(&mMeshVertices[0].x, &mMeshVertices[0].u); - glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount); + glDrawArrays(GL_TRIANGLE_STRIP, 0, kMeshCount); } void OpenGLRenderer::composeLayerRect(Layer* layer, const Rect& rect, bool swap) { @@ -1005,7 +1005,7 @@ void OpenGLRenderer::composeLayerRect(Layer* layer, const Rect& rect, bool swap) drawTextureMesh(x, y, x + rect.getWidth(), y + rect.getHeight(), layer->getTexture(), &layerPaint, blend, &mMeshVertices[0].x, &mMeshVertices[0].u, - GL_TRIANGLE_STRIP, gMeshCount, swap, swap || simpleTransform); + GL_TRIANGLE_STRIP, kMeshCount, swap, swap || simpleTransform); resetDrawTextureTexCoords(0.0f, 0.0f, 1.0f, 1.0f); } @@ -1171,7 +1171,7 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) { numQuads++; - if (numQuads >= gMaxNumberOfQuads) { + if (numQuads >= kMaxNumberOfQuads) { DRAW_DOUBLE_STENCIL(glDrawElements(GL_TRIANGLES, numQuads * 6, GL_UNSIGNED_SHORT, nullptr)); numQuads = 0; @@ -1264,7 +1264,7 @@ void OpenGLRenderer::dirtyLayerUnchecked(Rect& bounds, Region* region) { void OpenGLRenderer::issueIndexedQuadDraw(Vertex* mesh, GLsizei quadsCount) { GLsizei elementsCount = quadsCount * 6; while (elementsCount > 0) { - GLsizei drawCount = min(elementsCount, (GLsizei) gMaxNumberOfQuads * 6); + GLsizei drawCount = min(elementsCount, (GLsizei) kMaxNumberOfQuads * 6); setupDrawIndexedVertices(&mesh[0].x); glDrawElements(GL_TRIANGLES, drawCount, GL_UNSIGNED_SHORT, nullptr); @@ -1537,7 +1537,7 @@ void OpenGLRenderer::setStencilFromClip() { incrementThreshold = 0; } - mCaches.stencil.enableWrite(incrementThreshold); + mRenderState.stencil().enableWrite(incrementThreshold); // Clean and update the stencil, but first make sure we restrict drawing // to the region's bounds @@ -1547,7 +1547,7 @@ void OpenGLRenderer::setStencilFromClip() { setScissorFromClip(); } - mCaches.stencil.clear(); + mRenderState.stencil().clear(); // stash and disable the outline clip state, since stencil doesn't account for outline bool storedSkipOutlineClip = mSkipOutlineClip; @@ -1571,7 +1571,7 @@ void OpenGLRenderer::setStencilFromClip() { if (resetScissor) mRenderState.scissor().setEnabled(false); mSkipOutlineClip = storedSkipOutlineClip; - mCaches.stencil.enableTest(incrementThreshold); + mRenderState.stencil().enableTest(incrementThreshold); // Draw the region used to generate the stencil if the appropriate debug // mode is enabled @@ -1584,7 +1584,7 @@ void OpenGLRenderer::setStencilFromClip() { } } else { EVENT_LOGD("setStencilFromClip - disabling"); - mCaches.stencil.disable(); + mRenderState.stencil().disable(); } } } @@ -1661,7 +1661,7 @@ void OpenGLRenderer::setupDraw(bool clearLayer) { // the stencil buffer and if stencil highlight debugging is on mDescription.hasDebugHighlight = !mCaches.debugOverdraw && mCaches.debugStencilClip == Caches::kStencilShowHighlight && - mCaches.stencil.isTestEnabled(); + mRenderState.stencil().isTestEnabled(); } void OpenGLRenderer::setupDrawWithTexture(bool isAlpha8) { @@ -1680,7 +1680,7 @@ void OpenGLRenderer::setupDrawWithExternalTexture() { } void OpenGLRenderer::setupDrawNoTexture() { - mCaches.disableTexCoordsVertexArray(); + mRenderState.meshState().disableTexCoordsVertexArray(); } void OpenGLRenderer::setupDrawVertexAlpha(bool useShadowAlphaInterp) { @@ -1892,21 +1892,21 @@ void OpenGLRenderer::setupDrawTextGammaUniforms() { } void OpenGLRenderer::setupDrawSimpleMesh() { - bool force = mCaches.bindMeshBuffer(); - mCaches.bindPositionVertexPointer(force, nullptr); - mCaches.unbindIndicesBuffer(); + bool force = mRenderState.meshState().bindMeshBuffer(); + mRenderState.meshState().bindPositionVertexPointer(mCaches.currentProgram, force, nullptr); + mRenderState.meshState().unbindIndicesBuffer(); } void OpenGLRenderer::setupDrawTexture(GLuint texture) { if (texture) bindTexture(texture); mTextureUnit++; - mCaches.enableTexCoordsVertexArray(); + mRenderState.meshState().enableTexCoordsVertexArray(); } void OpenGLRenderer::setupDrawExternalTexture(GLuint texture) { bindExternalTexture(texture); mTextureUnit++; - mCaches.enableTexCoordsVertexArray(); + mRenderState.meshState().enableTexCoordsVertexArray(); } void OpenGLRenderer::setupDrawTextureTransform() { @@ -1922,27 +1922,29 @@ void OpenGLRenderer::setupDrawMesh(const GLvoid* vertices, const GLvoid* texCoords, GLuint vbo) { bool force = false; if (!vertices || vbo) { - force = mCaches.bindMeshBuffer(vbo == 0 ? mCaches.meshBuffer : vbo); + force = mRenderState.meshState().bindMeshBuffer(vbo); } else { - force = mCaches.unbindMeshBuffer(); + force = mRenderState.meshState().unbindMeshBuffer(); } - mCaches.bindPositionVertexPointer(force, vertices); + mRenderState.meshState().bindPositionVertexPointer(mCaches.currentProgram, force, vertices); if (mCaches.currentProgram->texCoords >= 0) { - mCaches.bindTexCoordsVertexPointer(force, texCoords); + mRenderState.meshState().bindTexCoordsVertexPointer(mCaches.currentProgram, force, texCoords); } - mCaches.unbindIndicesBuffer(); + mRenderState.meshState().unbindIndicesBuffer(); } void OpenGLRenderer::setupDrawMesh(const GLvoid* vertices, const GLvoid* texCoords, const GLvoid* colors) { - bool force = mCaches.unbindMeshBuffer(); + bool force = mRenderState.meshState().unbindMeshBuffer(); GLsizei stride = sizeof(ColorTextureVertex); - mCaches.bindPositionVertexPointer(force, vertices, stride); + mRenderState.meshState().bindPositionVertexPointer(mCaches.currentProgram, force, + vertices, stride); if (mCaches.currentProgram->texCoords >= 0) { - mCaches.bindTexCoordsVertexPointer(force, texCoords, stride); + mRenderState.meshState().bindTexCoordsVertexPointer(mCaches.currentProgram, force, + texCoords, stride); } int slot = mCaches.currentProgram->getAttrib("colors"); if (slot >= 0) { @@ -1950,7 +1952,7 @@ void OpenGLRenderer::setupDrawMesh(const GLvoid* vertices, glVertexAttribPointer(slot, 4, GL_FLOAT, GL_FALSE, stride, colors); } - mCaches.unbindIndicesBuffer(); + mRenderState.meshState().unbindIndicesBuffer(); } void OpenGLRenderer::setupDrawMeshIndices(const GLvoid* vertices, @@ -1958,24 +1960,26 @@ void OpenGLRenderer::setupDrawMeshIndices(const GLvoid* vertices, bool force = false; // If vbo is != 0 we want to treat the vertices parameter as an offset inside // a VBO. However, if vertices is set to NULL and vbo == 0 then we want to - // use the default VBO found in Caches + // use the default VBO found in RenderState if (!vertices || vbo) { - force = mCaches.bindMeshBuffer(vbo == 0 ? mCaches.meshBuffer : vbo); + force = mRenderState.meshState().bindMeshBuffer(vbo); } else { - force = mCaches.unbindMeshBuffer(); + force = mRenderState.meshState().unbindMeshBuffer(); } - mCaches.bindQuadIndicesBuffer(); + mRenderState.meshState().bindQuadIndicesBuffer(); - mCaches.bindPositionVertexPointer(force, vertices); + mRenderState.meshState().bindPositionVertexPointer(mCaches.currentProgram, force, vertices); if (mCaches.currentProgram->texCoords >= 0) { - mCaches.bindTexCoordsVertexPointer(force, texCoords); + mRenderState.meshState().bindTexCoordsVertexPointer(mCaches.currentProgram, + force, texCoords); } } void OpenGLRenderer::setupDrawIndexedVertices(GLvoid* vertices) { - bool force = mCaches.unbindMeshBuffer(); - mCaches.bindQuadIndicesBuffer(); - mCaches.bindPositionVertexPointer(force, vertices, gVertexStride); + bool force = mRenderState.meshState().unbindMeshBuffer(); + mRenderState.meshState().bindQuadIndicesBuffer(); + mRenderState.meshState().bindPositionVertexPointer(mCaches.currentProgram, force, + vertices, kVertexStride); } /////////////////////////////////////////////////////////////////////////////// @@ -2034,8 +2038,8 @@ void OpenGLRenderer::drawAlphaBitmap(Texture* texture, float left, float top, // No need to check for a UV mapper on the texture object, only ARGB_8888 // bitmaps get packed in the atlas drawAlpha8TextureMesh(x, y, x + texture->width, y + texture->height, texture->id, - paint, (GLvoid*) nullptr, (GLvoid*) gMeshTextureOffset, - GL_TRIANGLE_STRIP, gMeshCount, ignoreTransform); + paint, (GLvoid*) nullptr, (GLvoid*) kMeshTextureOffset, + GL_TRIANGLE_STRIP, kMeshCount, ignoreTransform); } /** @@ -2228,7 +2232,7 @@ void OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, getMapper(texture).map(u1, v1, u2, v2); - mCaches.unbindMeshBuffer(); + mRenderState.meshState().unbindMeshBuffer(); resetDrawTextureTexCoords(u1, v1, u2, v2); texture->setWrap(GL_CLAMP_TO_EDGE, true); @@ -2275,12 +2279,12 @@ void OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, drawAlpha8TextureMesh(dstLeft, dstTop, dstRight, dstBottom, texture->id, paint, &mMeshVertices[0].x, &mMeshVertices[0].u, - GL_TRIANGLE_STRIP, gMeshCount, ignoreTransform); + GL_TRIANGLE_STRIP, kMeshCount, ignoreTransform); } else { drawTextureMesh(dstLeft, dstTop, dstRight, dstBottom, texture->id, paint, texture->blend, &mMeshVertices[0].x, &mMeshVertices[0].u, - GL_TRIANGLE_STRIP, gMeshCount, false, ignoreTransform); + GL_TRIANGLE_STRIP, kMeshCount, false, ignoreTransform); } if (CC_UNLIKELY(useScaleTransform)) { @@ -2412,33 +2416,34 @@ void OpenGLRenderer::drawVertexBuffer(float translateX, float translateY, setupDrawShaderUniforms(getShader(paint)); const void* vertices = vertexBuffer.getBuffer(); - mCaches.unbindMeshBuffer(); - mCaches.bindPositionVertexPointer(true, vertices, isAA ? gAlphaVertexStride : gVertexStride); - mCaches.resetTexCoordsVertexPointer(); + mRenderState.meshState().unbindMeshBuffer(); + mRenderState.meshState().bindPositionVertexPointer(mCaches.currentProgram, + true, vertices, isAA ? kAlphaVertexStride : kVertexStride); + mRenderState.meshState().resetTexCoordsVertexPointer(); int alphaSlot = -1; if (isAA) { - void* alphaCoords = ((GLbyte*) vertices) + gVertexAlphaOffset; + void* alphaCoords = ((GLbyte*) vertices) + kVertexAlphaOffset; alphaSlot = mCaches.currentProgram->getAttrib("vtxAlpha"); // TODO: avoid enable/disable in back to back uses of the alpha attribute glEnableVertexAttribArray(alphaSlot); - glVertexAttribPointer(alphaSlot, 1, GL_FLOAT, GL_FALSE, gAlphaVertexStride, alphaCoords); + glVertexAttribPointer(alphaSlot, 1, GL_FLOAT, GL_FALSE, kAlphaVertexStride, alphaCoords); } const VertexBuffer::Mode mode = vertexBuffer.getMode(); if (mode == VertexBuffer::kStandard) { - mCaches.unbindIndicesBuffer(); + mRenderState.meshState().unbindIndicesBuffer(); glDrawArrays(GL_TRIANGLE_STRIP, 0, vertexBuffer.getVertexCount()); } else if (mode == VertexBuffer::kOnePolyRingShadow) { - mCaches.bindShadowIndicesBuffer(); + mRenderState.meshState().bindShadowIndicesBuffer(); glDrawElements(GL_TRIANGLE_STRIP, ONE_POLY_RING_SHADOW_INDEX_COUNT, GL_UNSIGNED_SHORT, nullptr); } else if (mode == VertexBuffer::kTwoPolyRingShadow) { - mCaches.bindShadowIndicesBuffer(); + mRenderState.meshState().bindShadowIndicesBuffer(); glDrawElements(GL_TRIANGLE_STRIP, TWO_POLY_RING_SHADOW_INDEX_COUNT, GL_UNSIGNED_SHORT, nullptr); } else if (mode == VertexBuffer::kIndices) { - mCaches.unbindIndicesBuffer(); + mRenderState.meshState().unbindIndicesBuffer(); glDrawElements(GL_TRIANGLE_STRIP, vertexBuffer.getIndexCount(), GL_UNSIGNED_SHORT, vertexBuffer.getIndices()); } @@ -2720,9 +2725,9 @@ void OpenGLRenderer::drawTextShadow(const SkPaint* paint, const char* text, setupDrawPureColorUniforms(); setupDrawColorFilterUniforms(getColorFilter(paint)); setupDrawShaderUniforms(getShader(paint)); - setupDrawMesh(nullptr, (GLvoid*) gMeshTextureOffset); + setupDrawMesh(nullptr, (GLvoid*) kMeshTextureOffset); - glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount); + glDrawArrays(GL_TRIANGLE_STRIP, 0, kMeshCount); } bool OpenGLRenderer::canSkipText(const SkPaint* paint) const { @@ -2872,8 +2877,6 @@ void OpenGLRenderer::setClippingRoundRect(LinearAllocator& allocator, mState.setClippingRoundRect(allocator, rect, radius, highPriority); } - - void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, float x, float y, const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds, DrawOpMode drawOpMode) { @@ -3078,7 +3081,7 @@ void OpenGLRenderer::drawLayer(Layer* layer, float x, float y) { GLsizei elementsCount = layer->meshElementCount; while (elementsCount > 0) { - GLsizei drawCount = min(elementsCount, (GLsizei) gMaxNumberOfQuads * 6); + GLsizei drawCount = min(elementsCount, (GLsizei) kMaxNumberOfQuads * 6); setupDrawMeshIndices(&mesh[0].x, &mesh[0].u); DRAW_DOUBLE_STENCIL_IF(!layer->hasDrawnSinceUpdate, @@ -3156,9 +3159,9 @@ void OpenGLRenderer::drawPathTexture(const PathTexture* texture, setupDrawPureColorUniforms(); setupDrawColorFilterUniforms(getColorFilter(paint)); setupDrawShaderUniforms(getShader(paint)); - setupDrawMesh(nullptr, (GLvoid*) gMeshTextureOffset); + setupDrawMesh(nullptr, (GLvoid*) kMeshTextureOffset); - glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount); + glDrawArrays(GL_TRIANGLE_STRIP, 0, kMeshCount); } // Same values used by Skia @@ -3337,7 +3340,7 @@ void OpenGLRenderer::drawColorRect(float left, float top, float right, float bot setupDrawColorFilterUniforms(getColorFilter(paint)); setupDrawSimpleMesh(); - glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount); + glDrawArrays(GL_TRIANGLE_STRIP, 0, kMeshCount); } void OpenGLRenderer::drawTextureRect(float left, float top, float right, float bottom, @@ -3345,7 +3348,7 @@ void OpenGLRenderer::drawTextureRect(float left, float top, float right, float b texture->setWrap(GL_CLAMP_TO_EDGE, true); GLvoid* vertices = (GLvoid*) nullptr; - GLvoid* texCoords = (GLvoid*) gMeshTextureOffset; + GLvoid* texCoords = (GLvoid*) kMeshTextureOffset; if (texture->uvMapper) { vertices = &mMeshVertices[0].x; @@ -3364,11 +3367,11 @@ void OpenGLRenderer::drawTextureRect(float left, float top, float right, float b texture->setFilter(GL_NEAREST, true); drawTextureMesh(x, y, x + texture->width, y + texture->height, texture->id, paint, texture->blend, vertices, texCoords, - GL_TRIANGLE_STRIP, gMeshCount, false, true); + GL_TRIANGLE_STRIP, kMeshCount, false, true); } else { texture->setFilter(getFilter(paint), true); drawTextureMesh(left, top, right, bottom, texture->id, paint, - texture->blend, vertices, texCoords, GL_TRIANGLE_STRIP, gMeshCount); + texture->blend, vertices, texCoords, GL_TRIANGLE_STRIP, kMeshCount); } if (texture->uvMapper) { diff --git a/libs/hwui/PatchCache.cpp b/libs/hwui/PatchCache.cpp index eb88bc0..af403b4 100644 --- a/libs/hwui/PatchCache.cpp +++ b/libs/hwui/PatchCache.cpp @@ -23,6 +23,7 @@ #include "Patch.h" #include "PatchCache.h" #include "Properties.h" +#include "renderstate/RenderState.h" namespace android { namespace uirenderer { @@ -31,9 +32,13 @@ namespace uirenderer { // Constructors/destructor /////////////////////////////////////////////////////////////////////////////// -PatchCache::PatchCache(): - mSize(0), mCache(LruCache<PatchDescription, Patch*>::kUnlimitedCapacity), - mMeshBuffer(0), mFreeBlocks(nullptr), mGenerationId(0) { +PatchCache::PatchCache(RenderState& renderState) + : mRenderState(renderState) + , mSize(0) + , mCache(LruCache<PatchDescription, Patch*>::kUnlimitedCapacity) + , mMeshBuffer(0) + , mFreeBlocks(nullptr) + , mGenerationId(0) { char property[PROPERTY_VALUE_MAX]; if (property_get(PROPERTY_PATCH_CACHE_SIZE, property, nullptr) > 0) { INIT_LOGD(" Setting patch cache size to %skB", property); @@ -48,15 +53,15 @@ PatchCache::~PatchCache() { clear(); } -void PatchCache::init(Caches& caches) { +void PatchCache::init() { bool created = false; if (!mMeshBuffer) { glGenBuffers(1, &mMeshBuffer); created = true; } - caches.bindMeshBuffer(mMeshBuffer); - caches.resetVertexPointers(); + mRenderState.meshState().bindMeshBuffer(mMeshBuffer); + mRenderState.meshState().resetVertexPointers(); if (created) { createVertexBuffer(); @@ -85,7 +90,7 @@ void PatchCache::clear() { clearCache(); if (mMeshBuffer) { - Caches::getInstance().unbindMeshBuffer(); + mRenderState.meshState().unbindMeshBuffer(); glDeleteBuffers(1, &mMeshBuffer); mMeshBuffer = 0; mSize = 0; @@ -187,7 +192,7 @@ void PatchCache::createVertexBuffer() { */ void PatchCache::setupMesh(Patch* newMesh, TextureVertex* vertices) { // This call ensures the VBO exists and that it is bound - init(Caches::getInstance()); + init(); // If we're running out of space, let's clear the entire cache uint32_t size = newMesh->getSize(); @@ -219,7 +224,7 @@ void PatchCache::setupMesh(Patch* newMesh, TextureVertex* vertices) { // Copy the 9patch mesh in the VBO newMesh->offset = (GLintptr) (block->offset); - newMesh->textureOffset = newMesh->offset + gMeshTextureOffset; + newMesh->textureOffset = newMesh->offset + kMeshTextureOffset; glBufferSubData(GL_ARRAY_BUFFER, newMesh->offset, size, vertices); // Remove the block since we've used it entirely diff --git a/libs/hwui/PatchCache.h b/libs/hwui/PatchCache.h index 4cb5338..e038720 100644 --- a/libs/hwui/PatchCache.h +++ b/libs/hwui/PatchCache.h @@ -51,9 +51,9 @@ class Caches; class PatchCache { public: - PatchCache(); + PatchCache(RenderState& renderState); ~PatchCache(); - void init(Caches& caches); + void init(); const Patch* get(const AssetAtlas::Entry* entry, const uint32_t bitmapWidth, const uint32_t bitmapHeight, @@ -168,6 +168,7 @@ private: void dumpFreeBlocks(const char* prefix); #endif + RenderState& mRenderState; uint32_t mMaxSize; uint32_t mSize; diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp index c564b87..cc7f88d 100644 --- a/libs/hwui/PathCache.cpp +++ b/libs/hwui/PathCache.cpp @@ -31,7 +31,6 @@ #include "PathCache.h" #include "thread/Signal.h" -#include "thread/Task.h" #include "thread/TaskProcessor.h" namespace android { diff --git a/libs/hwui/PathCache.h b/libs/hwui/PathCache.h index ecd3712..7378018 100644 --- a/libs/hwui/PathCache.h +++ b/libs/hwui/PathCache.h @@ -17,21 +17,22 @@ #ifndef ANDROID_HWUI_PATH_CACHE_H #define ANDROID_HWUI_PATH_CACHE_H -#include <GLES2/gl2.h> - -#include <utils/LruCache.h> -#include <utils/Mutex.h> -#include <utils/Vector.h> - #include "Debug.h" #include "Texture.h" +#include "thread/Task.h" +#include "thread/TaskProcessor.h" #include "utils/Macros.h" #include "utils/Pair.h" +#include <GLES2/gl2.h> +#include <SkPath.h> +#include <utils/LruCache.h> +#include <utils/Mutex.h> +#include <utils/Vector.h> + class SkBitmap; class SkCanvas; class SkPaint; -class SkPath; struct SkRect; namespace android { diff --git a/libs/hwui/PixelBuffer.cpp b/libs/hwui/PixelBuffer.cpp index efa271e..62eb68c 100644 --- a/libs/hwui/PixelBuffer.cpp +++ b/libs/hwui/PixelBuffer.cpp @@ -16,13 +16,14 @@ #define LOG_TAG "OpenGLRenderer" -#include <utils/Log.h> +#include "PixelBuffer.h" -#include "Caches.h" #include "Debug.h" #include "Extensions.h" -#include "PixelBuffer.h" #include "Properties.h" +#include "renderstate/RenderState.h" + +#include <utils/Log.h> namespace android { namespace uirenderer { @@ -93,14 +94,16 @@ private: Caches& mCaches; }; -GpuPixelBuffer::GpuPixelBuffer(GLenum format, uint32_t width, uint32_t height) +GpuPixelBuffer::GpuPixelBuffer(GLenum format, + uint32_t width, uint32_t height) : PixelBuffer(format, width, height) , mMappedPointer(nullptr) - , mCaches(Caches::getInstance()) { + , mCaches(Caches::getInstance()){ glGenBuffers(1, &mBuffer); - mCaches.bindPixelBuffer(mBuffer); + + mCaches.pixelBuffer().bind(mBuffer); glBufferData(GL_PIXEL_UNPACK_BUFFER, getSize(), nullptr, GL_DYNAMIC_DRAW); - mCaches.unbindPixelBuffer(); + mCaches.pixelBuffer().unbind(); } GpuPixelBuffer::~GpuPixelBuffer() { @@ -109,7 +112,7 @@ GpuPixelBuffer::~GpuPixelBuffer() { uint8_t* GpuPixelBuffer::map(AccessMode mode) { if (mAccessMode == kAccessMode_None) { - mCaches.bindPixelBuffer(mBuffer); + mCaches.pixelBuffer().bind(mBuffer); mMappedPointer = (uint8_t*) glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, getSize(), mode); #if DEBUG_OPENGL if (!mMappedPointer) { @@ -128,7 +131,7 @@ uint8_t* GpuPixelBuffer::map(AccessMode mode) { void GpuPixelBuffer::unmap() { if (mAccessMode != kAccessMode_None) { if (mMappedPointer) { - mCaches.bindPixelBuffer(mBuffer); + mCaches.pixelBuffer().bind(mBuffer); GLboolean status = glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); if (status == GL_FALSE) { ALOGE("Corrupted GPU pixel buffer"); @@ -145,7 +148,7 @@ uint8_t* GpuPixelBuffer::getMappedPointer() const { void GpuPixelBuffer::upload(uint32_t x, uint32_t y, uint32_t width, uint32_t height, int offset) { // If the buffer is not mapped, unmap() will not bind it - mCaches.bindPixelBuffer(mBuffer); + mCaches.pixelBuffer().bind(mBuffer); unmap(); glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, mFormat, GL_UNSIGNED_BYTE, reinterpret_cast<void*>(offset)); @@ -155,7 +158,8 @@ void GpuPixelBuffer::upload(uint32_t x, uint32_t y, uint32_t width, uint32_t hei // Factory /////////////////////////////////////////////////////////////////////////////// -PixelBuffer* PixelBuffer::create(GLenum format, uint32_t width, uint32_t height, BufferType type) { +PixelBuffer* PixelBuffer::create(GLenum format, + uint32_t width, uint32_t height, BufferType type) { if (type == kBufferType_Auto && Caches::getInstance().gpuPixelBuffersEnabled) { return new GpuPixelBuffer(format, width, height); } diff --git a/libs/hwui/PixelBuffer.h b/libs/hwui/PixelBuffer.h index 04225a2..aac5ec4 100644 --- a/libs/hwui/PixelBuffer.h +++ b/libs/hwui/PixelBuffer.h @@ -18,6 +18,7 @@ #define ANDROID_HWUI_PIXEL_BUFFER_H #include <GLES3/gl3.h> +#include <cutils/log.h> namespace android { namespace uirenderer { diff --git a/libs/hwui/Vector.h b/libs/hwui/Vector.h index aa6acc9..7c3f2fd 100644 --- a/libs/hwui/Vector.h +++ b/libs/hwui/Vector.h @@ -17,6 +17,9 @@ #ifndef ANDROID_HWUI_VECTOR_H #define ANDROID_HWUI_VECTOR_H +#include <math.h> +#include <utils/Log.h> + namespace android { namespace uirenderer { diff --git a/libs/hwui/renderstate/MeshState.cpp b/libs/hwui/renderstate/MeshState.cpp new file mode 100644 index 0000000..7820a66 --- /dev/null +++ b/libs/hwui/renderstate/MeshState.cpp @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "renderstate/MeshState.h" + +#include "Program.h" + +#include "ShadowTessellator.h" + +namespace android { +namespace uirenderer { + +MeshState::MeshState() + : mCurrentPositionPointer(this) + , mCurrentPositionStride(0) + , mCurrentTexCoordsPointer(this) + , mCurrentTexCoordsStride(0) + , mTexCoordsArrayEnabled(false) { + + glGenBuffers(1, &meshBuffer); + glBindBuffer(GL_ARRAY_BUFFER, meshBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(kMeshVertices), kMeshVertices, GL_STATIC_DRAW); + + mCurrentBuffer = meshBuffer; + mCurrentIndicesBuffer = 0; + mCurrentPixelBuffer = 0; + + mQuadListIndices = 0; + mShadowStripsIndices = 0; +} + +MeshState::~MeshState() { + glDeleteBuffers(1, &meshBuffer); + mCurrentBuffer = 0; + + glDeleteBuffers(1, &mQuadListIndices); + mQuadListIndices = 0; + + glDeleteBuffers(1, &mShadowStripsIndices); + mShadowStripsIndices = 0; +} + +/////////////////////////////////////////////////////////////////////////////// +// Buffer Objects +/////////////////////////////////////////////////////////////////////////////// + +bool MeshState::bindMeshBuffer() { + return bindMeshBuffer(meshBuffer); +} + +bool MeshState::bindMeshBuffer(GLuint buffer) { + if (!buffer) buffer = meshBuffer; + if (mCurrentBuffer != buffer) { + glBindBuffer(GL_ARRAY_BUFFER, buffer); + mCurrentBuffer = buffer; + return true; + } + return false; +} + +bool MeshState::unbindMeshBuffer() { + if (mCurrentBuffer) { + glBindBuffer(GL_ARRAY_BUFFER, 0); + mCurrentBuffer = 0; + return true; + } + return false; +} + +/////////////////////////////////////////////////////////////////////////////// +// Vertices +/////////////////////////////////////////////////////////////////////////////// + +void MeshState::bindPositionVertexPointer(const Program* currentProgram, bool force, + const GLvoid* vertices, GLsizei stride) { + if (force || vertices != mCurrentPositionPointer || stride != mCurrentPositionStride) { + GLuint slot = currentProgram->position; + glVertexAttribPointer(slot, 2, GL_FLOAT, GL_FALSE, stride, vertices); + mCurrentPositionPointer = vertices; + mCurrentPositionStride = stride; + } +} + +void MeshState::bindTexCoordsVertexPointer(const Program* currentProgram, bool force, + const GLvoid* vertices, GLsizei stride) { + if (force || vertices != mCurrentTexCoordsPointer || stride != mCurrentTexCoordsStride) { + GLuint slot = currentProgram->texCoords; + glVertexAttribPointer(slot, 2, GL_FLOAT, GL_FALSE, stride, vertices); + mCurrentTexCoordsPointer = vertices; + mCurrentTexCoordsStride = stride; + } +} + +void MeshState::resetVertexPointers() { + mCurrentPositionPointer = this; + mCurrentTexCoordsPointer = this; +} + +void MeshState::resetTexCoordsVertexPointer() { + mCurrentTexCoordsPointer = this; +} + +void MeshState::enableTexCoordsVertexArray() { + if (!mTexCoordsArrayEnabled) { + glEnableVertexAttribArray(Program::kBindingTexCoords); + mCurrentTexCoordsPointer = this; + mTexCoordsArrayEnabled = true; + } +} + +void MeshState::disableTexCoordsVertexArray() { + if (mTexCoordsArrayEnabled) { + glDisableVertexAttribArray(Program::kBindingTexCoords); + mTexCoordsArrayEnabled = false; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Indices +/////////////////////////////////////////////////////////////////////////////// + +bool MeshState::bindIndicesBufferInternal(const GLuint buffer) { + if (mCurrentIndicesBuffer != buffer) { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer); + mCurrentIndicesBuffer = buffer; + return true; + } + return false; +} + +bool MeshState::bindQuadIndicesBuffer() { + if (!mQuadListIndices) { + std::unique_ptr<uint16_t[]> regionIndices(new uint16_t[kMaxNumberOfQuads * 6]); + for (uint32_t i = 0; i < kMaxNumberOfQuads; i++) { + uint16_t quad = i * 4; + int index = i * 6; + regionIndices[index ] = quad; // top-left + regionIndices[index + 1] = quad + 1; // top-right + regionIndices[index + 2] = quad + 2; // bottom-left + regionIndices[index + 3] = quad + 2; // bottom-left + regionIndices[index + 4] = quad + 1; // top-right + regionIndices[index + 5] = quad + 3; // bottom-right + } + + glGenBuffers(1, &mQuadListIndices); + bool force = bindIndicesBufferInternal(mQuadListIndices); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, kMaxNumberOfQuads * 6 * sizeof(uint16_t), + regionIndices.get(), GL_STATIC_DRAW); + return force; + } + + return bindIndicesBufferInternal(mQuadListIndices); +} + +bool MeshState::bindShadowIndicesBuffer() { + if (!mShadowStripsIndices) { + std::unique_ptr<uint16_t[]> shadowIndices(new uint16_t[MAX_SHADOW_INDEX_COUNT]); + ShadowTessellator::generateShadowIndices(shadowIndices.get()); + glGenBuffers(1, &mShadowStripsIndices); + bool force = bindIndicesBufferInternal(mShadowStripsIndices); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, MAX_SHADOW_INDEX_COUNT * sizeof(uint16_t), + shadowIndices.get(), GL_STATIC_DRAW); + return force; + } + + return bindIndicesBufferInternal(mShadowStripsIndices); +} + +bool MeshState::unbindIndicesBuffer() { + if (mCurrentIndicesBuffer) { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + mCurrentIndicesBuffer = 0; + return true; + } + return false; +} + +} /* namespace uirenderer */ +} /* namespace android */ + diff --git a/libs/hwui/renderstate/MeshState.h b/libs/hwui/renderstate/MeshState.h new file mode 100644 index 0000000..76f73d4 --- /dev/null +++ b/libs/hwui/renderstate/MeshState.h @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef RENDERSTATE_MESHSTATE_H +#define RENDERSTATE_MESHSTATE_H + +#include "Vertex.h" + +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> +#include <memory> + +namespace android { +namespace uirenderer { + +class Program; + +// Maximum number of quads that pre-allocated meshes can draw +const uint32_t kMaxNumberOfQuads = 2048; + +// This array is never used directly but used as a memcpy source in the +// OpenGLRenderer constructor +const TextureVertex kMeshVertices[] = { + { 0, 0, 0, 0 }, + { 1, 0, 1, 0 }, + { 0, 1, 0, 1 }, + { 1, 1, 1, 1 }, +}; + +const GLsizei kVertexStride = sizeof(Vertex); +const GLsizei kAlphaVertexStride = sizeof(AlphaVertex); +const GLsizei kTextureVertexStride = sizeof(TextureVertex); + +const GLsizei kMeshTextureOffset = 2 * sizeof(float); +const GLsizei kVertexAlphaOffset = 2 * sizeof(float); +const GLsizei kVertexAAWidthOffset = 2 * sizeof(float); +const GLsizei kVertexAALengthOffset = 3 * sizeof(float); +const GLsizei kMeshCount = 4; + +class MeshState { +private: + friend class RenderState; + +public: + ~MeshState(); + /////////////////////////////////////////////////////////////////////////////// + // Buffer objects + /////////////////////////////////////////////////////////////////////////////// + /** + * Binds the VBO used to render simple textured quads. + */ + bool bindMeshBuffer(); + + /** + * Binds the specified VBO if needed. If buffer == 0, binds default simple textured quad. + */ + bool bindMeshBuffer(GLuint buffer); + + /** + * Unbinds the VBO used to render simple textured quads. + */ + bool unbindMeshBuffer(); + + /////////////////////////////////////////////////////////////////////////////// + // Vertices + /////////////////////////////////////////////////////////////////////////////// + /** + * Binds an attrib to the specified float vertex pointer. + * Assumes a stride of gTextureVertexStride and a size of 2. + */ + void bindPositionVertexPointer(const Program* currentProgram, bool force, + const GLvoid* vertices, GLsizei stride = kTextureVertexStride); + + /** + * Binds an attrib to the specified float vertex pointer. + * Assumes a stride of gTextureVertexStride and a size of 2. + */ + void bindTexCoordsVertexPointer(const Program* currentProgram, bool force, + const GLvoid* vertices, GLsizei stride = kTextureVertexStride); + + /** + * Resets the vertex pointers. + */ + void resetVertexPointers(); + void resetTexCoordsVertexPointer(); + + void enableTexCoordsVertexArray(); + void disableTexCoordsVertexArray(); + + /////////////////////////////////////////////////////////////////////////////// + // Indices + /////////////////////////////////////////////////////////////////////////////// + /** + * Binds a global indices buffer that can draw up to + * gMaxNumberOfQuads quads. + */ + bool bindQuadIndicesBuffer(); + bool bindShadowIndicesBuffer(); + bool unbindIndicesBuffer(); + +private: + MeshState(); + bool bindIndicesBufferInternal(const GLuint buffer); + + // VBO to draw with + GLuint meshBuffer; + + GLuint mCurrentBuffer; + GLuint mCurrentIndicesBuffer; + GLuint mCurrentPixelBuffer; + + const void* mCurrentPositionPointer; + GLsizei mCurrentPositionStride; + const void* mCurrentTexCoordsPointer; + GLsizei mCurrentTexCoordsStride; + + bool mTexCoordsArrayEnabled; + + // Global index buffer + GLuint mQuadListIndices; + GLuint mShadowStripsIndices; +}; + +} /* namespace uirenderer */ +} /* namespace android */ + +#endif // RENDERSTATE_MESHSTATE_H diff --git a/libs/hwui/renderstate/PixelBufferState.cpp b/libs/hwui/renderstate/PixelBufferState.cpp new file mode 100644 index 0000000..c23af52 --- /dev/null +++ b/libs/hwui/renderstate/PixelBufferState.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "renderstate/PixelBufferState.h" + +namespace android { +namespace uirenderer { + +PixelBufferState::PixelBufferState() + : mCurrentPixelBuffer(0) { +} + +bool PixelBufferState::bind(GLuint buffer) { + if (mCurrentPixelBuffer != buffer) { + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer); + mCurrentPixelBuffer = buffer; + return true; + } + return false; +} + +bool PixelBufferState::unbind() { + if (mCurrentPixelBuffer) { + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + mCurrentPixelBuffer = 0; + return true; + } + return false; +} + +} /* namespace uirenderer */ +} /* namespace android */ + diff --git a/libs/hwui/renderstate/PixelBufferState.h b/libs/hwui/renderstate/PixelBufferState.h new file mode 100644 index 0000000..8dab21d --- /dev/null +++ b/libs/hwui/renderstate/PixelBufferState.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef RENDERSTATE_PIXELBUFFERSTATE_H +#define RENDERSTATE_PIXELBUFFERSTATE_H + +#include <GLES3/gl3.h> + +namespace android { +namespace uirenderer { + +class PixelBufferState { + friend class Caches; // TODO: move to RenderState +public: + bool bind(GLuint buffer); + bool unbind(); +private: + PixelBufferState(); + GLuint mCurrentPixelBuffer; +}; + +} /* namespace uirenderer */ +} /* namespace android */ + +#endif // RENDERSTATE_PIXELBUFFERSTATE_H diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp index 3a9a92e..4b190f0 100644 --- a/libs/hwui/renderstate/RenderState.cpp +++ b/libs/hwui/renderstate/RenderState.cpp @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "RenderState.h" +#include "renderstate/RenderState.h" #include "renderthread/CanvasContext.h" #include "renderthread/EglManager.h" @@ -24,6 +24,9 @@ namespace uirenderer { RenderState::RenderState(renderthread::RenderThread& thread) : mRenderThread(thread) , mCaches(nullptr) + , mMeshState(nullptr) + , mScissor(nullptr) + , mStencil(nullptr) , mViewportWidth(0) , mViewportHeight(0) , mFramebuffer(0) { @@ -31,17 +34,21 @@ RenderState::RenderState(renderthread::RenderThread& thread) } RenderState::~RenderState() { + LOG_ALWAYS_FATAL_IF(mMeshState || mScissor || mStencil, + "State object lifecycle not managed correctly"); } void RenderState::onGLContextCreated() { + LOG_ALWAYS_FATAL_IF(mMeshState || mScissor || mStencil, + "State object lifecycle not managed correctly"); + mMeshState = new MeshState(); + mScissor = new Scissor(); + mStencil = new Stencil(); + // This is delayed because the first access of Caches makes GL calls - mCaches = &Caches::getInstance(); + mCaches = &Caches::createInstance(*this); mCaches->init(); - mCaches->setRenderState(this); mCaches->textureCache.setAssetAtlas(&mAssetAtlas); - - LOG_ALWAYS_FATAL_IF(scissor().isEnabled(), "scissor used before GL context created"); - glDisable(GL_SCISSOR_TEST); } void RenderState::onGLContextDestroyed() { @@ -76,7 +83,15 @@ void RenderState::onGLContextDestroyed() { LOG_ALWAYS_FATAL("%d layers have survived gl context destruction", size); } */ + // TODO: reset all cached state in state objects mAssetAtlas.terminate(); + + delete mMeshState; + mMeshState = nullptr; + delete mScissor; + mScissor = nullptr; + delete mStencil; + mStencil = nullptr; } void RenderState::setViewport(GLsizei width, GLsizei height) { @@ -112,10 +127,10 @@ void RenderState::interruptForFunctorInvoke() { } } mCaches->resetActiveTexture(); - mCaches->unbindMeshBuffer(); - mCaches->unbindIndicesBuffer(); - mCaches->resetVertexPointers(); - mCaches->disableTexCoordsVertexArray(); + meshState().unbindMeshBuffer(); + meshState().unbindIndicesBuffer(); + meshState().resetVertexPointers(); + meshState().disableTexCoordsVertexArray(); debugOverdraw(false, false); } @@ -141,12 +156,12 @@ void RenderState::debugOverdraw(bool enable, bool clear) { if (mCaches->debugOverdraw && mFramebuffer == 0) { if (clear) { scissor().setEnabled(false); - mCaches->stencil.clear(); + stencil().clear(); } if (enable) { - mCaches->stencil.enableDebugWrite(); + stencil().enableDebugWrite(); } else { - mCaches->stencil.disable(); + stencil().disable(); } } } diff --git a/libs/hwui/renderstate/RenderState.h b/libs/hwui/renderstate/RenderState.h index b2d5cc5..501d76f 100644 --- a/libs/hwui/renderstate/RenderState.h +++ b/libs/hwui/renderstate/RenderState.h @@ -27,7 +27,10 @@ #include "AssetAtlas.h" #include "Caches.h" -#include "Scissor.h" +#include "renderstate/MeshState.h" +#include "renderstate/PixelBufferState.h" +#include "renderstate/Scissor.h" +#include "renderstate/Stencil.h" #include "utils/Macros.h" namespace android { @@ -81,8 +84,9 @@ public: void postDecStrong(VirtualLightRefBase* object); AssetAtlas& assetAtlas() { return mAssetAtlas; } - - Scissor& scissor() { return mScissor; } + MeshState& meshState() { return *mMeshState; } + Scissor& scissor() { return *mScissor; } + Stencil& stencil() { return *mStencil; } private: friend class renderthread::RenderThread; friend class Caches; @@ -94,10 +98,14 @@ private: RenderState(renderthread::RenderThread& thread); ~RenderState(); - Scissor mScissor; renderthread::RenderThread& mRenderThread; Caches* mCaches; + + MeshState* mMeshState; + Scissor* mScissor; + Stencil* mStencil; + AssetAtlas mAssetAtlas; std::set<const Layer*> mActiveLayers; std::set<renderthread::CanvasContext*> mRegisteredContexts; diff --git a/libs/hwui/renderstate/Scissor.cpp b/libs/hwui/renderstate/Scissor.cpp index ede57be..66c31a2 100644 --- a/libs/hwui/renderstate/Scissor.cpp +++ b/libs/hwui/renderstate/Scissor.cpp @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "Scissor.h" +#include "renderstate/Scissor.h" namespace android { namespace uirenderer { diff --git a/libs/hwui/renderstate/Scissor.h b/libs/hwui/renderstate/Scissor.h index eabf3a7..cc8b3dd 100644 --- a/libs/hwui/renderstate/Scissor.h +++ b/libs/hwui/renderstate/Scissor.h @@ -25,12 +25,12 @@ namespace uirenderer { class Scissor { friend class RenderState; public: - Scissor(); bool setEnabled(bool enabled); bool set(GLint x, GLint y, GLint width, GLint height); void reset(); bool isEnabled() { return mEnabled; } private: + Scissor(); void invalidate(); bool mEnabled; GLint mScissorX; diff --git a/libs/hwui/Stencil.cpp b/libs/hwui/renderstate/Stencil.cpp index f56a02e..acbed14 100644 --- a/libs/hwui/Stencil.cpp +++ b/libs/hwui/renderstate/Stencil.cpp @@ -17,7 +17,7 @@ #include "Debug.h" #include "Extensions.h" #include "Properties.h" -#include "Stencil.h" +#include "renderstate/Stencil.h" #include <GLES2/gl2ext.h> diff --git a/libs/hwui/Stencil.h b/libs/hwui/renderstate/Stencil.h index 20bb955..20bb955 100644 --- a/libs/hwui/Stencil.h +++ b/libs/hwui/renderstate/Stencil.h diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index 4d5d8c8..6346479 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -22,9 +22,9 @@ #include "../Caches.h" #include "../DeferredLayerUpdater.h" #include "../renderstate/RenderState.h" +#include "../renderstate/Stencil.h" #include "../LayerRenderer.h" #include "../OpenGLRenderer.h" -#include "../Stencil.h" #include <algorithm> #include <private/hwui/DrawGlInfo.h> |