Merge "Discard framebuffer rendering queues when discarding layers Bug #5581817" into ics-mr1
This commit is contained in:
committed by
Android (Google) Code Review
commit
2858749704
@ -154,6 +154,7 @@ class GLES20Canvas extends HardwareCanvas {
|
||||
static native void nSetTextureLayerTransform(int layerId, int matrix);
|
||||
static native void nDestroyLayer(int layerId);
|
||||
static native void nDestroyLayerDeferred(int layerId);
|
||||
static native void nFlushLayer(int layerId);
|
||||
static native boolean nCopyLayer(int layerId, int bitmap);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
@ -60,6 +60,13 @@ abstract class GLES20Layer extends HardwareLayer {
|
||||
}
|
||||
mLayer = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
void flush() {
|
||||
if (mLayer != 0) {
|
||||
GLES20Canvas.nFlushLayer(mLayer);
|
||||
}
|
||||
}
|
||||
|
||||
static class Finalizer {
|
||||
private int mLayerId;
|
||||
|
@ -115,6 +115,11 @@ abstract class HardwareLayer {
|
||||
*/
|
||||
abstract void destroy();
|
||||
|
||||
/**
|
||||
* Flush the render queue associated with this layer.
|
||||
*/
|
||||
abstract void flush();
|
||||
|
||||
/**
|
||||
* This must be invoked before drawing onto this layer.
|
||||
* @param currentCanvas
|
||||
|
@ -10146,6 +10146,12 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void flushLayer() {
|
||||
if (mLayerType == LAYER_TYPE_HARDWARE && mHardwareLayer != null) {
|
||||
mHardwareLayer.flush();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns a hardware layer that can be used to draw this view again
|
||||
@ -10158,6 +10164,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
|
||||
!mAttachInfo.mHardwareRenderer.isEnabled()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!mAttachInfo.mHardwareRenderer.validate()) return null;
|
||||
|
||||
|
||||
final int width = mRight - mLeft;
|
||||
final int height = mBottom - mTop;
|
||||
@ -10232,8 +10241,14 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
|
||||
*/
|
||||
boolean destroyLayer() {
|
||||
if (mHardwareLayer != null) {
|
||||
mHardwareLayer.destroy();
|
||||
mHardwareLayer = null;
|
||||
AttachInfo info = mAttachInfo;
|
||||
if (info != null && info.mHardwareRenderer != null &&
|
||||
info.mHardwareRenderer.isEnabled()) {
|
||||
if (!info.mHardwareRenderer.validate()) {
|
||||
mHardwareLayer.destroy();
|
||||
mHardwareLayer = null;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -2957,6 +2957,16 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
||||
if (enabled != mDrawLayers) {
|
||||
mDrawLayers = enabled;
|
||||
invalidate(true);
|
||||
|
||||
AttachInfo info = mAttachInfo;
|
||||
if (info != null && info.mHardwareRenderer != null &&
|
||||
info.mHardwareRenderer.isEnabled()) {
|
||||
if (!info.mHardwareRenderer.validate()) {
|
||||
enabled = false;
|
||||
}
|
||||
} else {
|
||||
enabled = false;
|
||||
}
|
||||
|
||||
// We need to invalidate any child with a layer. For instance,
|
||||
// if a child is backed by a hardware layer and we disable layers
|
||||
@ -2968,6 +2978,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
||||
for (int i = 0; i < mChildrenCount; i++) {
|
||||
View child = mChildren[i];
|
||||
if (child.mLayerType != LAYER_TYPE_NONE) {
|
||||
if (!enabled) child.flushLayer();
|
||||
child.invalidate(true);
|
||||
}
|
||||
}
|
||||
|
@ -718,6 +718,10 @@ static void android_view_GLES20Canvas_destroyLayerDeferred(JNIEnv* env,
|
||||
LayerRenderer::destroyLayerDeferred(layer);
|
||||
}
|
||||
|
||||
static void android_view_GLES20Canvas_flushLayer(JNIEnv* env, jobject clazz, Layer* layer) {
|
||||
LayerRenderer::flushLayer(layer);
|
||||
}
|
||||
|
||||
static void android_view_GLES20Canvas_drawLayer(JNIEnv* env, jobject clazz,
|
||||
OpenGLRenderer* renderer, Layer* layer, jfloat x, jfloat y, SkPaint* paint) {
|
||||
renderer->drawLayer(layer, x, y, paint);
|
||||
@ -860,6 +864,7 @@ static JNINativeMethod gMethods[] = {
|
||||
{ "nSetTextureLayerTransform", "(II)V", (void*) android_view_GLES20Canvas_setTextureLayerTransform },
|
||||
{ "nDestroyLayer", "(I)V", (void*) android_view_GLES20Canvas_destroyLayer },
|
||||
{ "nDestroyLayerDeferred", "(I)V", (void*) android_view_GLES20Canvas_destroyLayerDeferred },
|
||||
{ "nFlushLayer", "(I)V", (void*) android_view_GLES20Canvas_flushLayer },
|
||||
{ "nDrawLayer", "(IIFFI)V", (void*) android_view_GLES20Canvas_drawLayer },
|
||||
{ "nCopyLayer", "(II)Z", (void*) android_view_GLES20Canvas_copyLayer },
|
||||
|
||||
|
@ -38,7 +38,7 @@ ifeq ($(USE_OPENGL_RENDERER),true)
|
||||
external/skia/src/ports \
|
||||
external/skia/include/utils
|
||||
|
||||
LOCAL_CFLAGS += -DUSE_OPENGL_RENDERER
|
||||
LOCAL_CFLAGS += -DUSE_OPENGL_RENDERER -DGL_GLEXT_PROTOTYPES
|
||||
LOCAL_CFLAGS += -fvisibility=hidden
|
||||
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
|
||||
LOCAL_SHARED_LIBRARIES := libcutils libutils libGLESv2 libskia libui
|
||||
|
@ -66,6 +66,7 @@ public:
|
||||
|
||||
mHasNPot = hasExtension("GL_OES_texture_npot");
|
||||
mHasFramebufferFetch = hasExtension("GL_NV_shader_framebuffer_fetch");
|
||||
mHasDiscardFramebuffer = hasExtension("GL_EXT_discard_framebuffer");
|
||||
|
||||
const char* vendor = (const char*) glGetString(GL_VENDOR);
|
||||
EXT_LOGD("Vendor: %s", vendor);
|
||||
@ -80,6 +81,7 @@ public:
|
||||
inline bool hasNPot() const { return mHasNPot; }
|
||||
inline bool hasFramebufferFetch() const { return mHasFramebufferFetch; }
|
||||
inline bool needsHighpTexCoords() const { return mNeedsHighpTexCoords; }
|
||||
inline bool hasDiscardFramebuffer() const { return mHasDiscardFramebuffer; }
|
||||
|
||||
bool hasExtension(const char* extension) const {
|
||||
const String8 s(extension);
|
||||
@ -98,6 +100,7 @@ private:
|
||||
bool mHasNPot;
|
||||
bool mNeedsHighpTexCoords;
|
||||
bool mHasFramebufferFetch;
|
||||
bool mHasDiscardFramebuffer;
|
||||
}; // class Extensions
|
||||
|
||||
}; // namespace uirenderer
|
||||
|
@ -305,8 +305,10 @@ void LayerRenderer::destroyLayer(Layer* layer) {
|
||||
LAYER_RENDERER_LOGD("Recycling layer, %dx%d fbo = %d",
|
||||
layer->getWidth(), layer->getHeight(), layer->getFbo());
|
||||
|
||||
if (layer->getFbo()) {
|
||||
Caches::getInstance().fboCache.put(layer->getFbo());
|
||||
GLuint fbo = layer->getFbo();
|
||||
if (fbo) {
|
||||
flushLayer(layer);
|
||||
Caches::getInstance().fboCache.put(fbo);
|
||||
}
|
||||
|
||||
if (!Caches::getInstance().layerCache.put(layer)) {
|
||||
@ -331,6 +333,26 @@ void LayerRenderer::destroyLayerDeferred(Layer* layer) {
|
||||
}
|
||||
}
|
||||
|
||||
void LayerRenderer::flushLayer(Layer* layer) {
|
||||
#ifdef GL_EXT_discard_framebuffer
|
||||
GLuint fbo = layer->getFbo();
|
||||
if (layer && fbo) {
|
||||
// If possible, discard any enqued operations on deferred
|
||||
// rendering architectures
|
||||
if (Caches::getInstance().extensions.hasDiscardFramebuffer()) {
|
||||
GLuint previousFbo;
|
||||
glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*) &previousFbo);
|
||||
|
||||
GLenum attachments = GL_COLOR_ATTACHMENT0;
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, &attachments);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, previousFbo);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool LayerRenderer::copyLayer(Layer* layer, SkBitmap* bitmap) {
|
||||
Caches& caches = Caches::getInstance();
|
||||
if (layer && layer->isTextureLayer() && bitmap->width() <= caches.maxTextureSize &&
|
||||
|
@ -61,6 +61,7 @@ public:
|
||||
bool isOpaque, GLenum renderTarget, float* transform);
|
||||
ANDROID_API static void destroyLayer(Layer* layer);
|
||||
ANDROID_API static void destroyLayerDeferred(Layer* layer);
|
||||
ANDROID_API static void flushLayer(Layer* layer);
|
||||
ANDROID_API static bool copyLayer(Layer* layer, SkBitmap* bitmap);
|
||||
|
||||
private:
|
||||
|
@ -611,6 +611,11 @@ void OpenGLRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) {
|
||||
}
|
||||
|
||||
if (fboLayer) {
|
||||
// Note: No need to use glDiscardFramebufferEXT() since we never
|
||||
// create/compose layers that are not on screen with this
|
||||
// code path
|
||||
// See LayerRenderer::destroyLayer(Layer*)
|
||||
|
||||
// Detach the texture from the FBO
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, current->fbo);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
|
||||
|
Reference in New Issue
Block a user