Merge "Minimize state changes when updating layers" into jb-mr1-dev
This commit is contained in:
@@ -378,6 +378,9 @@ bool Caches::setScissor(GLint x, GLint y, GLint width, GLint height) {
|
||||
if (scissorEnabled && (x != mScissorX || y != mScissorY ||
|
||||
width != mScissorWidth || height != mScissorHeight)) {
|
||||
|
||||
if (x < 0) x = 0;
|
||||
if (y < 0) y = 0;
|
||||
|
||||
glScissor(x, y, width, height);
|
||||
|
||||
mScissorX = x;
|
||||
|
||||
@@ -37,6 +37,10 @@ LayerRenderer::LayerRenderer(Layer* layer): mLayer(layer) {
|
||||
LayerRenderer::~LayerRenderer() {
|
||||
}
|
||||
|
||||
void LayerRenderer::setViewport(int width, int height) {
|
||||
initViewport(width, height);
|
||||
}
|
||||
|
||||
int LayerRenderer::prepareDirty(float left, float top, float right, float bottom, bool opaque) {
|
||||
LAYER_RENDERER_LOGD("Rendering into layer, fbo = %d", mLayer->getFbo());
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ public:
|
||||
ANDROID_API LayerRenderer(Layer* layer);
|
||||
virtual ~LayerRenderer();
|
||||
|
||||
virtual void setViewport(int width, int height);
|
||||
virtual int prepareDirty(float left, float top, float right, float bottom, bool opaque);
|
||||
virtual void finish();
|
||||
|
||||
|
||||
@@ -144,6 +144,15 @@ bool OpenGLRenderer::isDeferred() {
|
||||
}
|
||||
|
||||
void OpenGLRenderer::setViewport(int width, int height) {
|
||||
initViewport(width, height);
|
||||
|
||||
glDisable(GL_DITHER);
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
glEnableVertexAttribArray(Program::kBindingPosition);
|
||||
}
|
||||
|
||||
void OpenGLRenderer::initViewport(int width, int height) {
|
||||
mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1);
|
||||
|
||||
mWidth = width;
|
||||
@@ -151,11 +160,6 @@ void OpenGLRenderer::setViewport(int width, int height) {
|
||||
|
||||
mFirstSnapshot->height = height;
|
||||
mFirstSnapshot->viewport.set(0, 0, width, height);
|
||||
|
||||
glDisable(GL_DITHER);
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
glEnableVertexAttribArray(Program::kBindingPosition);
|
||||
}
|
||||
|
||||
int OpenGLRenderer::prepare(bool opaque) {
|
||||
@@ -251,8 +255,9 @@ void OpenGLRenderer::interrupt() {
|
||||
|
||||
void OpenGLRenderer::resume() {
|
||||
sp<Snapshot> snapshot = (mSnapshot != NULL) ? mSnapshot : mFirstSnapshot;
|
||||
|
||||
glViewport(0, 0, snapshot->viewport.getWidth(), snapshot->viewport.getHeight());
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, snapshot->fbo);
|
||||
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
mCaches.scissorEnabled = glIsEnabled(GL_SCISSOR_TEST);
|
||||
@@ -261,7 +266,6 @@ void OpenGLRenderer::resume() {
|
||||
dirtyClip();
|
||||
|
||||
mCaches.activeTexture(0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, snapshot->fbo);
|
||||
|
||||
mCaches.blend = true;
|
||||
glEnable(GL_BLEND);
|
||||
@@ -269,6 +273,15 @@ void OpenGLRenderer::resume() {
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
}
|
||||
|
||||
void OpenGLRenderer::resumeAfterLayer() {
|
||||
sp<Snapshot> snapshot = (mSnapshot != NULL) ? mSnapshot : mFirstSnapshot;
|
||||
glViewport(0, 0, snapshot->viewport.getWidth(), snapshot->viewport.getHeight());
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, snapshot->fbo);
|
||||
|
||||
mCaches.resetScissor();
|
||||
dirtyClip();
|
||||
}
|
||||
|
||||
void OpenGLRenderer::detachFunctor(Functor* functor) {
|
||||
mFunctors.remove(functor);
|
||||
}
|
||||
@@ -1081,6 +1094,22 @@ bool OpenGLRenderer::quickRejectNoScissor(float left, float top, float right, fl
|
||||
return !clipRect.intersects(r);
|
||||
}
|
||||
|
||||
bool OpenGLRenderer::quickRejectNoScissor(float left, float top, float right, float bottom,
|
||||
Rect& transformed, Rect& clip) {
|
||||
if (mSnapshot->isIgnored()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
transformed.set(left, top, right, bottom);
|
||||
mSnapshot->transform->mapRect(transformed);
|
||||
transformed.snapToPixelBoundaries();
|
||||
|
||||
clip.set(*mSnapshot->clipRect);
|
||||
clip.snapToPixelBoundaries();
|
||||
|
||||
return !clip.intersects(transformed);
|
||||
}
|
||||
|
||||
bool OpenGLRenderer::quickReject(float left, float top, float right, float bottom) {
|
||||
if (mSnapshot->isIgnored()) {
|
||||
return true;
|
||||
@@ -2574,22 +2603,30 @@ status_t OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) {
|
||||
}
|
||||
|
||||
status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
|
||||
if (!layer || quickReject(x, y, x + layer->layer.getWidth(), y + layer->layer.getHeight())) {
|
||||
if (!layer) {
|
||||
return DrawGlInfo::kStatusDone;
|
||||
}
|
||||
|
||||
Rect transformed;
|
||||
Rect clip;
|
||||
const bool rejected = quickRejectNoScissor(x, y,
|
||||
x + layer->layer.getWidth(), y + layer->layer.getHeight(), transformed, clip);
|
||||
|
||||
if (rejected) {
|
||||
return DrawGlInfo::kStatusDone;
|
||||
}
|
||||
|
||||
bool debugLayerUpdate = false;
|
||||
|
||||
if (layer->deferredUpdateScheduled && layer->renderer && layer->displayList) {
|
||||
OpenGLRenderer* renderer = layer->renderer;
|
||||
Rect& dirty = layer->dirtyRect;
|
||||
|
||||
interrupt();
|
||||
renderer->setViewport(layer->layer.getWidth(), layer->layer.getHeight());
|
||||
renderer->prepareDirty(dirty.left, dirty.top, dirty.right, dirty.bottom, !layer->isBlend());
|
||||
renderer->drawDisplayList(layer->displayList, dirty, DisplayList::kReplayFlag_ClipChildren);
|
||||
renderer->finish();
|
||||
resume();
|
||||
|
||||
resumeAfterLayer();
|
||||
|
||||
dirty.setEmpty();
|
||||
layer->deferredUpdateScheduled = false;
|
||||
@@ -2599,6 +2636,7 @@ status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* pain
|
||||
debugLayerUpdate = mCaches.debugLayersUpdates;
|
||||
}
|
||||
|
||||
mCaches.setScissorEnabled(!clip.contains(transformed));
|
||||
mCaches.activeTexture(0);
|
||||
|
||||
if (CC_LIKELY(!layer->region.isEmpty())) {
|
||||
|
||||
@@ -254,6 +254,17 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Computes the projection matrix, initialize the first snapshot
|
||||
* and stores the dimensions of the render target.
|
||||
*/
|
||||
void initViewport(int width, int height);
|
||||
|
||||
/**
|
||||
* Call this method after updating a layer during a drawing pass.
|
||||
*/
|
||||
void resumeAfterLayer();
|
||||
|
||||
/**
|
||||
* Compose the layer defined in the current snapshot with the layer
|
||||
* defined by the previous snapshot.
|
||||
@@ -359,6 +370,13 @@ private:
|
||||
*/
|
||||
void setScissorFromClip();
|
||||
|
||||
/**
|
||||
* Performs a quick reject but does not affect the scissor. Returns
|
||||
* the transformed rect to test and the current clip.
|
||||
*/
|
||||
bool quickRejectNoScissor(float left, float top, float right, float bottom,
|
||||
Rect& transformed, Rect& clip);
|
||||
|
||||
/**
|
||||
* Creates a new layer stored in the specified snapshot.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user