Support nested display lists.

Change-Id: I3815a2832fc0f722c668ba8f51c5f177edb77c94
This commit is contained in:
Romain Guy
2010-11-08 12:08:41 -08:00
parent cce1d2a60b
commit 0fe478ea04
7 changed files with 49 additions and 8 deletions

View File

@@ -421,7 +421,7 @@ static void android_view_GLES20Canvas_destroyDisplayList(JNIEnv* env,
static void android_view_GLES20Canvas_drawDisplayList(JNIEnv* env,
jobject canvas, OpenGLRenderer* renderer, DisplayList* displayList) {
displayList->replay(*renderer);
renderer->drawDisplayList(displayList);
}
#endif // USE_OPENGL_RENDERER

View File

@@ -226,6 +226,10 @@ void DisplayList::replay(OpenGLRenderer& renderer) {
(SkRegion::Op) getInt());
}
break;
case DrawDisplayList: {
renderer.drawDisplayList(getDisplayList());
}
break;
case DrawBitmap: {
renderer.drawBitmap(getBitmap(), getFloat(), getFloat(), getPaint());
}
@@ -453,6 +457,11 @@ bool DisplayListRenderer::clipRect(float left, float top, float right, float bot
return OpenGLRenderer::clipRect(left, top, right, bottom, op);
}
void DisplayListRenderer::drawDisplayList(DisplayList* displayList) {
addOp(DisplayList::DrawDisplayList);
addDisplayList(displayList);
}
void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top,
SkPaint* paint) {
addOp(DisplayList::DrawBitmap);

View File

@@ -92,6 +92,7 @@ public:
SetMatrix,
ConcatMatrix,
ClipRect,
DrawDisplayList,
DrawBitmap,
DrawBitmapMatrix,
DrawBitmapRect,
@@ -160,6 +161,10 @@ private:
return (SkPaint*) getInt();
}
DisplayList* getDisplayList() {
return (DisplayList*) getInt();
}
inline float getFloat() {
return mReader.readScalar();
}
@@ -235,6 +240,7 @@ public:
bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
void drawDisplayList(DisplayList* displayList);
void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
@@ -348,16 +354,25 @@ private:
inline void addPaint(SkPaint* paint) {
if (paint == NULL) {
addInt((int)NULL);
addInt((int) NULL);
return;
}
SkPaint *paintCopy = mPaintMap.valueFor(paint);
if (paintCopy == NULL || paintCopy->getGenerationID() != paint->getGenerationID()) {
paintCopy = new SkPaint(*paint);
mPaintMap.add(paint, paintCopy);
mPaints.add(paintCopy);
}
addInt((int)paintCopy);
addInt((int) paintCopy);
}
inline void addDisplayList(DisplayList* displayList) {
// TODO: To be safe, the display list should be ref-counted in the
// resources cache, but we rely on the caller (UI toolkit) to
// do the right thing for now
addInt((int) displayList);
}
inline void addMatrix(SkMatrix* matrix) {
@@ -371,21 +386,21 @@ private:
// correctly, such as creating the bitmap from scratch, drawing with it, changing its
// contents, and drawing again. The only fix would be to always copy it the first time,
// which doesn't seem worth the extra cycles for this unlikely case.
addInt((int)bitmap);
addInt((int) bitmap);
mBitmapResources.add(bitmap);
Caches& caches = Caches::getInstance();
caches.resourceCache.incrementRefcount(bitmap);
}
inline void addShader(SkiaShader* shader) {
addInt((int)shader);
addInt((int) shader);
mShaderResources.add(shader);
Caches& caches = Caches::getInstance();
caches.resourceCache.incrementRefcount(shader);
}
inline void addColorFilter(SkiaColorFilter* colorFilter) {
addInt((int)colorFilter);
addInt((int) colorFilter);
mFilterResources.add(colorFilter);
Caches& caches = Caches::getInstance();
caches.resourceCache.incrementRefcount(colorFilter);
@@ -398,7 +413,7 @@ private:
Vector<SkiaColorFilter*> mFilterResources;
Vector<SkPaint*> mPaints;
DefaultKeyedVector<SkPaint *, SkPaint *> mPaintMap;
DefaultKeyedVector<SkPaint*, SkPaint*> mPaintMap;
Vector<SkMatrix*> mMatrices;
PathHeap* mPathHeap;

View File

@@ -48,6 +48,12 @@ int OpenGLDebugRenderer::saveLayer(float left, float top, float right, float bot
return OpenGLRenderer::saveLayer(left, top, right, bottom, p, flags);
}
void OpenGLDebugRenderer::drawDisplayList(DisplayList* displayList) {
mPrimitivesCount++;
StopWatch w("drawDisplayList");
OpenGLRenderer::drawDisplayList(displayList);
}
void OpenGLDebugRenderer::drawBitmap(SkBitmap* bitmap, float left, float top,
SkPaint* paint) {
mPrimitivesCount++;

View File

@@ -40,6 +40,7 @@ public:
int saveLayer(float left, float top, float right, float bottom,
SkPaint* p, int flags);
void drawDisplayList(DisplayList* displayList);
void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,

View File

@@ -29,6 +29,7 @@
#include <ui/Rect.h>
#include "OpenGLRenderer.h"
#include "DisplayListRenderer.h"
namespace android {
namespace uirenderer {
@@ -827,6 +828,14 @@ bool OpenGLRenderer::clipRect(float left, float top, float right, float bottom,
// Drawing
///////////////////////////////////////////////////////////////////////////////
void OpenGLRenderer::drawDisplayList(DisplayList* displayList) {
// All the usual checks and setup operations (quickReject, setupDraw, etc.)
// will be performed by the display list itself
if (displayList) {
displayList->replay(*this);
}
}
void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) {
const float right = left + bitmap->width();
const float bottom = top + bitmap->height();

View File

@@ -58,7 +58,7 @@ namespace uirenderer {
// Renderer
///////////////////////////////////////////////////////////////////////////////
class DisplayListRenderer;
class DisplayList;
/**
* OpenGL renderer used to draw accelerated 2D graphics. The API is a
@@ -100,6 +100,7 @@ public:
bool quickReject(float left, float top, float right, float bottom);
virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
virtual void drawDisplayList(DisplayList* displayList);
virtual void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
virtual void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
virtual void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,