Move more GL state management to RenderState and its directory

Change-Id: Ic68584e1c08dc64be2ad43450cb6caa1de834fdc
This commit is contained in:
Chris Craik
2015-01-27 15:46:35 -08:00
parent 06a8a121b0
commit 96a5c4c7ba
25 changed files with 685 additions and 499 deletions

View File

@@ -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 \

View File

@@ -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
// Textures
///////////////////////////////////////////////////////////////////////////////
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
///////////////////////////////////////////////////////////////////////////////
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();

View File

@@ -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,
@@ -94,16 +72,6 @@ static const GLenum gTextureUnits[] = {
GL_TEXTURE2
};
///////////////////////////////////////////////////////////////////////////////
// Debug
///////////////////////////////////////////////////////////////////////////////
struct CacheLogger {
CacheLogger() {
INIT_LOGD("Creating OpenGL renderer caches");
}
}; // struct CacheLogger
///////////////////////////////////////////////////////////////////////////////
// Caches
///////////////////////////////////////////////////////////////////////////////
@@ -111,12 +79,25 @@ struct CacheLogger {
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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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>

View File

@@ -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) {

View File

@@ -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

View File

@@ -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;

View File

@@ -31,7 +31,6 @@
#include "PathCache.h"
#include "thread/Signal.h"
#include "thread/Task.h"
#include "thread/TaskProcessor.h"
namespace android {

View File

@@ -17,21 +17,22 @@
#ifndef ANDROID_HWUI_PATH_CACHE_H
#define ANDROID_HWUI_PATH_CACHE_H
#include <GLES2/gl2.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>
#include "Debug.h"
#include "Texture.h"
#include "utils/Macros.h"
#include "utils/Pair.h"
class SkBitmap;
class SkCanvas;
class SkPaint;
class SkPath;
struct SkRect;
namespace android {

View File

@@ -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);
}

View File

@@ -18,6 +18,7 @@
#define ANDROID_HWUI_PIXEL_BUFFER_H
#include <GLES3/gl3.h>
#include <cutils/log.h>
namespace android {
namespace uirenderer {

View File

@@ -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 {

View File

@@ -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 */

View File

@@ -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

View File

@@ -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 */

View File

@@ -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

View File

@@ -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() {
// This is delayed because the first access of Caches makes GL calls
mCaches = &Caches::getInstance();
mCaches->init();
mCaches->setRenderState(this);
mCaches->textureCache.setAssetAtlas(&mAssetAtlas);
LOG_ALWAYS_FATAL_IF(mMeshState || mScissor || mStencil,
"State object lifecycle not managed correctly");
mMeshState = new MeshState();
mScissor = new Scissor();
mStencil = new Stencil();
LOG_ALWAYS_FATAL_IF(scissor().isEnabled(), "scissor used before GL context created");
glDisable(GL_SCISSOR_TEST);
// This is delayed because the first access of Caches makes GL calls
mCaches = &Caches::createInstance(*this);
mCaches->init();
mCaches->textureCache.setAssetAtlas(&mAssetAtlas);
}
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();
}
}
}

View File

@@ -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;

View File

@@ -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 {

View File

@@ -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;

View File

@@ -17,7 +17,7 @@
#include "Debug.h"
#include "Extensions.h"
#include "Properties.h"
#include "Stencil.h"
#include "renderstate/Stencil.h"
#include <GLES2/gl2ext.h>

View File

@@ -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>