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())); } } 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); +} 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) { } diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp index 6590503d31f11..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); + } } // ============================================================================ @@ -437,9 +452,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/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/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 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..c22c21b89e6b9 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 avoid 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;