am 8b946c05: Merge "Defer layer rendering to avoid stalls Bug #7326824" into jb-mr1-dev

* commit '8b946c055ddd90cf79cd407c9f68a013d5d24c2a':
  Defer layer rendering to avoid stalls Bug #7326824
This commit is contained in:
Romain Guy
2012-10-19 10:43:04 -07:00
committed by Android Git Automerger
9 changed files with 64 additions and 14 deletions

View File

@ -1200,7 +1200,12 @@ public abstract class HardwareRenderer {
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
status = onPreDraw(dirty);
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "prepareFrame");
try {
status = onPreDraw(dirty);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
saveCount = canvas.save();
callbacks.onHardwarePreDraw(canvas);

View File

@ -1434,7 +1434,7 @@ void DisplayListRenderer::setViewport(int width, int height) {
mHeight = height;
}
int DisplayListRenderer::prepareDirty(float left, float top,
status_t DisplayListRenderer::prepareDirty(float left, float top,
float right, float bottom, bool opaque) {
mSnapshot = new Snapshot(mFirstSnapshot,
SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);

View File

@ -550,7 +550,7 @@ public:
virtual bool isDeferred();
virtual void setViewport(int width, int height);
virtual int prepareDirty(float left, float top, float right, float bottom, bool opaque);
virtual status_t prepareDirty(float left, float top, float right, float bottom, bool opaque);
virtual void finish();
virtual status_t callDrawGLFunction(Functor *functor, Rect& dirty);

View File

@ -31,6 +31,7 @@ Layer::Layer(const uint32_t layerWidth, const uint32_t layerHeight) {
meshIndices = NULL;
meshElementCount = 0;
cacheable = true;
dirty = false;
textureLayer = false;
renderTarget = GL_TEXTURE_2D;
texture.width = layerWidth;

View File

@ -162,6 +162,14 @@ struct Layer {
this->cacheable = cacheable;
}
inline bool isDirty() {
return dirty;
}
inline void setDirty(bool dirty) {
this->dirty = dirty;
}
inline bool isTextureLayer() {
return textureLayer;
}
@ -286,6 +294,12 @@ private:
*/
bool textureLayer;
/**
* When set to true, this layer is dirty and should be cleared
* before any rendering occurs.
*/
bool dirty;
/**
* Indicates the render target.
*/

View File

@ -18,6 +18,8 @@
#include <ui/Rect.h>
#include <private/hwui/DrawGlInfo.h>
#include "LayerCache.h"
#include "LayerRenderer.h"
#include "Matrix.h"
@ -41,7 +43,8 @@ void LayerRenderer::setViewport(int width, int height) {
initViewport(width, height);
}
int LayerRenderer::prepareDirty(float left, float top, float right, float bottom, bool opaque) {
status_t LayerRenderer::prepareDirty(float left, float top, float right, float bottom,
bool opaque) {
LAYER_RENDERER_LOGD("Rendering into layer, fbo = %d", mLayer->getFbo());
glBindFramebuffer(GL_FRAMEBUFFER, mLayer->getFbo());
@ -63,6 +66,20 @@ int LayerRenderer::prepareDirty(float left, float top, float right, float bottom
return OpenGLRenderer::prepareDirty(dirty.left, dirty.top, dirty.right, dirty.bottom, opaque);
}
status_t LayerRenderer::clear(float left, float top, float right, float bottom, bool opaque) {
if (mLayer->isDirty()) {
getCaches().disableScissor();
glClear(GL_COLOR_BUFFER_BIT);
getCaches().resetScissor();
mLayer->setDirty(false);
return DrawGlInfo::kStatusDone;
}
return OpenGLRenderer::clear(left, top, right, bottom, opaque);
}
void LayerRenderer::finish() {
OpenGLRenderer::finish();
@ -201,6 +218,7 @@ Layer* LayerRenderer::createLayer(uint32_t width, uint32_t height, bool isOpaque
layer->setAlpha(255, SkXfermode::kSrcOver_Mode);
layer->setBlend(!isOpaque);
layer->setColorFilter(NULL);
layer->setDirty(true);
layer->region.clear();
GLuint previousFbo;
@ -229,9 +247,6 @@ Layer* LayerRenderer::createLayer(uint32_t width, uint32_t height, bool isOpaque
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
layer->getTexture(), 0);
caches.disableScissor();
glClear(GL_COLOR_BUFFER_BIT);
glBindFramebuffer(GL_FRAMEBUFFER, previousFbo);
return layer;

View File

@ -48,7 +48,8 @@ public:
virtual ~LayerRenderer();
virtual void setViewport(int width, int height);
virtual int prepareDirty(float left, float top, float right, float bottom, bool opaque);
virtual status_t prepareDirty(float left, float top, float right, float bottom, bool opaque);
virtual status_t clear(float left, float top, float right, float bottom, bool opaque);
virtual void finish();
ANDROID_API static Layer* createTextureLayer(bool isOpaque);

View File

@ -165,11 +165,12 @@ void OpenGLRenderer::initViewport(int width, int height) {
mFirstSnapshot->viewport.set(0, 0, width, height);
}
int OpenGLRenderer::prepare(bool opaque) {
status_t OpenGLRenderer::prepare(bool opaque) {
return prepareDirty(0.0f, 0.0f, mWidth, mHeight, opaque);
}
int OpenGLRenderer::prepareDirty(float left, float top, float right, float bottom, bool opaque) {
status_t OpenGLRenderer::prepareDirty(float left, float top, float right, float bottom,
bool opaque) {
mCaches.clearGarbage();
mSnapshot = new Snapshot(mFirstSnapshot,
@ -203,15 +204,18 @@ int OpenGLRenderer::prepareDirty(float left, float top, float right, float botto
debugOverdraw(true, true);
return clear(left, top, right, bottom, opaque);
}
status_t OpenGLRenderer::clear(float left, float top, float right, float bottom, bool opaque) {
if (!opaque) {
mCaches.enableScissor();
mCaches.setScissor(left, mSnapshot->height - bottom, right - left, bottom - top);
glClear(GL_COLOR_BUFFER_BIT);
return DrawGlInfo::kStatusDrew;
} else {
mCaches.resetScissor();
}
mCaches.resetScissor();
return DrawGlInfo::kStatusDone;
}
@ -743,6 +747,7 @@ bool OpenGLRenderer::createLayer(float left, float top, float right, float botto
bounds.getWidth() / float(layer->getWidth()), 0.0f);
layer->setColorFilter(mColorFilter);
layer->setBlend(true);
layer->setDirty(false);
// Save the layer in the snapshot
mSnapshot->flags |= Snapshot::kFlagIsLayer;

View File

@ -94,7 +94,7 @@ public:
* and will not be cleared. If false, the target surface
* will be cleared
*/
ANDROID_API int prepare(bool opaque);
ANDROID_API status_t prepare(bool opaque);
/**
* Prepares the renderer to draw a frame. This method must be invoked
@ -110,7 +110,7 @@ public:
* and will not be cleared. If false, the target surface
* will be cleared in the specified dirty rectangle
*/
virtual int prepareDirty(float left, float top, float right, float bottom, bool opaque);
virtual status_t prepareDirty(float left, float top, float right, float bottom, bool opaque);
/**
* Indicates the end of a frame. This method must be invoked whenever
@ -269,6 +269,11 @@ protected:
*/
void initViewport(int width, int height);
/**
* Clears the underlying surface if needed.
*/
virtual status_t clear(float left, float top, float right, float bottom, bool opaque);
/**
* Call this method after updating a layer during a drawing pass.
*/
@ -355,6 +360,10 @@ protected:
return false;
}
Caches& getCaches() {
return mCaches;
}
private:
/**
* Ensures the state of the renderer is the same as the state of