From f007a2faa1d765e9b53553a8214179b253e3cbbd Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Wed, 28 Oct 2009 21:00:29 -0700 Subject: [PATCH 1/6] return proper error code from eglCreateImageKHR --- libs/surfaceflinger/LayerBuffer.cpp | 4 +--- opengl/libagl/copybit.cpp | 14 ++++++++++++++ opengl/libs/EGL/egl.cpp | 28 ++++++++++++++++++++++++---- 3 files changed, 39 insertions(+), 7 deletions(-) diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp index 6590503d31f11..f70bcf4c987cf 100644 --- a/libs/surfaceflinger/LayerBuffer.cpp +++ b/libs/surfaceflinger/LayerBuffer.cpp @@ -437,9 +437,7 @@ void LayerBuffer::BufferSource::onDraw(const Region& clip) const } if (err != NO_ERROR) { - // OpenGL fall-back - GLuint w = 0; - GLuint h = 0; + // slower fallback GGLSurface t; t.version = sizeof(GGLSurface); t.width = src.crop.r; diff --git a/opengl/libagl/copybit.cpp b/opengl/libagl/copybit.cpp index 4b9e59b7c885f..d73d6ddcf1a22 100644 --- a/opengl/libagl/copybit.cpp +++ b/opengl/libagl/copybit.cpp @@ -74,6 +74,7 @@ private: static int iterate_done(copybit_region_t const *, copybit_rect_t*) { return 0; } +public: copybit_rect_t r; }; @@ -421,6 +422,19 @@ static bool copybit(GLint x, GLint y, (enables & GGL_ENABLE_DITHER) ? COPYBIT_ENABLE : COPYBIT_DISABLE); clipRectRegion it(c); + + LOGD("dst={%d, %d, %d, %p, %p}, " + "src={%d, %d, %d, %p, %p}, " + "drect={%d,%d,%d,%d}, " + "srect={%d,%d,%d,%d}, " + "it={%d,%d,%d,%d}, " , + dst.w, dst.h, dst.format, dst.base, dst.handle, + src.w, src.h, src.format, src.base, src.handle, + drect.l, drect.t, drect.r, drect.b, + srect.l, srect.t, srect.r, srect.b, + it.r.l, it.r.t, it.r.r, it.r.b + ); + err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it); } if (err != NO_ERROR) { diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp index 3efb6780c9412..5efecb064cb33 100644 --- a/opengl/libs/EGL/egl.cpp +++ b/opengl/libs/EGL/egl.cpp @@ -1641,8 +1641,13 @@ EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, if (dp == 0) { return setError(EGL_BAD_DISPLAY, EGL_NO_IMAGE_KHR); } - // since we don't have a way to know which implementation to call, - // we're calling all of them + + /* Since we don't have a way to know which implementation to call, + * we're calling all of them. If at least one of the implementation + * succeeded, this is a success. + */ + + EGLint currentError = eglGetError(); EGLImageKHR implImages[IMPL_NUM_IMPLEMENTATIONS]; bool success = false; @@ -1659,9 +1664,24 @@ EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, } } } - if (!success) + + if (!success) { + // failure, if there was an error when we entered this function, + // the error flag must not be updated. + // Otherwise, the error is whatever happened in the implementation + // that faulted. + if (currentError != EGL_SUCCESS) { + setError(currentError, EGL_NO_IMAGE_KHR); + } return EGL_NO_IMAGE_KHR; - + } else { + // In case of success, we need to clear all error flags + // (especially those caused by the implementation that didn't + // succeed). TODO: we could about this if we knew this was + // a "full" success (all implementation succeeded). + eglGetError(); + } + egl_image_t* result = new egl_image_t(dpy, ctx); memcpy(result->images, implImages, sizeof(implImages)); return (EGLImageKHR)result; From d8b28e4fcddcacdbd2b69584a4e3aa12f52e8229 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Thu, 29 Oct 2009 20:24:44 -0700 Subject: [PATCH 2/6] fix [2225964] Android runtime restarted in surfaceflinger/BlurFilter.cpp crash was due to an unintialized variable, which caused the wrong bluring format to be used and caused a memory overrrun. --- libs/surfaceflinger/LayerBlur.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libs/surfaceflinger/LayerBlur.cpp b/libs/surfaceflinger/LayerBlur.cpp index 744f2e940d20c..5fd7904be6cf0 100644 --- a/libs/surfaceflinger/LayerBlur.cpp +++ b/libs/surfaceflinger/LayerBlur.cpp @@ -40,9 +40,10 @@ const char* const LayerBlur::typeID = "LayerBlur"; LayerBlur::LayerBlur(SurfaceFlinger* flinger, DisplayID display, const sp& client, int32_t i) -: LayerBaseClient(flinger, display, client, i), mCacheDirty(true), -mRefreshCache(true), mCacheAge(0), mTextureName(-1U), -mWidthScale(1.0f), mHeightScale(1.0f) + : LayerBaseClient(flinger, display, client, i), mCacheDirty(true), + mRefreshCache(true), mCacheAge(0), mTextureName(-1U), + mWidthScale(1.0f), mHeightScale(1.0f), + mBlurFormat(GGL_PIXEL_FORMAT_RGB_565) { } From 0e1e62301112a51d9b91ac4ac31c406d726f93ab Mon Sep 17 00:00:00 2001 From: Mike Reed Date: Thu, 29 Oct 2009 17:20:49 -0400 Subject: [PATCH 3/6] add table maskfilter hidden for now, since it need only be seen by Launcher2 http://b/issue?id=2210685 --- core/jni/android/graphics/MaskFilter.cpp | 21 +++++++++ .../android/graphics/TableMaskFilter.java | 46 +++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 graphics/java/android/graphics/TableMaskFilter.java diff --git a/core/jni/android/graphics/MaskFilter.cpp b/core/jni/android/graphics/MaskFilter.cpp index 0f8dff1210551..455449e5349d1 100644 --- a/core/jni/android/graphics/MaskFilter.cpp +++ b/core/jni/android/graphics/MaskFilter.cpp @@ -1,6 +1,7 @@ #include "GraphicsJNI.h" #include "SkMaskFilter.h" #include "SkBlurMaskFilter.h" +#include "SkTableMaskFilter.h" #include @@ -39,6 +40,19 @@ public: ThrowIAE_IfNull(env, filter); return filter; } + + static SkMaskFilter* createTable(JNIEnv* env, jobject, jbyteArray jtable) { + AutoJavaByteArray autoTable(env, jtable, 256); + return new SkTableMaskFilter((const uint8_t*)autoTable.ptr()); + } + + static SkMaskFilter* createClipTable(JNIEnv* env, jobject, int min, int max) { + return SkTableMaskFilter::CreateClip(min, max); + } + + static SkMaskFilter* createGammaTable(JNIEnv* env, jobject, float gamma) { + return SkTableMaskFilter::CreateGamma(gamma); + } }; static JNINativeMethod gMaskFilterMethods[] = { @@ -53,6 +67,12 @@ static JNINativeMethod gEmbossMaskFilterMethods[] = { { "nativeConstructor", "([FFFF)I", (void*)SkMaskFilterGlue::createEmboss } }; +static JNINativeMethod gTableMaskFilterMethods[] = { + { "nativeNewTable", "([B)I", (void*)SkMaskFilterGlue::createTable }, + { "nativeNewClip", "(II)I", (void*)SkMaskFilterGlue::createClipTable }, + { "nativeNewGamma", "(F)I", (void*)SkMaskFilterGlue::createGammaTable } +}; + #include #define REG(env, name, array) \ @@ -67,6 +87,7 @@ int register_android_graphics_MaskFilter(JNIEnv* env) REG(env, "android/graphics/MaskFilter", gMaskFilterMethods); REG(env, "android/graphics/BlurMaskFilter", gBlurMaskFilterMethods); REG(env, "android/graphics/EmbossMaskFilter", gEmbossMaskFilterMethods); + REG(env, "android/graphics/TableMaskFilter", gTableMaskFilterMethods); return 0; } diff --git a/graphics/java/android/graphics/TableMaskFilter.java b/graphics/java/android/graphics/TableMaskFilter.java new file mode 100644 index 0000000000000..a8a7ff0528e13 --- /dev/null +++ b/graphics/java/android/graphics/TableMaskFilter.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2006 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 android.graphics; + +/** + * @hide + */ +public class TableMaskFilter extends MaskFilter { + + public TableMaskFilter(byte[] table) { + if (table.length < 256) { + throw new RuntimeException("table.length must be >= 256"); + } + native_instance = nativeNewTable(table); + } + + private TableMaskFilter(int ni) { + native_instance = ni; + } + + public static TableMaskFilter CreateClipTable(int min, int max) { + return new TableMaskFilter(nativeNewClip(min, max)); + } + + public static TableMaskFilter CreateGammaTable(float gamma) { + return new TableMaskFilter(nativeNewGamma(gamma)); + } + + private static native int nativeNewTable(byte[] table); + private static native int nativeNewClip(int min, int max); + private static native int nativeNewGamma(float gamma); +} From 4b3db907f04d85cd20e0a0e35056ba44a10e8867 Mon Sep 17 00:00:00 2001 From: Jaikumar Ganesh Date: Fri, 30 Oct 2009 09:37:25 -0700 Subject: [PATCH 4/6] Revert the channge where channels were not selected randomly. The Bluez SDP bug has been fixed. Reverting parts of the commit: 16fb88a673c41b93c5d57ccb28c2697e7d87701a Bug: 2173752 Dr No: Eastham --- .../android/bluetooth/BluetoothAdapter.java | 23 ++++--------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index ff48583a80305..3fc676b271f24 100644 --- a/core/java/android/bluetooth/BluetoothAdapter.java +++ b/core/java/android/bluetooth/BluetoothAdapter.java @@ -597,14 +597,6 @@ public final class BluetoothAdapter { /** * Picks RFCOMM channels until none are left. * Avoids reserved channels. - * Ideally we would pick random channels, but in the current implementation - * we start with the channel that is the hash of the UUID, and try every - * available channel from there. This means that in most cases a given - * uuid will use the same channel. This is a workaround for a Bluez SDP - * bug where we are not updating the cache when the channel changes for a - * uuid. - * TODO: Fix the Bluez SDP caching bug, and go back to random channel - * selection */ private static class RfcommChannelPicker { private static final int[] RESERVED_RFCOMM_CHANNELS = new int[] { @@ -637,19 +629,12 @@ public final class BluetoothAdapter { } mUuid = uuid; } - /* Returns next channel, or -1 if we're out */ + /* Returns next random channel, or -1 if we're out */ public int nextChannel() { - int channel = mUuid.hashCode(); // always pick the same channel to try first - Integer channelInt; - while (mChannels.size() > 0) { - channelInt = new Integer(channel); - if (mChannels.remove(channelInt)) { - return channel; - } - channel = (channel % BluetoothSocket.MAX_RFCOMM_CHANNEL) + 1; + if (mChannels.size() == 0) { + return -1; } - - return -1; + return mChannels.remove(sRandom.nextInt(mChannels.size())); } } From 08c19beee4c8a2fce3f9d2baa78c9d436bedf65d Mon Sep 17 00:00:00 2001 From: Andy McFadden Date: Thu, 29 Oct 2009 10:19:34 -0700 Subject: [PATCH 5/6] DO NOT MERGE: Another gcc 4.0.3 workaround. Temporarily make a function public that doesn't need to be. When host gcc-4.0.3 is gone from the build servers we can undo this. (Cherry-picked from eclair-mr2.) --- libs/surfaceflinger/SurfaceFlinger.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h index 6698e003c32dc..f9bfe6c7c3016 100644 --- a/libs/surfaceflinger/SurfaceFlinger.h +++ b/libs/surfaceflinger/SurfaceFlinger.h @@ -246,8 +246,10 @@ private: virtual status_t readyToRun(); virtual void onFirstRef(); +public: // hack to work around gcc 4.0.3 bug const GraphicPlane& graphicPlane(int dpy) const; GraphicPlane& graphicPlane(int dpy); +private: void waitForEvent(); public: // hack to work around gcc 4.0.3 bug From 0b0722f980f40e1ac0929a7f1a6e2df7af983478 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Thu, 29 Oct 2009 18:29:30 -0700 Subject: [PATCH 6/6] fix[2222341] Soft reset while going back from camcorder settings add a way to convert a mapped "pushbuffer" buffer to a gralloc handle which then can be safely used by surfaceflinger, without including gralloc_priv.h --- libs/surfaceflinger/LayerBuffer.cpp | 55 ++++++++++++++++++----------- libs/surfaceflinger/LayerBuffer.h | 5 +++ opengl/libs/EGL/egl.cpp | 2 +- 3 files changed, 41 insertions(+), 21 deletions(-) diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp index f70bcf4c987cf..82a8e519f8738 100644 --- a/libs/surfaceflinger/LayerBuffer.cpp +++ b/libs/surfaceflinger/LayerBuffer.cpp @@ -33,14 +33,13 @@ #include "SurfaceFlinger.h" #include "DisplayHardware/DisplayHardware.h" -#include "gralloc_priv.h" // needed for msm / copybit - namespace android { // --------------------------------------------------------------------------- const uint32_t LayerBuffer::typeInfo = LayerBaseClient::typeInfo | 0x20; const char* const LayerBuffer::typeID = "LayerBuffer"; +gralloc_module_t const* LayerBuffer::sGrallocModule = 0; // --------------------------------------------------------------------------- @@ -60,6 +59,16 @@ void LayerBuffer::onFirstRef() LayerBaseClient::onFirstRef(); mSurface = new SurfaceLayerBuffer(mFlinger, clientIndex(), const_cast(this)); + + hw_module_t const* module = (hw_module_t const*)sGrallocModule; + if (!module) { + // NOTE: technically there is a race here, but it shouldn't + // cause any problem since hw_get_module() always returns + // the same value. + if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) { + sGrallocModule = (gralloc_module_t const *)module; + } + } } sp LayerBuffer::createSurface() const @@ -243,30 +252,36 @@ LayerBuffer::Buffer::Buffer(const ISurface::BufferHeap& buffers, ssize_t offset) : mBufferHeap(buffers) { NativeBuffer& src(mNativeBuffer); - - src.crop.l = 0; - src.crop.t = 0; - src.crop.r = buffers.w; - src.crop.b = buffers.h; - - src.img.w = buffers.hor_stride ?: buffers.w; - src.img.h = buffers.ver_stride ?: buffers.h; - src.img.format = buffers.format; - src.img.base = (void*)(intptr_t(buffers.heap->base()) + offset); + src.img.handle = 0; - // FIXME: gross hack, we should never access private_handle_t from here, - // but this is needed by msm drivers - private_handle_t* hnd = new private_handle_t( - buffers.heap->heapID(), buffers.heap->getSize(), 0); - hnd->offset = offset; - src.img.handle = hnd; + gralloc_module_t const * module = LayerBuffer::getGrallocModule(); + if (module && module->perform) { + int err = module->perform(module, + GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER, + buffers.heap->heapID(), buffers.heap->getSize(), + offset, buffers.heap->base(), + &src.img.handle); + + if (err == NO_ERROR) { + src.crop.l = 0; + src.crop.t = 0; + src.crop.r = buffers.w; + src.crop.b = buffers.h; + + src.img.w = buffers.hor_stride ?: buffers.w; + src.img.h = buffers.ver_stride ?: buffers.h; + src.img.format = buffers.format; + src.img.base = (void*)(intptr_t(buffers.heap->base()) + offset); + } + } } LayerBuffer::Buffer::~Buffer() { NativeBuffer& src(mNativeBuffer); - if (src.img.handle) - delete (private_handle_t*)src.img.handle; + if (src.img.handle) { + native_handle_delete(src.img.handle); + } } // ============================================================================ diff --git a/libs/surfaceflinger/LayerBuffer.h b/libs/surfaceflinger/LayerBuffer.h index 438b711be9c3e..47482f49e476f 100644 --- a/libs/surfaceflinger/LayerBuffer.h +++ b/libs/surfaceflinger/LayerBuffer.h @@ -91,6 +91,11 @@ private: copybit_rect_t crop; }; + static gralloc_module_t const* sGrallocModule; + static gralloc_module_t const* getGrallocModule() { + return sGrallocModule; + } + class Buffer : public LightRefBase { public: Buffer(const ISurface::BufferHeap& buffers, ssize_t offset); diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp index 5efecb064cb33..c22c21b89e6b9 100644 --- a/opengl/libs/EGL/egl.cpp +++ b/opengl/libs/EGL/egl.cpp @@ -1677,7 +1677,7 @@ EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, } else { // In case of success, we need to clear all error flags // (especially those caused by the implementation that didn't - // succeed). TODO: we could about this if we knew this was + // succeed). TODO: we could avoid this if we knew this was // a "full" success (all implementation succeeded). eglGetError(); }