* commit '8b946c055ddd90cf79cd407c9f68a013d5d24c2a': Defer layer rendering to avoid stalls Bug #7326824
This commit is contained in:
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user