summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/hwui/Android.common.mk4
-rw-r--r--libs/hwui/Caches.cpp196
-rw-r--r--libs/hwui/Caches.h172
-rw-r--r--libs/hwui/FontRenderer.cpp62
-rw-r--r--libs/hwui/FontRenderer.h59
-rw-r--r--libs/hwui/GradientCache.h2
-rw-r--r--libs/hwui/OpenGLRenderer.cpp133
-rw-r--r--libs/hwui/PatchCache.cpp23
-rw-r--r--libs/hwui/PatchCache.h5
-rw-r--r--libs/hwui/PathCache.cpp1
-rw-r--r--libs/hwui/PathCache.h15
-rw-r--r--libs/hwui/PixelBuffer.cpp26
-rw-r--r--libs/hwui/PixelBuffer.h1
-rw-r--r--libs/hwui/Vector.h3
-rw-r--r--libs/hwui/renderstate/MeshState.cpp192
-rw-r--r--libs/hwui/renderstate/MeshState.h139
-rw-r--r--libs/hwui/renderstate/PixelBufferState.cpp45
-rw-r--r--libs/hwui/renderstate/PixelBufferState.h37
-rw-r--r--libs/hwui/renderstate/RenderState.cpp41
-rw-r--r--libs/hwui/renderstate/RenderState.h16
-rw-r--r--libs/hwui/renderstate/Scissor.cpp2
-rw-r--r--libs/hwui/renderstate/Scissor.h2
-rw-r--r--libs/hwui/renderstate/Stencil.cpp (renamed from libs/hwui/Stencil.cpp)2
-rw-r--r--libs/hwui/renderstate/Stencil.h (renamed from libs/hwui/Stencil.h)0
-rw-r--r--libs/hwui/renderthread/CanvasContext.cpp2
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>