Prevent crash when a single layer is enqueued several times for updates
Bug #8504687 Change-Id: I9b01bbc4e3f37af23dfe5e68d3d03ad3d238b94a
This commit is contained in:
@@ -165,6 +165,9 @@ void Layer::defer() {
|
||||
dirtyRect.right, dirtyRect.bottom, !isBlend());
|
||||
|
||||
displayList->defer(deferredState, 0);
|
||||
|
||||
deferredUpdateScheduled = false;
|
||||
displayList = NULL;
|
||||
}
|
||||
|
||||
void Layer::flush() {
|
||||
@@ -183,5 +186,21 @@ void Layer::flush() {
|
||||
}
|
||||
}
|
||||
|
||||
void Layer::render() {
|
||||
renderer->setViewport(layer.getWidth(), layer.getHeight());
|
||||
renderer->prepareDirty(dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom,
|
||||
!isBlend());
|
||||
|
||||
renderer->drawDisplayList(displayList, dirtyRect, DisplayList::kReplayFlag_ClipChildren);
|
||||
|
||||
renderer->finish();
|
||||
renderer = NULL;
|
||||
|
||||
dirtyRect.setEmpty();
|
||||
|
||||
deferredUpdateScheduled = false;
|
||||
displayList = NULL;
|
||||
}
|
||||
|
||||
}; // namespace uirenderer
|
||||
}; // namespace android
|
||||
|
||||
@@ -275,6 +275,7 @@ struct Layer {
|
||||
|
||||
void defer();
|
||||
void flush();
|
||||
void render();
|
||||
|
||||
/**
|
||||
* Bounds of the layer.
|
||||
|
||||
@@ -540,13 +540,7 @@ bool OpenGLRenderer::updateLayer(Layer* layer, bool inFrame) {
|
||||
}
|
||||
|
||||
if (CC_UNLIKELY(inFrame || mCaches.drawDeferDisabled)) {
|
||||
OpenGLRenderer* renderer = layer->renderer;
|
||||
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();
|
||||
layer->render();
|
||||
} else {
|
||||
layer->defer();
|
||||
}
|
||||
@@ -556,13 +550,6 @@ bool OpenGLRenderer::updateLayer(Layer* layer, bool inFrame) {
|
||||
startTiling(mSnapshot);
|
||||
}
|
||||
|
||||
if (CC_UNLIKELY(inFrame || mCaches.drawDeferDisabled)) {
|
||||
dirty.setEmpty();
|
||||
layer->renderer = NULL;
|
||||
}
|
||||
|
||||
layer->deferredUpdateScheduled = false;
|
||||
layer->displayList = NULL;
|
||||
layer->debugDrawUpdate = mCaches.debugLayersUpdates;
|
||||
|
||||
return true;
|
||||
@@ -609,11 +596,12 @@ void OpenGLRenderer::flushLayers() {
|
||||
// Note: it is very important to update the layers in reverse order
|
||||
for (int i = count - 1; i >= 0; i--) {
|
||||
sprintf(layerName, "Layer #%d", i);
|
||||
startMark(layerName); {
|
||||
Layer* layer = mLayerUpdates.itemAt(i);
|
||||
layer->flush();
|
||||
mCaches.resourceCache.decrementRefcount(layer);
|
||||
}
|
||||
startMark(layerName);
|
||||
|
||||
Layer* layer = mLayerUpdates.itemAt(i);
|
||||
layer->flush();
|
||||
mCaches.resourceCache.decrementRefcount(layer);
|
||||
|
||||
endMark();
|
||||
}
|
||||
|
||||
@@ -626,6 +614,15 @@ void OpenGLRenderer::flushLayers() {
|
||||
|
||||
void OpenGLRenderer::pushLayerUpdate(Layer* layer) {
|
||||
if (layer) {
|
||||
// Make sure we don't introduce duplicates.
|
||||
// SortedVector would do this automatically but we need to respect
|
||||
// the insertion order. The linear search is not an issue since
|
||||
// this list is usually very short (typically one item, at most a few)
|
||||
for (int i = mLayerUpdates.size() - 1; i >= 0; i--) {
|
||||
if (mLayerUpdates.itemAt(i) == layer) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
mLayerUpdates.push_back(layer);
|
||||
mCaches.resourceCache.incrementRefcount(layer);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user