Add debug mode to measure performance.
Change-Id: I9d4c84034dc200b99c8266165942a7cdbcb5c0c5
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index 3a85bc1..cd57ab2 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -30,6 +30,7 @@
#include <SkTemplates.h>
#include <SkXfermode.h>
+#include <OpenGLDebugRenderer.h>
#include <OpenGLRenderer.h>
#include <SkiaShader.h>
#include <SkiaColorFilter.h>
@@ -48,6 +49,8 @@
*/
#ifdef USE_OPENGL_RENDERER
+#define DEBUG_RENDERER 0
+
// ----------------------------------------------------------------------------
// Java APIs
// ----------------------------------------------------------------------------
@@ -62,7 +65,11 @@
// ----------------------------------------------------------------------------
static OpenGLRenderer* android_view_GLES20Canvas_createRenderer(JNIEnv* env, jobject canvas) {
+#if DEBUG_RENDERER
+ return new OpenGLDebugRenderer;
+#else
return new OpenGLRenderer;
+#endif
}
static void android_view_GLES20Canvas_destroyRenderer(JNIEnv* env, jobject canvas,
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 0469508..e8ffd99 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -5,11 +5,13 @@
# defined in the current device/board configuration
ifeq ($(USE_OPENGL_RENDERER),true)
LOCAL_SRC_FILES:= \
+ FboCache.cpp \
FontRenderer.cpp \
GammaFontRenderer.cpp \
GradientCache.cpp \
LayerCache.cpp \
Matrix.cpp \
+ OpenGLDebugRenderer.cpp \
OpenGLRenderer.cpp \
Patch.cpp \
PatchCache.cpp \
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index 5ef66f3..a4933c0 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -31,6 +31,7 @@
#include "ProgramCache.h"
#include "PathCache.h"
#include "TextDropShadowCache.h"
+#include "FboCache.h"
#include "Line.h"
namespace android {
@@ -65,6 +66,7 @@
PatchCache patchCache;
TextDropShadowCache dropShadowCache;
GammaFontRenderer fontRenderer;
+ FboCache fboCache;
Line line;
}; // class Caches
diff --git a/libs/hwui/FboCache.cpp b/libs/hwui/FboCache.cpp
new file mode 100644
index 0000000..77fbda2
--- /dev/null
+++ b/libs/hwui/FboCache.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#define LOG_TAG "OpenGLRenderer"
+
+#include "FboCache.h"
+#include "Properties.h"
+
+namespace android {
+namespace uirenderer {
+
+///////////////////////////////////////////////////////////////////////////////
+// Constructors/destructor
+///////////////////////////////////////////////////////////////////////////////
+
+FboCache::FboCache(): mMaxSize(DEFAULT_FBO_CACHE_SIZE) {
+ char property[PROPERTY_VALUE_MAX];
+ if (property_get(PROPERTY_FBO_CACHE_SIZE, property, NULL) > 0) {
+ LOGD(" Setting fbo cache size to %s", property);
+ mMaxSize = atoi(property);
+ } else {
+ LOGD(" Using default fbo cache size of %d", DEFAULT_FBO_CACHE_SIZE);
+ }
+}
+
+FboCache::~FboCache() {
+ clear();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Size management
+///////////////////////////////////////////////////////////////////////////////
+
+uint32_t FboCache::getSize() {
+ return mCache.size();
+}
+
+uint32_t FboCache::getMaxSize() {
+ return mMaxSize;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Caching
+///////////////////////////////////////////////////////////////////////////////
+
+void FboCache::clear() {
+
+}
+
+GLuint FboCache::get() {
+ return 0;
+}
+
+bool FboCache::put(GLuint fbo) {
+ return false;
+}
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/FboCache.h b/libs/hwui/FboCache.h
new file mode 100644
index 0000000..66f66ea
--- /dev/null
+++ b/libs/hwui/FboCache.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2010 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 ANDROID_UI_FBO_CACHE_H
+#define ANDROID_UI_FBO_CACHE_H
+
+#include <GLES2/gl2.h>
+
+#include <utils/SortedVector.h>
+
+#include "GenerationCache.h"
+
+namespace android {
+namespace uirenderer {
+
+///////////////////////////////////////////////////////////////////////////////
+// Cache
+///////////////////////////////////////////////////////////////////////////////
+
+class FboCache {
+public:
+ FboCache();
+ ~FboCache();
+
+ /**
+ * Returns an FBO from the cache. If no FBO is available, a new one
+ * is created. If creating a new FBO fails, 0 is returned.
+ *
+ * When an FBO is obtained from the cache, it is removed and the
+ * total number of FBOs available in the cache decreases.
+ *
+ * @return The name of the FBO, or 0 if no FBO can be obtained.
+ */
+ GLuint get();
+
+ /**
+ * Adds the specified FBO to the cache.
+ *
+ * @param fbo The FBO to add to the cache.
+ *
+ * @return True if the FBO was added, false otherwise.
+ */
+ bool put(GLuint fbo);
+
+ /**
+ * Clears the cache. This causes all FBOs to be deleted.
+ */
+ void clear();
+
+ /**
+ * Returns the current size of the cache.
+ */
+ uint32_t getSize();
+
+ /**
+ * Returns the maximum number of FBOs that the cache can hold.
+ */
+ uint32_t getMaxSize();
+
+private:
+ SortedVector<GLuint> mCache;
+ uint32_t mMaxSize;
+}; // class FboCache
+
+}; // namespace uirenderer
+}; // namespace android
+
+#endif // ANDROID_UI_FBO_CACHE_H
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index 2959814..b66696d 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -19,6 +19,7 @@
#include <SkUtils.h>
#include <cutils/properties.h>
+
#include <utils/Log.h>
#include "FontRenderer.h"
diff --git a/libs/hwui/OpenGLDebugRenderer.cpp b/libs/hwui/OpenGLDebugRenderer.cpp
new file mode 100644
index 0000000..f5a4286
--- /dev/null
+++ b/libs/hwui/OpenGLDebugRenderer.cpp
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#define LOG_TAG "OpenGLRenderer"
+
+#include <utils/StopWatch.h>
+
+#include "OpenGLDebugRenderer.h"
+
+namespace android {
+namespace uirenderer {
+
+void OpenGLDebugRenderer::prepare() {
+ mPrimitivesCount = 0;
+ LOGD("========= Frame start =========");
+ OpenGLRenderer::prepare();
+}
+
+void OpenGLDebugRenderer::finish() {
+ LOGD("========= Frame end =========");
+ LOGD("Primitives draw count = %d", mPrimitivesCount);
+ OpenGLRenderer::finish();
+}
+
+void OpenGLDebugRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) {
+ mPrimitivesCount++;
+ StopWatch w("composeLayer");
+ return OpenGLRenderer::composeLayer(current, previous);
+}
+
+int OpenGLDebugRenderer::saveLayer(float left, float top, float right, float bottom,
+ const SkPaint* p, int flags) {
+ mPrimitivesCount++;
+ StopWatch w("saveLayer");
+ return OpenGLRenderer::saveLayer(left, top, right, bottom, p, flags);
+}
+
+void OpenGLDebugRenderer::drawBitmap(SkBitmap* bitmap, float left, float top,
+ const SkPaint* paint) {
+ mPrimitivesCount++;
+ StopWatch w("drawBitmap");
+ OpenGLRenderer::drawBitmap(bitmap, left, top, paint);
+}
+
+void OpenGLDebugRenderer::drawBitmap(SkBitmap* bitmap, const SkMatrix* matrix,
+ const SkPaint* paint) {
+ mPrimitivesCount++;
+ StopWatch w("drawBitmapMatrix");
+ OpenGLRenderer::drawBitmap(bitmap, matrix, paint);
+}
+
+void OpenGLDebugRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
+ float srcRight, float srcBottom, float dstLeft, float dstTop,
+ float dstRight, float dstBottom, const SkPaint* paint) {
+ mPrimitivesCount++;
+ StopWatch w("drawBitmapRect");
+ OpenGLRenderer::drawBitmap(bitmap, srcLeft, srcTop, srcRight, srcBottom,
+ dstLeft, dstTop, dstRight, dstBottom, paint);
+}
+
+void OpenGLDebugRenderer::drawPatch(SkBitmap* bitmap, Res_png_9patch* patch,
+ float left, float top, float right, float bottom, const SkPaint* paint) {
+ mPrimitivesCount++;
+ StopWatch w("drawPatch");
+ OpenGLRenderer::drawPatch(bitmap, patch, left, top, right, bottom, paint);
+}
+
+void OpenGLDebugRenderer::drawColor(int color, SkXfermode::Mode mode) {
+ mPrimitivesCount++;
+ StopWatch w("drawColor");
+ OpenGLRenderer::drawColor(color, mode);
+}
+
+void OpenGLDebugRenderer::drawRect(float left, float top, float right, float bottom,
+ const SkPaint* paint) {
+ mPrimitivesCount++;
+ StopWatch w("drawRect");
+ OpenGLRenderer::drawRect(left, top, right, bottom, paint);
+}
+
+void OpenGLDebugRenderer::drawPath(SkPath* path, SkPaint* paint) {
+ mPrimitivesCount++;
+ StopWatch w("drawPath");
+ OpenGLRenderer::drawPath(path, paint);
+}
+
+void OpenGLDebugRenderer::drawLines(float* points, int count, const SkPaint* paint) {
+ mPrimitivesCount++;
+ StopWatch w("drawLines");
+ OpenGLRenderer::drawLines(points, count, paint);
+}
+
+void OpenGLDebugRenderer::drawText(const char* text, int bytesCount, int count, float x, float y,
+ SkPaint* paint) {
+ mPrimitivesCount++;
+ StopWatch w("drawText");
+ OpenGLRenderer::drawText(text, bytesCount, count, x, y, paint);
+}
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/OpenGLDebugRenderer.h b/libs/hwui/OpenGLDebugRenderer.h
new file mode 100644
index 0000000..37fac93
--- /dev/null
+++ b/libs/hwui/OpenGLDebugRenderer.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2010 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 ANDROID_UI_OPENGL_DEBUG_RENDERER_H
+#define ANDROID_UI_OPENGL_DEBUG_RENDERER_H
+
+#include "OpenGLRenderer.h"
+
+namespace android {
+namespace uirenderer {
+
+///////////////////////////////////////////////////////////////////////////////
+// Renderer
+///////////////////////////////////////////////////////////////////////////////
+
+class OpenGLDebugRenderer: public OpenGLRenderer {
+public:
+ OpenGLDebugRenderer(): mPrimitivesCount(0) {
+ }
+
+ ~OpenGLDebugRenderer() {
+ }
+
+ void prepare();
+ void finish();
+
+ int saveLayer(float left, float top, float right, float bottom,
+ const SkPaint* p, int flags);
+
+ void drawBitmap(SkBitmap* bitmap, float left, float top, const SkPaint* paint);
+ void drawBitmap(SkBitmap* bitmap, const SkMatrix* matrix, const SkPaint* paint);
+ void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
+ float srcRight, float srcBottom, float dstLeft, float dstTop,
+ float dstRight, float dstBottom, const SkPaint* paint);
+ void drawPatch(SkBitmap* bitmap, Res_png_9patch* patch, float left, float top,
+ float right, float bottom, const SkPaint* paint);
+ void drawColor(int color, SkXfermode::Mode mode);
+ void drawRect(float left, float top, float right, float bottom, const SkPaint* paint);
+ void drawPath(SkPath* path, SkPaint* paint);
+ void drawLines(float* points, int count, const SkPaint* paint);
+ void drawText(const char* text, int bytesCount, int count, float x, float y,
+ SkPaint* paint);
+
+protected:
+ void composeLayer(sp<Snapshot> current, sp<Snapshot> previous);
+
+private:
+ uint32_t mPrimitivesCount;
+
+}; // class OpenGLDebugRenderer
+
+}; // namespace uirenderer
+}; // namespace android
+
+#endif // ANDROID_UI_OPENGL_DEBUG_RENDERER_H
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index e032085..dbd499e 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -24,6 +24,7 @@
#include <SkTypeface.h>
#include <utils/Log.h>
+#include <utils/StopWatch.h>
#include "OpenGLRenderer.h"
@@ -710,6 +711,7 @@
if (text == NULL || count == 0 || (paint->getAlpha() == 0 && paint->getXfermode() == NULL)) {
return;
}
+
paint->setAntiAlias(true);
float length = -1.0f;
@@ -739,6 +741,7 @@
FontRenderer& fontRenderer = mCaches.fontRenderer.getFontRenderer(paint);
fontRenderer.setFont(paint, SkTypeface::UniqueID(paint->getTypeface()),
paint->getTextSize());
+
if (mHasShadow) {
glActiveTexture(gTextureUnits[0]);
mCaches.dropShadowCache.setFontRenderer(fontRenderer);
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index f903505..af2a70b 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -62,11 +62,13 @@
class OpenGLRenderer {
public:
OpenGLRenderer();
- ~OpenGLRenderer();
+ virtual ~OpenGLRenderer();
void setViewport(int width, int height);
- void prepare();
- void finish();
+
+ virtual void prepare();
+ virtual void finish();
+
void acquireContext();
void releaseContext();
@@ -75,8 +77,10 @@
void restore();
void restoreToCount(int saveCount);
- int saveLayer(float left, float top, float right, float bottom, const SkPaint* p, int flags);
- int saveLayerAlpha(float left, float top, float right, float bottom, int alpha, int flags);
+ virtual int saveLayer(float left, float top, float right, float bottom,
+ const SkPaint* p, int flags);
+ virtual int saveLayerAlpha(float left, float top, float right, float bottom,
+ int alpha, int flags);
void translate(float dx, float dy);
void rotate(float degrees);
@@ -90,16 +94,19 @@
bool quickReject(float left, float top, float right, float bottom);
bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
- void drawBitmap(SkBitmap* bitmap, float left, float top, const SkPaint* paint);
- void drawBitmap(SkBitmap* bitmap, const SkMatrix* matrix, const SkPaint* paint);
- void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop, float srcRight, float srcBottom,
- float dstLeft, float dstTop, float dstRight, float dstBottom, const SkPaint* paint);
- void drawPatch(SkBitmap* bitmap, Res_png_9patch* patch, float left, float top,
+ virtual void drawBitmap(SkBitmap* bitmap, float left, float top, const SkPaint* paint);
+ virtual void drawBitmap(SkBitmap* bitmap, const SkMatrix* matrix, const SkPaint* paint);
+ virtual void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
+ float srcRight, float srcBottom, float dstLeft, float dstTop,
+ float dstRight, float dstBottom, const SkPaint* paint);
+ virtual void drawPatch(SkBitmap* bitmap, Res_png_9patch* patch, float left, float top,
float right, float bottom, const SkPaint* paint);
- void drawColor(int color, SkXfermode::Mode mode);
- void drawRect(float left, float top, float right, float bottom, const SkPaint* paint);
- void drawPath(SkPath* path, SkPaint* paint);
- void drawLines(float* points, int count, const SkPaint* paint);
+ virtual void drawColor(int color, SkXfermode::Mode mode);
+ virtual void drawRect(float left, float top, float right, float bottom, const SkPaint* paint);
+ virtual void drawPath(SkPath* path, SkPaint* paint);
+ virtual void drawLines(float* points, int count, const SkPaint* paint);
+ virtual void drawText(const char* text, int bytesCount, int count, float x, float y,
+ SkPaint* paint);
void resetShader();
void setupShader(SkiaShader* shader);
@@ -110,7 +117,17 @@
void resetShadow();
void setupShadow(float radius, float dx, float dy, int color);
- void drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint);
+protected:
+ /**
+ * Compose the layer defined in the current snapshot with the layer
+ * defined by the previous snapshot.
+ *
+ * The current snapshot *must* be a layer (flag kFlagIsLayer set.)
+ *
+ * @param curent The current snapshot containing the layer to compose
+ * @param previous The previous snapshot to compose the current layer with
+ */
+ virtual void composeLayer(sp<Snapshot> current, sp<Snapshot> previous);
private:
/**
@@ -138,17 +155,6 @@
void setScissorFromClip();
/**
- * Compose the layer defined in the current snapshot with the layer
- * defined by the previous snapshot.
- *
- * The current snapshot *must* be a layer (flag kFlagIsLayer set.)
- *
- * @param curent The current snapshot containing the layer to compose
- * @param previous The previous snapshot to compose the current layer with
- */
- void composeLayer(sp<Snapshot> current, sp<Snapshot> previous);
-
- /**
* Creates a new layer stored in the specified snapshot.
*
* @param snapshot The snapshot associated with the new layer
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index 4e2f091..d573805 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -30,6 +30,7 @@
#define PROPERTY_GRADIENT_CACHE_SIZE "ro.hwui.gradient_cache_size"
#define PROPERTY_PATH_CACHE_SIZE "ro.hwui.path_cache_size"
#define PROPERTY_DROP_SHADOW_CACHE_SIZE "ro.hwui.drop_shadow_cache_size"
+#define PROPERTY_FBO_CACHE_SIZE "ro.hwui.fbo_cache_size"
// These properties are defined in pixels
#define PROPERTY_TEXT_CACHE_WIDTH "ro.hwui.text_cache_width"
@@ -43,12 +44,13 @@
// Converts a number of mega-bytes into bytes
#define MB(s) s * 1024 * 1024
-#define DEFAULT_TEXTURE_CACHE_SIZE 20.0f
-#define DEFAULT_LAYER_CACHE_SIZE 6.0f
-#define DEFAULT_PATH_CACHE_SIZE 6.0f
+#define DEFAULT_TEXTURE_CACHE_SIZE 18.0f
+#define DEFAULT_LAYER_CACHE_SIZE 4.0f
+#define DEFAULT_PATH_CACHE_SIZE 5.0f
#define DEFAULT_PATCH_CACHE_SIZE 100
#define DEFAULT_GRADIENT_CACHE_SIZE 0.5f
#define DEFAULT_DROP_SHADOW_CACHE_SIZE 2.0f
+#define DEFAULT_FBO_CACHE_SIZE 25
#define DEFAULT_TEXT_GAMMA 1.4f
#define DEFAULT_TEXT_BLACK_GAMMA_THRESHOLD 64