summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/hwui/Layer.cpp7
-rw-r--r--libs/hwui/Layer.h3
-rw-r--r--libs/hwui/OpenGLRenderer.cpp110
-rw-r--r--libs/hwui/OpenGLRenderer.h10
-rw-r--r--libs/hwui/ProgramCache.cpp1
-rw-r--r--libs/hwui/Properties.h15
-rw-r--r--libs/hwui/ResourceCache.cpp15
-rw-r--r--libs/hwui/ResourceCache.h2
-rw-r--r--libs/hwui/SkiaColorFilter.cpp19
9 files changed, 116 insertions, 66 deletions
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index 76b274b..fb525ee 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -50,6 +50,13 @@ Layer::~Layer() {
deleteTexture();
}
+void Layer::freeResourcesLocked() {
+ if (colorFilter) {
+ Caches::getInstance().resourceCache.decrementRefcountLocked(colorFilter);
+ colorFilter = NULL;
+ }
+}
+
void Layer::setPaint(SkPaint* paint) {
OpenGLRenderer::getAlphaAndModeDirect(paint, &alpha, &mode);
}
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index 420073a..d2cd440 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -45,10 +45,11 @@ class DisplayList;
* A layer has dimensions and is backed by an OpenGL texture or FBO.
*/
struct Layer {
-
Layer(const uint32_t layerWidth, const uint32_t layerHeight);
~Layer();
+ void freeResourcesLocked();
+
/**
* Sets this layer's region to a rectangle. Computes the appropriate
* texture coordinates.
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index a4403c8..d0d1d93 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -34,6 +34,7 @@
#include "OpenGLRenderer.h"
#include "DisplayListRenderer.h"
#include "PathRenderer.h"
+#include "Properties.h"
#include "Vector.h"
namespace android {
@@ -117,6 +118,8 @@ OpenGLRenderer::OpenGLRenderer(): mCaches(Caches::getInstance()) {
memcpy(mMeshVertices, gMeshVertices, sizeof(gMeshVertices));
mFirstSnapshot = new Snapshot;
+
+ mScissorOptimizationDisabled = false;
}
OpenGLRenderer::~OpenGLRenderer() {
@@ -124,16 +127,15 @@ OpenGLRenderer::~OpenGLRenderer() {
// GL APIs. All GL state should be kept in Caches.h
}
-///////////////////////////////////////////////////////////////////////////////
-// Debug
-///////////////////////////////////////////////////////////////////////////////
-
-void OpenGLRenderer::startMark(const char* name) const {
- mCaches.startMark(0, name);
-}
-
-void OpenGLRenderer::endMark() const {
- mCaches.endMark();
+void OpenGLRenderer::initProperties() {
+ char property[PROPERTY_VALUE_MAX];
+ if (property_get(PROPERTY_DISABLE_SCISSOR_OPTIMIZATION, property, "false")) {
+ mScissorOptimizationDisabled = !strcasecmp(property, "true");
+ INIT_LOGD(" Scissor optimization %s",
+ mScissorOptimizationDisabled ? "disabled" : "enabled");
+ } else {
+ INIT_LOGD(" Scissor optimization enabled");
+ }
}
///////////////////////////////////////////////////////////////////////////////
@@ -268,40 +270,6 @@ void OpenGLRenderer::finish() {
}
}
-void OpenGLRenderer::debugOverdraw(bool enable, bool clear) {
- if (mCaches.debugOverdraw && getTargetFbo() == 0) {
- if (clear) {
- mCaches.disableScissor();
- mCaches.stencil.clear();
- }
- if (enable) {
- mCaches.stencil.enableDebugWrite();
- } else {
- mCaches.stencil.disable();
- }
- }
-}
-
-void OpenGLRenderer::renderOverdraw() {
- if (mCaches.debugOverdraw && getTargetFbo() == 0) {
- const Rect* clip = mTilingSnapshot->clipRect;
-
- mCaches.enableScissor();
- mCaches.setScissor(clip->left, mTilingSnapshot->height - clip->bottom,
- clip->right - clip->left, clip->bottom - clip->top);
-
- mCaches.stencil.enableDebugTest(2);
- drawColor(0x2f0000ff, SkXfermode::kSrcOver_Mode);
- mCaches.stencil.enableDebugTest(3);
- drawColor(0x2f00ff00, SkXfermode::kSrcOver_Mode);
- mCaches.stencil.enableDebugTest(4);
- drawColor(0x3fff0000, SkXfermode::kSrcOver_Mode);
- mCaches.stencil.enableDebugTest(4, true);
- drawColor(0x7fff0000, SkXfermode::kSrcOver_Mode);
- mCaches.stencil.disable();
- }
-}
-
void OpenGLRenderer::interrupt() {
if (mCaches.currentProgram) {
if (mCaches.currentProgram->isInUse()) {
@@ -439,6 +407,52 @@ status_t OpenGLRenderer::callDrawGLFunction(Functor* functor, Rect& dirty) {
}
///////////////////////////////////////////////////////////////////////////////
+// Debug
+///////////////////////////////////////////////////////////////////////////////
+
+void OpenGLRenderer::startMark(const char* name) const {
+ mCaches.startMark(0, name);
+}
+
+void OpenGLRenderer::endMark() const {
+ mCaches.endMark();
+}
+
+void OpenGLRenderer::debugOverdraw(bool enable, bool clear) {
+ if (mCaches.debugOverdraw && getTargetFbo() == 0) {
+ if (clear) {
+ mCaches.disableScissor();
+ mCaches.stencil.clear();
+ }
+ if (enable) {
+ mCaches.stencil.enableDebugWrite();
+ } else {
+ mCaches.stencil.disable();
+ }
+ }
+}
+
+void OpenGLRenderer::renderOverdraw() {
+ if (mCaches.debugOverdraw && getTargetFbo() == 0) {
+ const Rect* clip = mTilingSnapshot->clipRect;
+
+ mCaches.enableScissor();
+ mCaches.setScissor(clip->left, mTilingSnapshot->height - clip->bottom,
+ clip->right - clip->left, clip->bottom - clip->top);
+
+ mCaches.stencil.enableDebugTest(2);
+ drawColor(0x2f0000ff, SkXfermode::kSrcOver_Mode);
+ mCaches.stencil.enableDebugTest(3);
+ drawColor(0x2f00ff00, SkXfermode::kSrcOver_Mode);
+ mCaches.stencil.enableDebugTest(4);
+ drawColor(0x3fff0000, SkXfermode::kSrcOver_Mode);
+ mCaches.stencil.enableDebugTest(4, true);
+ drawColor(0x7fff0000, SkXfermode::kSrcOver_Mode);
+ mCaches.stencil.disable();
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
// Layers
///////////////////////////////////////////////////////////////////////////////
@@ -1248,7 +1262,7 @@ bool OpenGLRenderer::quickReject(float left, float top, float right, float botto
bool rejected = !clipRect.intersects(r);
if (!isDeferred() && !rejected) {
- mCaches.setScissorEnabled(!clipRect.contains(r));
+ mCaches.setScissorEnabled(mScissorOptimizationDisabled || !clipRect.contains(r));
}
return rejected;
@@ -1384,8 +1398,8 @@ void OpenGLRenderer::setupDrawBlending(bool blend, SkXfermode::Mode mode, bool s
// When the blending mode is kClear_Mode, we need to use a modulate color
// argb=1,0,0,0
accountForClear(mode);
- chooseBlending(blend || (mColorSet && mColorA < 1.0f) || (mShader && mShader->blend()), mode,
- mDescription, swapSrcDst);
+ chooseBlending(blend || (mColorSet && mColorA < 1.0f) || (mShader && mShader->blend()) ||
+ (mColorFilter && mColorFilter->blend()), mode, mDescription, swapSrcDst);
}
void OpenGLRenderer::setupDrawProgram() {
@@ -2711,7 +2725,7 @@ status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* pain
debugLayerUpdate = mCaches.debugLayersUpdates;
}
- mCaches.setScissorEnabled(!clip.contains(transformed));
+ mCaches.setScissorEnabled(mScissorOptimizationDisabled || !clip.contains(transformed));
mCaches.activeTexture(0);
if (CC_LIKELY(!layer->region.isEmpty())) {
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 46e66cb..c29e3fb 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -64,6 +64,12 @@ public:
virtual ~OpenGLRenderer();
/**
+ * Read externally defined properties to control the behavior
+ * of the renderer.
+ */
+ ANDROID_API void initProperties();
+
+ /**
* Indicates whether this renderer executes drawing commands immediately.
* If this method returns true, the drawing commands will be executed
* later.
@@ -804,6 +810,10 @@ private:
// Indicate whether we are drawing an opaque frame
bool mOpaqueFrame;
+ // See PROPERTY_DISABLE_SCISSOR_OPTIMIZATION in
+ // Properties.h
+ bool mScissorOptimizationDisabled;
+
friend class DisplayListRenderer;
}; // class OpenGLRenderer
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index c81319e..7bc2b37 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -347,7 +347,6 @@ const char* gFS_Main_ApplyColorOp[4] = {
// None
"",
// Matrix
- // TODO: Fix premultiplied alpha computations for color matrix
" fragColor *= colorMatrix;\n"
" fragColor += colorMatrixVector;\n"
" fragColor.rgb *= fragColor.a;\n",
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index 31e60e4..1e8765b 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -67,6 +67,21 @@ enum DebugLevel {
*/
#define PROPERTY_DEBUG_OVERDRAW "debug.hwui.show_overdraw"
+/**
+ * Used to enable/disable scissor optimization. The accepted values are
+ * "true" and "false". The default value is "false".
+ *
+ * When scissor optimization is enabled, OpenGLRenderer will attempt to
+ * minimize the use of scissor by selectively enabling and disabling the
+ * GL scissor test.
+ * When the optimization is disabled, OpenGLRenderer will keep the GL
+ * scissor test enabled and change the scissor rect as needed.
+ * Some GPUs (for instance the SGX 540) perform better when changing
+ * the scissor rect often than when enabling/disabling the scissor test
+ * often.
+ */
+#define PROPERTY_DISABLE_SCISSOR_OPTIMIZATION "ro.hwui.disable_scissor_opt"
+
// These properties are defined in mega-bytes
#define PROPERTY_TEXTURE_CACHE_SIZE "ro.hwui.texture_cache_size"
#define PROPERTY_LAYER_CACHE_SIZE "ro.hwui.layer_cache_size"
diff --git a/libs/hwui/ResourceCache.cpp b/libs/hwui/ResourceCache.cpp
index 1c83ea4..18d8324 100644
--- a/libs/hwui/ResourceCache.cpp
+++ b/libs/hwui/ResourceCache.cpp
@@ -155,7 +155,7 @@ void ResourceCache::decrementRefcountLocked(void* resource) {
}
ref->refCount--;
if (ref->refCount == 0) {
- deleteResourceReference(resource, ref);
+ deleteResourceReferenceLocked(resource, ref);
}
}
@@ -201,7 +201,7 @@ void ResourceCache::destructorLocked(SkPath* resource) {
}
ref->destroyed = true;
if (ref->refCount == 0) {
- deleteResourceReference(resource, ref);
+ deleteResourceReferenceLocked(resource, ref);
}
}
@@ -223,7 +223,7 @@ void ResourceCache::destructorLocked(SkBitmap* resource) {
}
ref->destroyed = true;
if (ref->refCount == 0) {
- deleteResourceReference(resource, ref);
+ deleteResourceReferenceLocked(resource, ref);
}
}
@@ -242,7 +242,7 @@ void ResourceCache::destructorLocked(SkiaShader* resource) {
}
ref->destroyed = true;
if (ref->refCount == 0) {
- deleteResourceReference(resource, ref);
+ deleteResourceReferenceLocked(resource, ref);
}
}
@@ -261,7 +261,7 @@ void ResourceCache::destructorLocked(SkiaColorFilter* resource) {
}
ref->destroyed = true;
if (ref->refCount == 0) {
- deleteResourceReference(resource, ref);
+ deleteResourceReferenceLocked(resource, ref);
}
}
@@ -284,7 +284,7 @@ void ResourceCache::recycleLocked(SkBitmap* resource) {
}
ref->recycled = true;
if (ref->refCount == 0) {
- deleteResourceReference(resource, ref);
+ deleteResourceReferenceLocked(resource, ref);
}
}
@@ -292,7 +292,7 @@ void ResourceCache::recycleLocked(SkBitmap* resource) {
* This method should only be called while the mLock mutex is held (that mutex is grabbed
* by the various destructor() and recycle() methods which call this method).
*/
-void ResourceCache::deleteResourceReference(void* resource, ResourceReference* ref) {
+void ResourceCache::deleteResourceReferenceLocked(void* resource, ResourceReference* ref) {
if (ref->recycled && ref->resourceType == kBitmap) {
((SkBitmap*) resource)->setPixels(NULL, NULL);
}
@@ -326,6 +326,7 @@ void ResourceCache::deleteResourceReference(void* resource, ResourceReference* r
break;
case kLayer: {
Layer* layer = (Layer*) resource;
+ layer->freeResourcesLocked();
delete layer;
}
break;
diff --git a/libs/hwui/ResourceCache.h b/libs/hwui/ResourceCache.h
index 2053d96..a80670c 100644
--- a/libs/hwui/ResourceCache.h
+++ b/libs/hwui/ResourceCache.h
@@ -103,7 +103,7 @@ public:
void recycleLocked(SkBitmap* resource);
private:
- void deleteResourceReference(void* resource, ResourceReference* ref);
+ void deleteResourceReferenceLocked(void* resource, ResourceReference* ref);
void incrementRefcount(void* resource, ResourceType resourceType);
void incrementRefcountLocked(void* resource, ResourceType resourceType);
diff --git a/libs/hwui/SkiaColorFilter.cpp b/libs/hwui/SkiaColorFilter.cpp
index b86bbc5..f754388 100644
--- a/libs/hwui/SkiaColorFilter.cpp
+++ b/libs/hwui/SkiaColorFilter.cpp
@@ -34,13 +34,10 @@ SkiaColorFilter::~SkiaColorFilter() {
// Color matrix filter
///////////////////////////////////////////////////////////////////////////////
-SkiaColorMatrixFilter::SkiaColorMatrixFilter(SkColorFilter *skFilter, float* matrix, float* vector):
+SkiaColorMatrixFilter::SkiaColorMatrixFilter(SkColorFilter* skFilter, float* matrix, float* vector):
SkiaColorFilter(skFilter, kColorMatrix, true), mMatrix(matrix), mVector(vector) {
- // Skia uses the range [0..255] for the addition vector, but we need
- // the [0..1] range to apply the vector in GLSL
- for (int i = 0; i < 4; i++) {
- mVector[i] /= 255.0f;
- }
+ // TODO: We should be smarter about this
+ mBlend = true;
}
SkiaColorMatrixFilter::~SkiaColorMatrixFilter() {
@@ -62,7 +59,7 @@ void SkiaColorMatrixFilter::setupProgram(Program* program) {
// Lighting color filter
///////////////////////////////////////////////////////////////////////////////
-SkiaLightingFilter::SkiaLightingFilter(SkColorFilter *skFilter, int multiply, int add):
+SkiaLightingFilter::SkiaLightingFilter(SkColorFilter* skFilter, int multiply, int add):
SkiaColorFilter(skFilter, kLighting, true) {
mMulR = ((multiply >> 16) & 0xFF) / 255.0f;
mMulG = ((multiply >> 8) & 0xFF) / 255.0f;
@@ -71,6 +68,9 @@ SkiaLightingFilter::SkiaLightingFilter(SkColorFilter *skFilter, int multiply, in
mAddR = ((add >> 16) & 0xFF) / 255.0f;
mAddG = ((add >> 8) & 0xFF) / 255.0f;
mAddB = ((add ) & 0xFF) / 255.0f;
+
+ // A lighting filter always ignores alpha
+ mBlend = false;
}
void SkiaLightingFilter::describe(ProgramDescription& description, const Extensions& extensions) {
@@ -86,13 +86,16 @@ void SkiaLightingFilter::setupProgram(Program* program) {
// Blend color filter
///////////////////////////////////////////////////////////////////////////////
-SkiaBlendFilter::SkiaBlendFilter(SkColorFilter *skFilter, int color, SkXfermode::Mode mode):
+SkiaBlendFilter::SkiaBlendFilter(SkColorFilter* skFilter, int color, SkXfermode::Mode mode):
SkiaColorFilter(skFilter, kBlend, true), mMode(mode) {
const int alpha = (color >> 24) & 0xFF;
mA = alpha / 255.0f;
mR = mA * ((color >> 16) & 0xFF) / 255.0f;
mG = mA * ((color >> 8) & 0xFF) / 255.0f;
mB = mA * ((color ) & 0xFF) / 255.0f;
+
+ // TODO: We should do something smarter here
+ mBlend = true;
}
void SkiaBlendFilter::describe(ProgramDescription& description, const Extensions& extensions) {