diff options
author | Romain Guy <romainguy@google.com> | 2011-06-17 17:47:59 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2011-06-17 17:47:59 -0700 |
commit | 98769300af3580723f99415bba0f790e874fb27b (patch) | |
tree | 386aa0d40bb838df92024f41ca9b8381ffa658fb | |
parent | 1a81a16a967173729839d3802a5527ff074f9af9 (diff) | |
parent | d6b2a00dd43257d1498b09175bff63663f6cb861 (diff) | |
download | frameworks_base-98769300af3580723f99415bba0f790e874fb27b.zip frameworks_base-98769300af3580723f99415bba0f790e874fb27b.tar.gz frameworks_base-98769300af3580723f99415bba0f790e874fb27b.tar.bz2 |
Merge "Add error checking to LayerRenderer::copyLayer"
-rw-r--r-- | core/java/android/view/TextureView.java | 9 | ||||
-rw-r--r-- | core/java/android/view/ViewAncestor.java | 2 | ||||
-rw-r--r-- | libs/hwui/Caches.h | 2 | ||||
-rw-r--r-- | libs/hwui/LayerRenderer.cpp | 56 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 1 | ||||
-rw-r--r-- | tests/HwAccelerationTest/AndroidManifest.xml | 9 | ||||
-rw-r--r-- | tests/HwAccelerationTest/src/com/android/test/hwui/GetBitmapActivity.java | 103 |
7 files changed, 161 insertions, 21 deletions
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java index 164c657..0421205 100644 --- a/core/java/android/view/TextureView.java +++ b/core/java/android/view/TextureView.java @@ -306,6 +306,8 @@ public class TextureView extends View { * <p><strong>Do not</strong> invoke this method from a drawing method * ({@link #onDraw(android.graphics.Canvas)} for instance).</p> * + * <p>If an error occurs during the copy, an empty bitmap will be returned.</p> + * * @return A valid {@link Bitmap.Config#ARGB_8888} bitmap, or null if the surface * texture is not available or the width <= 0 or the height <= 0 * @@ -328,6 +330,8 @@ public class TextureView extends View { * <p><strong>Do not</strong> invoke this method from a drawing method * ({@link #onDraw(android.graphics.Canvas)} for instance).</p> * + * <p>If an error occurs during the copy, an empty bitmap will be returned.</p> + * * @param width The width of the bitmap to create * @param height The height of the bitmap to create * @@ -354,6 +358,8 @@ public class TextureView extends View { * <p><strong>Do not</strong> invoke this method from a drawing method * ({@link #onDraw(android.graphics.Canvas)} for instance).</p> * + * <p>If an error occurs, the bitmap is left unchanged.</p> + * * @param bitmap The bitmap to copy the content of the surface texture into, * cannot be null, all configurations are supported * @@ -447,5 +453,6 @@ public class TextureView extends View { public void onSurfaceTextureDestroyed(SurfaceTexture surface); } - private static native void nSetDefaultBufferSize(SurfaceTexture surfaceTexture, int width, int height); + private static native void nSetDefaultBufferSize(SurfaceTexture surfaceTexture, + int width, int height); } diff --git a/core/java/android/view/ViewAncestor.java b/core/java/android/view/ViewAncestor.java index ba3ae58..afbedaf 100644 --- a/core/java/android/view/ViewAncestor.java +++ b/core/java/android/view/ViewAncestor.java @@ -4479,7 +4479,7 @@ public final class ViewAncestor extends Handler implements ViewParent, ArrayList<View> foundViews = mAttachInfo.mFocusablesTempList; foundViews.clear(); - View root = null; + View root; if (accessibilityViewId != View.NO_ID) { root = findViewByAccessibilityId(accessibilityViewId); } else { diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h index 596781e..e64d8ac 100644 --- a/libs/hwui/Caches.h +++ b/libs/hwui/Caches.h @@ -74,7 +74,7 @@ static const GLsizei gMeshCount = 4; struct CacheLogger { CacheLogger() { - LOGD("Creating OpenGL renderer caches"); + INIT_LOGD("Creating OpenGL renderer caches"); } }; // struct CacheLogger diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp index 146e789..77e63d7 100644 --- a/libs/hwui/LayerRenderer.cpp +++ b/libs/hwui/LayerRenderer.cpp @@ -326,12 +326,17 @@ bool LayerRenderer::copyLayer(Layer* layer, SkBitmap* bitmap) { return false; } + SkAutoLockPixels alp(*bitmap); + GLuint texture; GLuint previousFbo; GLenum format; GLenum type; + GLenum error = GL_NO_ERROR; + bool status = false; + switch (bitmap->config()) { case SkBitmap::kA8_Config: format = GL_ALPHA; @@ -352,10 +357,18 @@ bool LayerRenderer::copyLayer(Layer* layer, SkBitmap* bitmap) { break; } + float alpha = layer->alpha; + SkXfermode::Mode mode = layer->mode; + + layer->mode = SkXfermode::kSrc_Mode; + layer->alpha = 255; + layer->fbo = fbo; + glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*) &previousFbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); glGenTextures(1, &texture); + if ((error = glGetError()) != GL_NO_ERROR) goto error; glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture); @@ -368,39 +381,48 @@ bool LayerRenderer::copyLayer(Layer* layer, SkBitmap* bitmap) { glTexImage2D(GL_TEXTURE_2D, 0, format, bitmap->width(), bitmap->height(), 0, format, type, NULL); + if ((error = glGetError()) != GL_NO_ERROR) goto error; + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); + if ((error = glGetError()) != GL_NO_ERROR) goto error; - glBindTexture(GL_TEXTURE_2D, layer->texture); + { + LayerRenderer renderer(layer); + renderer.setViewport(bitmap->width(), bitmap->height()); + renderer.OpenGLRenderer::prepareDirty(0.0f, 0.0f, + bitmap->width(), bitmap->height(), !layer->blend); + if ((error = glGetError()) != GL_NO_ERROR) goto error; - float alpha = layer->alpha; - SkXfermode::Mode mode = layer->mode; + { + Rect bounds; + bounds.set(0.0f, 0.0f, bitmap->width(), bitmap->height()); + renderer.drawTextureLayer(layer, bounds); - layer->mode = SkXfermode::kSrc_Mode; - layer->alpha = 255; - layer->fbo = fbo; + glReadPixels(0, 0, bitmap->width(), bitmap->height(), format, + type, bitmap->getPixels()); - LayerRenderer renderer(layer); - renderer.setViewport(bitmap->width(), bitmap->height()); - renderer.OpenGLRenderer::prepareDirty(0.0f, 0.0f, - bitmap->width(), bitmap->height(), !layer->blend); + if ((error = glGetError()) != GL_NO_ERROR) goto error; + } - Rect bounds; - bounds.set(0.0f, 0.0f, bitmap->width(), bitmap->height()); - renderer.drawTextureLayer(layer, bounds); + status = true; + } - SkAutoLockPixels alp(*bitmap); - glReadPixels(0, 0, bitmap->width(), bitmap->height(), format, type, bitmap->getPixels()); +error: +#if DEBUG_OPENGL + if (error != GL_NO_ERROR) { + LOGD("GL error while copying layer into bitmap = 0x%x", error); + } +#endif glBindFramebuffer(GL_FRAMEBUFFER, previousFbo); - layer->mode = mode; layer->alpha = alpha; layer->fbo = 0; glDeleteTextures(1, &texture); caches.fboCache.put(fbo); - return true; + return status; } return false; } diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 5343a05..88774c6 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -151,7 +151,6 @@ void OpenGLRenderer::prepareDirty(float left, float top, float right, float bott mSaveCount = 1; glViewport(0, 0, mWidth, mHeight); - glDisable(GL_DITHER); glEnable(GL_SCISSOR_TEST); diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml index d5dcd4e..c650021 100644 --- a/tests/HwAccelerationTest/AndroidManifest.xml +++ b/tests/HwAccelerationTest/AndroidManifest.xml @@ -31,6 +31,15 @@ android:hardwareAccelerated="true"> <activity + android:name="GetBitmapActivity" + android:label="_GetBitmap"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + + <activity android:name="SmallCircleActivity" android:label="_SmallCircle"> <intent-filter> diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/GetBitmapActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/GetBitmapActivity.java new file mode 100644 index 0000000..2e23aaa --- /dev/null +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/GetBitmapActivity.java @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.test.hwui; + +import android.app.Activity; +import android.graphics.Bitmap; +import android.graphics.SurfaceTexture; +import android.hardware.Camera; +import android.os.Bundle; +import android.os.Environment; +import android.view.Gravity; +import android.view.TextureView; +import android.view.View; +import android.widget.Button; +import android.widget.FrameLayout; + +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; + +@SuppressWarnings({"UnusedDeclaration"}) +public class GetBitmapActivity extends Activity implements TextureView.SurfaceTextureListener { + private Camera mCamera; + private TextureView mTextureView; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + FrameLayout content = new FrameLayout(this); + + mTextureView = new TextureView(this); + mTextureView.setSurfaceTextureListener(this); + + Button button = new Button(this); + button.setText("Copy bitmap to /sdcard/textureview.png"); + button.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Bitmap b = mTextureView.getBitmap(); + try { + FileOutputStream out = new FileOutputStream( + Environment.getExternalStorageDirectory() + "/textureview.png"); + try { + b.compress(Bitmap.CompressFormat.PNG, 100, out); + } finally { + try { + out.close(); + } catch (IOException e) { + // Ignore + } + } + } catch (FileNotFoundException e) { + // Ignore + } + } + }); + + content.addView(mTextureView, new FrameLayout.LayoutParams(500, 400, Gravity.CENTER)); + content.addView(button, new FrameLayout.LayoutParams( + FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT, + Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM)); + setContentView(content); + } + + @Override + public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { + mCamera = Camera.open(); + + try { + mCamera.setPreviewTexture(surface); + } catch (IOException t) { + android.util.Log.e("TextureView", "Cannot set preview texture target!", t); + } + + mCamera.startPreview(); + } + + @Override + public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { + // Ignored, the Camera does all the work for us + } + + @Override + public void onSurfaceTextureDestroyed(SurfaceTexture surface) { + mCamera.stopPreview(); + mCamera.release(); + } +} |