From 1473f46cbc82aa6f0ba744cc896a36923823d55b Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Fri, 10 Apr 2009 14:24:30 -0700 Subject: [PATCH 01/83] Integrate from //sandbox/mathias/donut/...@145728 SurfaceFlinger rework for new EGL driver model support. --- core/jni/Android.mk | 2 + core/jni/android_view_Surface.cpp | 25 +- .../com_google_android_gles_jni_EGLImpl.cpp | 3 +- .../drawable/stat_sys_signal_flightmode.png | Bin include/private/opengles/gl_context.h | 43 +- include/private/ui/SharedState.h | 17 +- include/ui/BufferMapper.h | 57 + include/ui/EGLNativeWindowSurface.h | 98 +- include/ui/ISurface.h | 8 +- include/ui/ISurfaceComposer.h | 37 - include/ui/ISurfaceFlingerClient.h | 1 - include/ui/PixelFormat.h | 36 +- include/ui/Surface.h | 82 +- include/ui/SurfaceComposerClient.h | 22 +- include/utils/Parcel.h | 18 +- include/utils/Singleton.h | 59 + libs/surfaceflinger/Android.mk | 7 +- libs/surfaceflinger/BootAnimation.cpp | 11 +- libs/surfaceflinger/BootAnimation.h | 1 - libs/surfaceflinger/BufferAllocator.cpp | 162 +++ libs/surfaceflinger/BufferAllocator.h | 100 ++ libs/surfaceflinger/CPUGauge.cpp | 4 +- .../DisplayHardware/DisplayHardware.cpp | 147 ++- .../DisplayHardware/DisplayHardware.h | 19 +- .../DisplayHardware/DisplayHardwareBase.cpp | 2 - libs/surfaceflinger/Layer.cpp | 335 +++-- libs/surfaceflinger/Layer.h | 46 +- libs/surfaceflinger/LayerBase.cpp | 313 ++--- libs/surfaceflinger/LayerBase.h | 90 +- libs/surfaceflinger/LayerBitmap.cpp | 286 +++-- libs/surfaceflinger/LayerBitmap.h | 118 +- libs/surfaceflinger/LayerBlur.cpp | 2 - libs/surfaceflinger/LayerBuffer.cpp | 212 +--- libs/surfaceflinger/LayerBuffer.h | 22 +- libs/surfaceflinger/LayerDim.cpp | 66 +- libs/surfaceflinger/LayerDim.h | 4 - libs/surfaceflinger/LayerOrientationAnim.cpp | 129 +- libs/surfaceflinger/LayerOrientationAnim.h | 8 +- .../LayerOrientationAnimRotate.cpp | 19 +- .../LayerOrientationAnimRotate.h | 8 +- libs/surfaceflinger/OrientationAnimation.cpp | 23 +- libs/surfaceflinger/OrientationAnimation.h | 3 +- libs/surfaceflinger/SurfaceFlinger.cpp | 254 ++-- libs/surfaceflinger/SurfaceFlinger.h | 98 +- libs/surfaceflinger/Tokenizer.cpp | 5 +- libs/surfaceflinger/purgatory/VRamHeap.cpp | 174 +++ libs/surfaceflinger/purgatory/VRamHeap.h | 78 ++ libs/surfaceflinger/tests/resize/Android.mk | 16 + libs/surfaceflinger/tests/resize/resize.cpp | 60 + libs/ui/Android.mk | 2 +- libs/ui/BufferMapper.cpp | 83 ++ libs/ui/EGLDisplaySurface.cpp | 519 -------- libs/ui/EGLNativeWindowSurface.cpp | 283 +++-- libs/ui/ISurface.cpp | 21 + libs/ui/ISurfaceComposer.cpp | 90 -- libs/ui/ISurfaceFlingerClient.cpp | 4 - libs/ui/Overlay.cpp | 12 +- libs/ui/Surface.cpp | 442 ++++++- libs/ui/SurfaceComposerClient.cpp | 283 +---- libs/utils/Parcel.cpp | 40 +- opengl/include/EGL/android_natives.h | 265 ++++ opengl/include/EGL/eglplatform.h | 9 +- opengl/include/GLES/glplatform.h | 6 - opengl/libagl/Android.mk | 13 +- opengl/libagl/TextureObjectManager.cpp | 25 +- opengl/libagl/TextureObjectManager.h | 19 +- opengl/libagl/array.cpp | 109 +- opengl/libagl/copybit.cpp | 370 ++++++ opengl/libagl/copybit.h | 75 ++ opengl/libagl/egl.cpp | 427 +++++-- opengl/libagl/state.cpp | 82 +- opengl/libagl/texture.cpp | 208 +++- opengl/libs/Android.mk | 10 +- opengl/libs/EGL/egl.cpp | 371 ++++-- opengl/libs/GLES_CM/gl.cpp | 37 +- opengl/libs/GLES_CM/gl_api.in | 1080 ++++++++++------- opengl/libs/egl_entries.in | 7 + opengl/libs/egl_impl.h | 3 + opengl/libs/gl_entries.in | 95 +- opengl/libs/hooks.h | 10 +- opengl/libs/tools/glapigen | 51 + opengl/tests/copybits/Android.mk | 18 + opengl/tests/copybits/copybits.cpp | 752 ++++++++++++ 83 files changed, 5854 insertions(+), 3297 deletions(-) mode change 100644 => 100755 core/res/res/drawable/stat_sys_signal_flightmode.png create mode 100644 include/ui/BufferMapper.h create mode 100644 include/utils/Singleton.h create mode 100644 libs/surfaceflinger/BufferAllocator.cpp create mode 100644 libs/surfaceflinger/BufferAllocator.h create mode 100644 libs/surfaceflinger/purgatory/VRamHeap.cpp create mode 100644 libs/surfaceflinger/purgatory/VRamHeap.h create mode 100644 libs/surfaceflinger/tests/resize/Android.mk create mode 100644 libs/surfaceflinger/tests/resize/resize.cpp create mode 100644 libs/ui/BufferMapper.cpp delete mode 100644 libs/ui/EGLDisplaySurface.cpp create mode 100644 opengl/include/EGL/android_natives.h create mode 100644 opengl/libagl/copybit.cpp create mode 100644 opengl/libagl/copybit.h create mode 100755 opengl/libs/tools/glapigen create mode 100644 opengl/tests/copybits/Android.mk create mode 100644 opengl/tests/copybits/copybits.cpp diff --git a/core/jni/Android.mk b/core/jni/Android.mk index 31b21e5d1ab1b..766febd712c17 100644 --- a/core/jni/Android.mk +++ b/core/jni/Android.mk @@ -15,6 +15,8 @@ ifneq ($(USE_CUSTOM_RUNTIME_HEAP_MAX),) LOCAL_CFLAGS += -DCUSTOM_RUNTIME_HEAP_MAX=$(USE_CUSTOM_RUNTIME_HEAP_MAX) endif +LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES + LOCAL_SRC_FILES:= \ ActivityManager.cpp \ AndroidRuntime.cpp \ diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp index 076775f44bc08..54d8b14f062e7 100644 --- a/core/jni/android_view_Surface.cpp +++ b/core/jni/android_view_Surface.cpp @@ -235,7 +235,8 @@ static jobject Surface_lockCanvas(JNIEnv* env, jobject clazz, jobject dirtyRect) SkCanvas* nativeCanvas = (SkCanvas*)env->GetIntField(canvas, no.native_canvas); SkBitmap bitmap; - bitmap.setConfig(convertPixelFormat(info.format), info.w, info.h, info.bpr); + ssize_t bpr = info.s * bytesPerPixel(info.format); + bitmap.setConfig(convertPixelFormat(info.format), info.w, info.h, bpr); if (info.w > 0 && info.h > 0) { bitmap.setPixels(info.bits); } else { @@ -289,26 +290,8 @@ static void Surface_unlockCanvasAndPost( static void Surface_unlockCanvas( JNIEnv* env, jobject clazz, jobject argCanvas) { - jobject canvas = env->GetObjectField(clazz, so.canvas); - if (canvas != argCanvas) { - doThrow(env, "java/lang/IllegalArgumentException", NULL); - return; - } - - const sp& surface = getSurface(env, clazz); - if (!surface->isValid()) - return; - - status_t err = surface->unlock(); - if (err < 0) { - doThrow(env, "java/lang/IllegalArgumentException", NULL); - return; - } - SkCanvas* nativeCanvas = (SkCanvas*)env->GetIntField(canvas, no.native_canvas); - int saveCount = env->GetIntField(clazz, so.saveCount); - nativeCanvas->restoreToCount(saveCount); - nativeCanvas->setBitmapDevice(SkBitmap()); - env->SetIntField(clazz, so.saveCount, 0); + // XXX: this API has been removed + doThrow(env, "java/lang/IllegalArgumentException", NULL); } static void Surface_openTransaction( diff --git a/core/jni/com_google_android_gles_jni_EGLImpl.cpp b/core/jni/com_google_android_gles_jni_EGLImpl.cpp index 4452065956bfc..974fc0bd12275 100644 --- a/core/jni/com_google_android_gles_jni_EGLImpl.cpp +++ b/core/jni/com_google_android_gles_jni_EGLImpl.cpp @@ -21,7 +21,6 @@ #include #include -#include #include #include #include @@ -338,7 +337,7 @@ not_valid_surface: goto not_valid_surface; jint* base = beginNativeAttribList(_env, attrib_list); - EGLSurface sur = eglCreateWindowSurface(dpy, cnf, new EGLNativeWindowSurface(window), base); + EGLSurface sur = eglCreateWindowSurface(dpy, cnf, window, base); endNativeAttributeList(_env, attrib_list, base); return (jint)sur; } diff --git a/core/res/res/drawable/stat_sys_signal_flightmode.png b/core/res/res/drawable/stat_sys_signal_flightmode.png old mode 100644 new mode 100755 diff --git a/include/private/opengles/gl_context.h b/include/private/opengles/gl_context.h index 0c7ad462fb2ac..641961f3a822e 100644 --- a/include/private/opengles/gl_context.h +++ b/include/private/opengles/gl_context.h @@ -26,6 +26,7 @@ #endif #include +#include #include #include @@ -39,7 +40,7 @@ class EGLSurfaceManager; class EGLBufferObjectManager; namespace gl { - + struct ogles_context_t; struct matrixx_t; struct transform_t; @@ -96,7 +97,7 @@ struct vec4_t { struct vertex_t { enum { - // these constant matter for our clipping + // these constant matter for our clipping CLIP_L = 0x0001, // clipping flags CLIP_R = 0x0002, CLIP_B = 0x0004, @@ -106,7 +107,7 @@ struct vertex_t { EYE = 0x0040, RESERVED = 0x0080, - + USER_CLIP_0 = 0x0100, // user clipping flags USER_CLIP_1 = 0x0200, USER_CLIP_2 = 0x0400, @@ -121,7 +122,7 @@ struct vertex_t { USER_CLIP_ALL = 0x3F00, CLIP_ALL = 0x3F3F, }; - + // the fields below are arranged to minimize d-cache usage // we group together, by cache-line, the fields most likely to be used @@ -130,7 +131,7 @@ struct vertex_t { vec4_t eye; }; vec4_t clip; - + uint32_t flags; size_t index; // cache tag, and vertex index GLfixed fog; @@ -142,7 +143,7 @@ struct vertex_t { vec4_t color; vec4_t texture[GGL_TEXTURE_UNIT_COUNT]; uint32_t reserved1[4]; - + inline void clear() { flags = index = locked = mru = 0; } @@ -199,7 +200,7 @@ struct array_machine_t { GLenum indicesType; buffer_t const* array_buffer; buffer_t const* element_array_buffer; - + void (*compileElements)(ogles_context_t*, vertex_t*, GLint, GLsizei); void (*compileElement)(ogles_context_t*, vertex_t*, GLint); @@ -410,7 +411,7 @@ struct transform_t { matrixx_t matrix; uint32_t flags; uint32_t ops; - + union { struct { void (*point2)(transform_t const* t, vec4_t*, vec4_t const*); @@ -509,17 +510,17 @@ struct viewport_t { GLint x; GLint y; GLsizei w; - GLsizei h; + GLsizei h; struct { GLint x; GLint y; - } surfaceport; + } surfaceport; struct { GLint x; GLint y; GLsizei w; - GLsizei h; - } scissor; + GLsizei h; + } scissor; }; // ---------------------------------------------------------------------------- @@ -594,6 +595,16 @@ struct prims_t { void (*renderTriangle)(GL, vertex_t*, vertex_t*, vertex_t*); }; +struct copybits_context_t { + // A handle to the blit engine, if it exists, else NULL. + copybit_device_t* blitEngine; + int32_t minScale; + int32_t maxScale; + // File descriptor of current drawing surface, if it's suitable for use as + // a copybits destination, else -1. + int drawSurfaceFd; +}; + struct ogles_context_t { context_t rasterizer; array_machine_t arrays __attribute__((aligned(32))); @@ -617,6 +628,14 @@ struct ogles_context_t { uint32_t transformTextures : 1; EGLSurfaceManager* surfaceManager; EGLBufferObjectManager* bufferObjectManager; + + // copybits is only used if LIBAGL_USE_GRALLOC_COPYBITS is + // defined, but it is always present because ogles_context_t is a public + // struct that is used by clients of libagl. We want the size and offsets + // to stay the same, whether or not LIBAGL_USE_GRALLOC_COPYBITS is defined. + + copybits_context_t copybits; + GLenum error; static inline ogles_context_t* get() { diff --git a/include/private/ui/SharedState.h b/include/private/ui/SharedState.h index 546d0adfd21ec..646cc10e9a4de 100644 --- a/include/private/ui/SharedState.h +++ b/include/private/ui/SharedState.h @@ -32,16 +32,12 @@ namespace android { struct surface_info_t { // 4 longs, 16 bytes enum { - eBufferDirty = 0x01 + eBufferDirty = 0x01, + eNeedNewBuffer = 0x02 }; - uint16_t w; - uint16_t h; - uint16_t stride; - uint16_t bpr; - uint16_t reserved; - uint8_t format; + uint8_t reserved[11]; uint8_t flags; - ssize_t bits_offset; + status_t status; }; // --------------------------------------------------------------------------- @@ -110,8 +106,6 @@ struct per_client_cblk_t // 4KB max INSPECT = 0x00000002 }; - per_client_cblk_t(); - // these functions are used by the clients status_t validate(size_t i) const; int32_t lock_layer(size_t i, uint32_t flags); @@ -138,12 +132,9 @@ struct display_cblk_t struct surface_flinger_cblk_t // 4KB max { - surface_flinger_cblk_t(); - uint8_t connected; uint8_t reserved[3]; uint32_t pad[7]; - display_cblk_t displays[NUM_DISPLAY_MAX]; }; diff --git a/include/ui/BufferMapper.h b/include/ui/BufferMapper.h new file mode 100644 index 0000000000000..8a33b2eab9a57 --- /dev/null +++ b/include/ui/BufferMapper.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2007 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. + */ + +#ifndef ANDROID_UI_BUFFER_MAPPER_H +#define ANDROID_UI_BUFFER_MAPPER_H + +#include +#include +#include +#include + +#include + + +struct gralloc_module_t; + +namespace android { + +// --------------------------------------------------------------------------- + +class Rect; + +class BufferMapper : public Singleton +{ +public: + static inline BufferMapper& get() { return getInstance(); } + status_t map(buffer_handle_t handle, void** addr); + status_t unmap(buffer_handle_t handle); + status_t lock(buffer_handle_t handle, int usage, const Rect& bounds); + status_t unlock(buffer_handle_t handle); + +private: + friend class Singleton; + BufferMapper(); + mutable Mutex mLock; + gralloc_module_t const *mAllocMod; +}; + +// --------------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_UI_BUFFER_MAPPER_H + diff --git a/include/ui/EGLNativeWindowSurface.h b/include/ui/EGLNativeWindowSurface.h index 3494234636042..4b25655cf332b 100644 --- a/include/ui/EGLNativeWindowSurface.h +++ b/include/ui/EGLNativeWindowSurface.h @@ -19,8 +19,17 @@ #include #include -#include + #include +#include + +#include +#include + +#include + + +extern "C" EGLNativeWindowType android_createDisplaySurface(void); // --------------------------------------------------------------------------- namespace android { @@ -28,27 +37,84 @@ namespace android { class Surface; -class EGLNativeWindowSurface : public EGLNativeSurface + +class NativeBuffer + : public EGLNativeBase< + android_native_buffer_t, + NativeBuffer, + LightRefBase > { public: - EGLNativeWindowSurface(const sp& surface); - ~EGLNativeWindowSurface(); + NativeBuffer(int w, int h, int f, int u) : BASE() { + android_native_buffer_t::width = w; + android_native_buffer_t::height = h; + android_native_buffer_t::format = f; + android_native_buffer_t::usage = u; + android_native_buffer_t::getHandle = getHandle; + } +public: + buffer_handle_t handle; +private: + friend class LightRefBase; + ~NativeBuffer() { }; // this class cannot be overloaded + static int getHandle(android_native_buffer_t const * base, buffer_handle_t* handle) { + *handle = getSelf(base)->handle; + return 0; + } +}; - void setSwapRectangle(int l, int t, int w, int h); +// --------------------------------------------------------------------------- + +class FramebufferNativeWindow + : public EGLNativeBase< + android_native_window_t, + FramebufferNativeWindow, + LightRefBase > +{ +public: + FramebufferNativeWindow(); + + framebuffer_device_t const * getDevice() const { return fbDev; } private: - static void hook_incRef(NativeWindowType window); - static void hook_decRef(NativeWindowType window); - static uint32_t hook_swapBuffers(NativeWindowType window); - static void hook_connect(NativeWindowType window); - static void hook_disconnect(NativeWindowType window); + friend class LightRefBase; + ~FramebufferNativeWindow(); // this class cannot be overloaded + static void connect(android_native_window_t* window); + static void disconnect(android_native_window_t* window); + static int setSwapInterval(android_native_window_t* window, int interval); + static int setSwapRectangle(android_native_window_t* window, + int l, int t, int w, int h); + static int dequeueBuffer(android_native_window_t* window, android_native_buffer_t** buffer); + static int lockBuffer(android_native_window_t* window, android_native_buffer_t* buffer); + static int queueBuffer(android_native_window_t* window, android_native_buffer_t* buffer); + - uint32_t swapBuffers(); - void connect(); - void disconnect(); - - sp mSurface; - bool mConnected; + static inline FramebufferNativeWindow* getSelf( + android_native_window_t* window) { + FramebufferNativeWindow* self = + static_cast(window); + return self; + } + + static inline FramebufferNativeWindow* getSelf( + android_native_base_t* window) { + return getSelf(reinterpret_cast(window)); + } + + + framebuffer_device_t* fbDev; + alloc_device_t* grDev; + + sp buffers[2]; + sp front; + + Rect mDirty; + + mutable Mutex mutex; + Condition mCondition; + int32_t mNumBuffers; + int32_t mNumFreeBuffers; + int32_t mBufferHead; }; // --------------------------------------------------------------------------- diff --git a/include/ui/ISurface.h b/include/ui/ISurface.h index 87b320f431b88..1a788720dbcd4 100644 --- a/include/ui/ISurface.h +++ b/include/ui/ISurface.h @@ -20,12 +20,15 @@ #include #include +#include + #include #include #include #include #include +#include namespace android { @@ -33,6 +36,7 @@ typedef int32_t SurfaceID; class IMemoryHeap; class OverlayRef; +class SurfaceBuffer; class ISurface : public IInterface { @@ -42,11 +46,13 @@ protected: UNREGISTER_BUFFERS, POST_BUFFER, // one-way transaction CREATE_OVERLAY, + GET_BUFFER, }; public: DECLARE_META_INTERFACE(Surface); + virtual sp getBuffer() = 0; class BufferHeap { public: @@ -78,9 +84,7 @@ public: }; virtual status_t registerBuffers(const BufferHeap& buffers) = 0; - virtual void postBuffer(ssize_t offset) = 0; // one-way - virtual void unregisterBuffers() = 0; virtual sp createOverlay( diff --git a/include/ui/ISurfaceComposer.h b/include/ui/ISurfaceComposer.h index 5c64b222bc5d4..fd5a473ff48ac 100644 --- a/include/ui/ISurfaceComposer.h +++ b/include/ui/ISurfaceComposer.h @@ -32,7 +32,6 @@ namespace android { // ---------------------------------------------------------------------------- class DisplayInfo; -class IGPUCallback; class ISurfaceComposer : public IInterface { @@ -112,37 +111,12 @@ public: */ virtual void bootFinished() = 0; - /* get access to the GPU. Access is relinquished when releasing regs */ - struct gpu_info_t { - struct gpu_region_t { - sp region; - size_t reserved; - }; - sp regs; - size_t count; - gpu_region_t regions[2]; - }; - virtual status_t requestGPU( - const sp& callback, - gpu_info_t* gpu) = 0; - - /* take the gpu back from any apps using it. They'll get a - * EGL_CONTEXT_LOST error */ - virtual status_t revokeGPU() = 0; - /* Signal surfaceflinger that there might be some work to do * This is an ASYNCHRONOUS call. */ virtual void signal() const = 0; }; -class IGPUCallback : public IInterface -{ -public: - DECLARE_META_INTERFACE(GPUCallback); - virtual void gpuLost() = 0; //one-way -}; - // ---------------------------------------------------------------------------- class BnSurfaceComposer : public BnInterface @@ -159,8 +133,6 @@ public: SET_ORIENTATION, FREEZE_DISPLAY, UNFREEZE_DISPLAY, - REQUEST_GPU, - REVOKE_GPU, SIGNAL }; @@ -170,15 +142,6 @@ public: uint32_t flags = 0); }; -class BnGPUCallback : public BnInterface -{ -public: - virtual status_t onTransact( uint32_t code, - const Parcel& data, - Parcel* reply, - uint32_t flags = 0); -}; - // ---------------------------------------------------------------------------- }; // namespace android diff --git a/include/ui/ISurfaceFlingerClient.h b/include/ui/ISurfaceFlingerClient.h index 5b9361d5d6364..8515e2e526d5a 100644 --- a/include/ui/ISurfaceFlingerClient.h +++ b/include/ui/ISurfaceFlingerClient.h @@ -52,7 +52,6 @@ public: struct surface_data_t { int32_t token; int32_t identity; - sp heap[2]; status_t readFromParcel(const Parcel& parcel); status_t writeToParcel(Parcel* parcel) const; }; diff --git a/include/ui/PixelFormat.h b/include/ui/PixelFormat.h index 14af8232bb15c..6d87321bb4eee 100644 --- a/include/ui/PixelFormat.h +++ b/include/ui/PixelFormat.h @@ -84,6 +84,13 @@ typedef int32_t PixelFormat; struct PixelFormatInfo { + enum { + INDEX_ALPHA = 0, + INDEX_RED = 1, + INDEX_GREEN = 2, + INDEX_BLUE = 3 + }; + enum { // components ALPHA = 1, RGB = 2, @@ -95,20 +102,33 @@ struct PixelFormatInfo Y_CB_CR_I = 8, }; + struct szinfo { + uint8_t h; + uint8_t l; + }; + inline PixelFormatInfo() : version(sizeof(PixelFormatInfo)) { } size_t getScanlineSize(unsigned int width) const; + size_t getSize(size_t ci) const { + return (ci <= 3) ? (cinfo[ci].h - cinfo[ci].l) : 0; + } size_t version; PixelFormat format; size_t bytesPerPixel; size_t bitsPerPixel; - uint8_t h_alpha; - uint8_t l_alpha; - uint8_t h_red; - uint8_t l_red; - uint8_t h_green; - uint8_t l_green; - uint8_t h_blue; - uint8_t l_blue; + union { + szinfo cinfo[4]; + struct { + uint8_t h_alpha; + uint8_t l_alpha; + uint8_t h_red; + uint8_t l_red; + uint8_t h_green; + uint8_t l_green; + uint8_t h_blue; + uint8_t l_blue; + }; + }; uint8_t components; uint8_t reserved0[3]; uint32_t reserved1; diff --git a/include/ui/Surface.h b/include/ui/Surface.h index 33953a95339a8..d92da4919e63b 100644 --- a/include/ui/Surface.h +++ b/include/ui/Surface.h @@ -28,24 +28,65 @@ #include #include +#include + namespace android { // --------------------------------------------------------------------------- class Rect; class SurfaceComposerClient; +struct per_client_cblk_t; +struct layer_cblk_t; -class Surface : public RefBase +// --------------------------------------------------------------------------- + +class SurfaceBuffer + : public EGLNativeBase< + android_native_buffer_t, + SurfaceBuffer, + LightRefBase > { +public: + buffer_handle_t getHandle() const { + return handle; + } + +protected: + SurfaceBuffer(); + SurfaceBuffer(const Parcel& reply); + virtual ~SurfaceBuffer(); + buffer_handle_t handle; + bool mOwner; +private: + friend class BpSurface; + friend class BnSurface; + friend class LightRefBase; + + SurfaceBuffer& operator = (const SurfaceBuffer& rhs); + const SurfaceBuffer& operator = (const SurfaceBuffer& rhs) const; + + static status_t writeToParcel(Parcel* reply, + android_native_buffer_t const* buffer); + + static int getHandle(android_native_buffer_t const * base, + buffer_handle_t* handle); +}; + +// --------------------------------------------------------------------------- + +class Surface + : public EGLNativeBase +{ public: struct SurfaceInfo { uint32_t w; uint32_t h; - uint32_t bpr; + uint32_t s; + uint32_t usage; PixelFormat format; void* bits; - void* base; uint32_t reserved[2]; }; @@ -55,15 +96,12 @@ public: status_t lock(SurfaceInfo* info, bool blocking = true); status_t lock(SurfaceInfo* info, Region* dirty, bool blocking = true); status_t unlockAndPost(); - status_t unlock(); - - void* heapBase(int i) const; + uint32_t getFlags() const { return mFlags; } // setSwapRectangle() is mainly used by EGL void setSwapRectangle(const Rect& r); const Rect& swapRectangle() const; - status_t nextBuffer(SurfaceInfo* info); sp dup() const; static sp readFromParcel(Parcel* parcel); @@ -95,6 +133,8 @@ private: friend class Test; const sp& getISurface() const { return mSurface; } + status_t getBufferLocked(int index); + // can't be copied Surface& operator = (Surface& rhs); Surface(const Surface& rhs); @@ -108,23 +148,39 @@ private: Surface(Surface const* rhs); ~Surface(); - + Region dirtyRegion() const; void setDirtyRegion(const Region& region) const; - // this locks protects calls to lockSurface() / unlockSurface() - // and is called by SurfaceComposerClient. - Mutex& getLock() const { return mSurfaceLock; } + + status_t validate(per_client_cblk_t const* cblk) const; + static void _send_dirty_region(layer_cblk_t* lcblk, const Region& dirty); + + static void connect(android_native_window_t* window); + static void disconnect(android_native_window_t* window); + static int setSwapInterval(android_native_window_t* window, int interval); + static int setSwapRectangle(android_native_window_t* window, + int l, int t, int w, int h); + static int dequeueBuffer(android_native_window_t* window, android_native_buffer_t** buffer); + static int lockBuffer(android_native_window_t* window, android_native_buffer_t* buffer); + static int queueBuffer(android_native_window_t* window, android_native_buffer_t* buffer); + + int dequeueBuffer(android_native_buffer_t** buffer); + int lockBuffer(android_native_buffer_t* buffer); + int queueBuffer(android_native_buffer_t* buffer); + + + alloc_device_t* mAllocDevice; sp mClient; sp mSurface; - sp mHeap[2]; + sp mBuffers[2]; + android_native_buffer_t* mLockedBuffer; SurfaceID mToken; uint32_t mIdentity; PixelFormat mFormat; uint32_t mFlags; const bool mOwner; - mutable void* mSurfaceHeapBase[2]; mutable Region mDirtyRegion; mutable Rect mSwapRectangle; mutable uint8_t mBackbufferIndex; diff --git a/include/ui/SurfaceComposerClient.h b/include/ui/SurfaceComposerClient.h index 76a3b554ba736..86de6ea343935 100644 --- a/include/ui/SurfaceComposerClient.h +++ b/include/ui/SurfaceComposerClient.h @@ -128,34 +128,17 @@ private: status_t setPosition(Surface* surface, int32_t x, int32_t y); status_t setSize(Surface* surface, uint32_t w, uint32_t h); - //! Unlock the surface, and specify the dirty region if any - status_t unlockAndPostSurface(Surface* surface); - status_t unlockSurface(Surface* surface); - - status_t lockSurface(Surface* surface, - Surface::SurfaceInfo* info, - Region* dirty, - bool blocking = true); - - status_t nextBuffer(Surface* surface, - Surface::SurfaceInfo* info); + void signalServer(); status_t destroySurface(SurfaceID sid); void _init(const sp& sm, const sp& conn); - void _signal_server(); - static void _send_dirty_region(layer_cblk_t* lcblk, const Region& dirty); inline layer_state_t* _get_state_l(const sp& surface); layer_state_t* _lockLayerState(const sp& surface); inline void _unlockLayerState(); - status_t validateSurface( - per_client_cblk_t const* cblk, Surface const * surface); - - void pinHeap(const sp& heap); - mutable Mutex mLock; layer_state_t* mPrebuiltLayerState; SortedVector mStates; @@ -167,9 +150,6 @@ private: per_client_cblk_t* mControl; sp mControlMemory; sp mClient; - sp mSurfaceHeap; - uint8_t* mSurfaceHeapBase; - void* mGL; SurfaceFlingerSynchro* mSignalServer; }; diff --git a/include/utils/Parcel.h b/include/utils/Parcel.h index 9087c4465b962..af1490a02973e 100644 --- a/include/utils/Parcel.h +++ b/include/utils/Parcel.h @@ -80,8 +80,11 @@ public: status_t writeStrongBinder(const sp& val); status_t writeWeakBinder(const wp& val); - // doesn't take ownership of the native_handle - status_t writeNativeHandle(const native_handle& handle); + // Place a native_handle into the parcel (the native_handle's file- + // descriptors are dup'ed, so it is safe to delete the native_handle + // when this function returns). + // Doesn't take ownership of the native_handle. + status_t writeNativeHandle(const native_handle* handle); // Place a file descriptor into the parcel. The given fd must remain // valid for the lifetime of the parcel. @@ -114,12 +117,11 @@ public: wp readWeakBinder() const; - // if alloc is NULL, native_handle is allocated with malloc(), otherwise - // alloc is used. If the function fails, the effects of alloc() must be - // reverted by the caller. - native_handle* readNativeHandle( - native_handle* (*alloc)(void* cookie, int numFds, int ints), - void* cookie) const; + // Retrieve native_handle from the parcel. This returns a copy of the + // parcel's native_handle (the caller takes ownership). The caller + // must free the native_handle with native_handle_close() and + // native_handle_delete(). + native_handle* readNativeHandle() const; // Retrieve a file descriptor from the parcel. This returns the raw fd diff --git a/include/utils/Singleton.h b/include/utils/Singleton.h new file mode 100644 index 0000000000000..776f93bb7535c --- /dev/null +++ b/include/utils/Singleton.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2007 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. + */ + +#ifndef ANDROID_UTILS_SINGLETON_H +#define ANDROID_UTILS_SINGLETON_H + +#include +#include +#include + +namespace android { +// --------------------------------------------------------------------------- + +template +class Singleton +{ +public: + static TYPE& getInstance() { + Mutex::Autolock _l(sLock); + TYPE* instance = sInstance; + if (instance == 0) { + instance = new TYPE(); + sInstance = instance; + } + return *instance; + } + +protected: + ~Singleton() { }; + Singleton() { }; + +private: + Singleton(const Singleton&); + Singleton& operator = (const Singleton&); + static Mutex sLock; + static TYPE* sInstance; +}; + +template Mutex Singleton::sLock; +template TYPE* Singleton::sInstance(0); + +// --------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_UTILS_SINGLETON_H + diff --git a/libs/surfaceflinger/Android.mk b/libs/surfaceflinger/Android.mk index 22124361ab3f6..ebd588b3e6aa4 100644 --- a/libs/surfaceflinger/Android.mk +++ b/libs/surfaceflinger/Android.mk @@ -5,9 +5,9 @@ LOCAL_SRC_FILES:= \ clz.cpp.arm \ DisplayHardware/DisplayHardware.cpp \ DisplayHardware/DisplayHardwareBase.cpp \ - GPUHardware/GPUHardware.cpp \ BootAnimation.cpp \ BlurFilter.cpp.arm \ + BufferAllocator.cpp \ CPUGauge.cpp \ Layer.cpp \ LayerBase.cpp \ @@ -20,9 +20,10 @@ LOCAL_SRC_FILES:= \ OrientationAnimation.cpp \ SurfaceFlinger.cpp \ Tokenizer.cpp \ - Transform.cpp \ - VRamHeap.cpp + Transform.cpp +LOCAL_CFLAGS:= -DLOG_TAG=\"SurfaceFlinger\" +LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES # need "-lrt" on Linux simulator to pick up clock_gettime ifeq ($(TARGET_SIMULATOR),true) diff --git a/libs/surfaceflinger/BootAnimation.cpp b/libs/surfaceflinger/BootAnimation.cpp index db403857323a4..4aa8c2c346a9f 100644 --- a/libs/surfaceflinger/BootAnimation.cpp +++ b/libs/surfaceflinger/BootAnimation.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "BootAnimation" - #include #include #include @@ -147,9 +145,7 @@ status_t BootAnimation::readyToRun() { EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); eglChooseConfig(display, attribs, &config, 1, &numConfigs); - mNativeWindowSurface = new EGLNativeWindowSurface(s); - surface = eglCreateWindowSurface(display, config, - mNativeWindowSurface.get(), NULL); + surface = eglCreateWindowSurface(display, config, s.get(), NULL); context = eglCreateContext(display, config, NULL, NULL); eglQuerySurface(display, surface, EGL_WIDTH, &w); @@ -180,7 +176,7 @@ bool BootAnimation::threadLoop() { eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroyContext(mDisplay, mContext); eglDestroySurface(mDisplay, mSurface); - mNativeWindowSurface.clear(); + mFlingerSurface.clear(); return r; } @@ -199,8 +195,7 @@ bool BootAnimation::android() { const Rect updateRect(xc, yc, xc + mAndroid[0].w, yc + mAndroid[0].h); // draw and update only what we need - mNativeWindowSurface->setSwapRectangle(updateRect.left, - updateRect.top, updateRect.width(), updateRect.height()); + mFlingerSurface->setSwapRectangle(updateRect); glEnable(GL_SCISSOR_TEST); glScissor(updateRect.left, mHeight - updateRect.bottom, updateRect.width(), diff --git a/libs/surfaceflinger/BootAnimation.h b/libs/surfaceflinger/BootAnimation.h index 3fb6670b3ef45..84846238bc5c7 100644 --- a/libs/surfaceflinger/BootAnimation.h +++ b/libs/surfaceflinger/BootAnimation.h @@ -72,7 +72,6 @@ private: EGLDisplay mContext; EGLDisplay mSurface; sp mFlingerSurface; - sp mNativeWindowSurface; Barrier mBarrier; }; diff --git a/libs/surfaceflinger/BufferAllocator.cpp b/libs/surfaceflinger/BufferAllocator.cpp new file mode 100644 index 0000000000000..ac32985890ac8 --- /dev/null +++ b/libs/surfaceflinger/BufferAllocator.cpp @@ -0,0 +1,162 @@ +/* +** +** Copyright 2009, 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. +*/ + +#include +#include +#include +#include +#include + +#include + +#include "BufferAllocator.h" + +// FIXME: ANDROID_GRALLOC_DEBUG must only be used with *our* gralloc +#define ANDROID_GRALLOC_DEBUG 1 + + +namespace android { +// --------------------------------------------------------------------------- + +Mutex BufferAllocator::sLock; +KeyedVector BufferAllocator::sAllocList; + +BufferAllocator::BufferAllocator() + : mAllocDev(0) +{ + hw_module_t const* module; + int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module); + LOGE_IF(err, "FATAL: can't find the %s module", GRALLOC_HARDWARE_MODULE_ID); + if (err == 0) { + gralloc_open(module, &mAllocDev); + } +} + +BufferAllocator::~BufferAllocator() +{ + gralloc_close(mAllocDev); +} + +void BufferAllocator::dump(String8& result) const +{ + Mutex::Autolock _l(sLock); + KeyedVector& list(sAllocList); + size_t total = 0; + const size_t SIZE = 512; + char buffer[SIZE]; + snprintf(buffer, SIZE, "Allocated buffers:\n"); + result.append(buffer); + const size_t c = list.size(); + for (size_t i=0 ; ialloc(mAllocDev, + w, h, format, usage, handle, stride); + LOGW_IF(err, "alloc(%u, %u, %d, %08x, ...) failed %d (%s)", + w, h, format, usage, err, strerror(-err)); + + if (err == NO_ERROR) { + Mutex::Autolock _l(sLock); + KeyedVector& list(sAllocList); + alloc_rec_t rec; + rec.w = w; + rec.h = h; + rec.format = format; + rec.usage = usage; + rec.vaddr = 0; + rec.size = h * stride[0] * bytesPerPixel(format); + list.add(*handle, rec); + } + + return err; +} + +status_t BufferAllocator::free(buffer_handle_t handle) +{ + Mutex::Autolock _l(mLock); + +#if ANDROID_GRALLOC_DEBUG + if (handle->data[2]) { + CallStack s; + s.update(); + s.dump(""); + } +#endif + + status_t err = mAllocDev->free(mAllocDev, handle); + LOGW_IF(err, "free(...) failed %d (%s)", err, strerror(-err)); + + if (err == NO_ERROR) { + Mutex::Autolock _l(sLock); + KeyedVector& list(sAllocList); + list.removeItem(handle); + } + + return err; +} + +status_t BufferAllocator::map(buffer_handle_t handle, void** addr) +{ + Mutex::Autolock _l(mLock); + status_t err = BufferMapper::get().map(handle, addr); + if (err == NO_ERROR) { + Mutex::Autolock _l(sLock); + KeyedVector& list(sAllocList); + ssize_t idx = list.indexOfKey(handle); + if (idx >= 0) + list.editValueAt(idx).vaddr = addr; + } + + return err; +} + +status_t BufferAllocator::unmap(buffer_handle_t handle) +{ + Mutex::Autolock _l(mLock); + gralloc_module_t* mod = (gralloc_module_t*)mAllocDev->common.module; + status_t err = mod->unmap(mod, handle); + LOGW_IF(err, "unmap(...) failed %d (%s)", err, strerror(-err)); + + if (err == NO_ERROR) { + Mutex::Autolock _l(sLock); + KeyedVector& list(sAllocList); + ssize_t idx = list.indexOfKey(handle); + if (idx >= 0) + list.editValueAt(idx).vaddr = 0; + } + + return err; +} + + +// --------------------------------------------------------------------------- +}; // namespace android diff --git a/libs/surfaceflinger/BufferAllocator.h b/libs/surfaceflinger/BufferAllocator.h new file mode 100644 index 0000000000000..0b69b8ecd46f7 --- /dev/null +++ b/libs/surfaceflinger/BufferAllocator.h @@ -0,0 +1,100 @@ +/* +** +** Copyright 2009, 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. +*/ + +#ifndef ANDROID_BUFFER_ALLOCATOR_H +#define ANDROID_BUFFER_ALLOCATOR_H + +#include + +#include + +#include +#include +#include +#include + +#include + +#include + + +namespace android { +// --------------------------------------------------------------------------- + +class String8; + +class BufferAllocator : public Singleton +{ +public: + enum { + USAGE_SW_READ_NEVER = GRALLOC_USAGE_SW_READ_NEVER, + USAGE_SW_READ_RARELY = GRALLOC_USAGE_SW_READ_RARELY, + USAGE_SW_READ_OFTEN = GRALLOC_USAGE_SW_READ_OFTEN, + USAGE_SW_READ_MASK = GRALLOC_USAGE_SW_READ_MASK, + + USAGE_SW_WRITE_NEVER = GRALLOC_USAGE_SW_WRITE_NEVER, + USAGE_SW_WRITE_RARELY = GRALLOC_USAGE_SW_WRITE_RARELY, + USAGE_SW_WRITE_OFTEN = GRALLOC_USAGE_SW_WRITE_OFTEN, + USAGE_SW_WRITE_MASK = GRALLOC_USAGE_SW_WRITE_MASK, + + USAGE_SOFTWARE_MASK = USAGE_SW_READ_MASK|USAGE_SW_WRITE_MASK, + + USAGE_HW_TEXTURE = GRALLOC_USAGE_HW_TEXTURE, + USAGE_HW_RENDER = GRALLOC_USAGE_HW_RENDER, + USAGE_HW_2D = GRALLOC_USAGE_HW_2D, + USAGE_HW_MASK = GRALLOC_USAGE_HW_MASK + }; + + static inline BufferAllocator& get() { return getInstance(); } + + + status_t alloc(uint32_t w, uint32_t h, PixelFormat format, int usage, + buffer_handle_t* handle, int32_t* stride); + + status_t free(buffer_handle_t handle); + + status_t map(buffer_handle_t handle, void** addr); + + status_t unmap(buffer_handle_t handle); + + void dump(String8& res) const; + +private: + struct alloc_rec_t { + uint32_t w; + uint32_t h; + PixelFormat format; + uint32_t usage; + void* vaddr; + size_t size; + }; + + static Mutex sLock; + static KeyedVector sAllocList; + + friend class Singleton; + BufferAllocator(); + ~BufferAllocator(); + + mutable Mutex mLock; + alloc_device_t *mAllocDev; +}; + +// --------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_BUFFER_ALLOCATOR_H diff --git a/libs/surfaceflinger/CPUGauge.cpp b/libs/surfaceflinger/CPUGauge.cpp index 74a9270b5e9a5..91dd2362583c3 100644 --- a/libs/surfaceflinger/CPUGauge.cpp +++ b/libs/surfaceflinger/CPUGauge.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "CPUGauge" - #include #include #include @@ -113,7 +111,7 @@ bool CPUGauge::threadLoop() fb.version = sizeof(GGLSurface); fb.width = info.w; fb.height = info.h; - fb.stride = info.w; + fb.stride = info.s; fb.format = info.format; fb.data = (GGLubyte*)info.bits; diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp index f14d7e99c2d3b..1f7211cc13ca2 100644 --- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp +++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "SurfaceFlinger" - #include #include #include @@ -23,18 +21,24 @@ #include +#include #include -#include +#include +#include #include +#include #include +#include +#include #include "DisplayHardware/DisplayHardware.h" #include #include +#include using namespace android; @@ -108,17 +112,28 @@ PixelFormat DisplayHardware::getFormat() const { return mFormat; } void DisplayHardware::init(uint32_t dpy) { + hw_module_t const* module; + + mNativeWindow = new FramebufferNativeWindow(); + + mOverlayEngine = NULL; + if (hw_get_module(OVERLAY_HARDWARE_MODULE_ID, &module) == 0) { + overlay_control_open(module, &mOverlayEngine); + } + + framebuffer_device_t const * fbDev = mNativeWindow->getDevice(); + + PixelFormatInfo fbFormatInfo; + getPixelFormatInfo(PixelFormat(fbDev->format), &fbFormatInfo); + // initialize EGL const EGLint attribs[] = { - EGL_RED_SIZE, 5, - EGL_GREEN_SIZE, 6, - EGL_BLUE_SIZE, 5, + EGL_BUFFER_SIZE, fbFormatInfo.bitsPerPixel, EGL_DEPTH_SIZE, 0, EGL_NONE }; EGLint w, h, dummy; - EGLint numConfigs, n; - EGLConfig config; + EGLint numConfigs=0, n=0; EGLSurface surface; EGLContext context; mFlags = 0; @@ -129,7 +144,31 @@ void DisplayHardware::init(uint32_t dpy) EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); eglInitialize(display, NULL, NULL); eglGetConfigs(display, NULL, 0, &numConfigs); - eglChooseConfig(display, attribs, &config, 1, &n); + + // Get all the "potential match" configs... + EGLConfig* const configs = new EGLConfig[numConfigs]; + eglChooseConfig(display, attribs, configs, numConfigs, &n); + LOGE_IF(n<=0, "no EGLConfig available!"); + EGLConfig config = configs[0]; + if (n > 1) { + // if there is more than one candidate, go through the list + // and pick one that matches our framebuffer format + int fbSzA = fbFormatInfo.getSize(PixelFormatInfo::INDEX_ALPHA); + int fbSzR = fbFormatInfo.getSize(PixelFormatInfo::INDEX_RED); + int fbSzG = fbFormatInfo.getSize(PixelFormatInfo::INDEX_GREEN); + int fbSzB = fbFormatInfo.getSize(PixelFormatInfo::INDEX_BLUE); + for (int i=0 ; ixdpi; + mDpiX = mNativeWindow->ydpi; + mRefreshRate = mNativeWindow->getDevice()->fps; char property[PROPERTY_VALUE_MAX]; if (property_get("ro.sf.lcd_density", property, NULL) <= 0) { @@ -225,7 +248,10 @@ void DisplayHardware::init(uint32_t dpy) if (strstr(gl_extensions, "GL_OES_draw_texture")) { mFlags |= DRAW_TEXTURE_EXTENSION; } - if (strstr(gl_extensions, "GL_ANDROID_direct_texture")) { + if (strstr( gl_extensions, "GL_OES_EGL_image") && + (strstr(egl_extensions, "KHR_image_base") || + strstr(egl_extensions, "EGL_KHR_image")) && + strstr(egl_extensions, "EGL_ANDROID_image_native_buffer")) { mFlags |= DIRECT_TEXTURE; } @@ -236,19 +262,8 @@ void DisplayHardware::init(uint32_t dpy) mConfig = config; mSurface = surface; mContext = context; - mFormat = GGL_PIXEL_FORMAT_RGB_565; - - hw_module_t const* module; - - mBlitEngine = NULL; - if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) { - copybit_open(module, &mBlitEngine); - } - - mOverlayEngine = NULL; - if (hw_get_module(OVERLAY_HARDWARE_MODULE_ID, &module) == 0) { - overlay_control_open(module, &mOverlayEngine); - } + mFormat = fbDev->format; + mPageFlipCount = 0; } /* @@ -262,7 +277,6 @@ void DisplayHardware::fini() { eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglTerminate(mDisplay); - copybit_close(mBlitEngine); overlay_control_close(mOverlayEngine); } @@ -276,28 +290,8 @@ void DisplayHardware::acquireScreen() const DisplayHardwareBase::acquireScreen(); } -void DisplayHardware::getDisplaySurface(copybit_image_t* img) const -{ - img->w = mDisplaySurface->stride; - img->h = mDisplaySurface->height; - img->format = mDisplaySurface->format; - img->offset = mDisplaySurface->offset; - img->base = (void*)mDisplaySurface->base; - img->fd = mDisplaySurface->fd; -} - -void DisplayHardware::getDisplaySurface(GGLSurface* fb) const -{ - fb->version= sizeof(GGLSurface); - fb->width = mDisplaySurface->width; - fb->height = mDisplaySurface->height; - fb->stride = mDisplaySurface->stride; - fb->format = mDisplaySurface->format; - fb->data = (GGLubyte*)mDisplaySurface->base + mDisplaySurface->offset; -} - uint32_t DisplayHardware::getPageFlipCount() const { - return mDisplaySurface->getPageFlipCount(); + return mPageFlipCount; } /* @@ -315,17 +309,14 @@ void DisplayHardware::flip(const Region& dirty) const newDirty.andSelf(Rect(mWidth, mHeight)); if (mFlags & BUFFER_PRESERVED) { - const Region copyback(mDirty.subtract(newDirty)); mDirty = newDirty; - mDisplaySurface->copyFrontToBack(copyback); } - if (mFlags & SWAP_RECTANGLE_EXTENSION) { - const Rect& b(newDirty.bounds()); - mDisplaySurface->setSwapRectangle( - b.left, b.top, b.width(), b.height()); - } + const Rect& b(newDirty.bounds()); + mNativeWindow->android_native_window_t::setSwapRectangle( + mNativeWindow.get(), b.left, b.top, b.width(), b.height()); + mPageFlipCount++; eglSwapBuffers(dpy, surface); checkEGLErrors("eglSwapBuffers"); @@ -345,9 +336,9 @@ void DisplayHardware::makeCurrent() const } void DisplayHardware::copyFrontToImage(const copybit_image_t& front) const { - mDisplaySurface->copyFrontToImage(front); + // FIXME: we need to get rid of this } void DisplayHardware::copyBackToImage(const copybit_image_t& front) const { - mDisplaySurface->copyBackToImage(front); + // FIXME: we need to get rid of this } diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h index 550a4d12702c9..97a68a53b424e 100644 --- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h +++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h @@ -22,25 +22,28 @@ #include #include +#include +#include #include +#include + +#include #include "DisplayHardware/DisplayHardwareBase.h" struct overlay_control_device_t; -struct copybit_device_t; +struct framebuffer_device_t; struct copybit_image_t; -struct copybit_t; namespace android { -class EGLDisplaySurface; +class FramebufferNativeWindow; class DisplayHardware : public DisplayHardwareBase { public: enum { DIRECT_TEXTURE = 0x00000002, - SWAP_RECTANGLE_EXTENSION= 0x00000004, COPY_BITS_EXTENSION = 0x00000008, NPOT_EXTENSION = 0x00000100, DRAW_TEXTURE_EXTENSION = 0x00000200, @@ -73,10 +76,7 @@ public: void makeCurrent() const; uint32_t getPageFlipCount() const; - void getDisplaySurface(copybit_image_t* img) const; - void getDisplaySurface(GGLSurface* fb) const; EGLDisplay getEGLDisplay() const { return mDisplay; } - copybit_device_t* getBlitEngine() const { return mBlitEngine; } overlay_control_device_t* getOverlayEngine() const { return mOverlayEngine; } void copyFrontToImage(const copybit_image_t& front) const; @@ -103,8 +103,9 @@ private: PixelFormat mFormat; uint32_t mFlags; mutable Region mDirty; - sp mDisplaySurface; - copybit_device_t* mBlitEngine; + mutable uint32_t mPageFlipCount; + + sp mNativeWindow; overlay_control_device_t* mOverlayEngine; }; diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp index f75e5c229ddd4..1d09f84dca840 100644 --- a/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp +++ b/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "SurfaceFlinger" - #include #include #include diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp index f65d66984d7f5..980b78b7a7679 100644 --- a/libs/surfaceflinger/Layer.cpp +++ b/libs/surfaceflinger/Layer.cpp @@ -14,26 +14,25 @@ * limitations under the License. */ -#define LOG_TAG "SurfaceFlinger" - #include #include #include #include +#include #include #include #include +#include #include -#include +#include #include "clz.h" #include "Layer.h" #include "LayerBitmap.h" #include "SurfaceFlinger.h" -#include "VRamHeap.h" #include "DisplayHardware/DisplayHardware.h" @@ -54,8 +53,7 @@ Layer::Layer(SurfaceFlinger* flinger, DisplayID display, Client* c, int32_t i) mSecure(false), mFrontBufferIndex(1), mNeedsBlending(true), - mResizeTransactionDone(false), - mTextureName(-1U), mTextureWidth(0), mTextureHeight(0) + mResizeTransactionDone(false) { // no OpenGL operation is possible here, since we might not be // in the OpenGL thread. @@ -63,11 +61,16 @@ Layer::Layer(SurfaceFlinger* flinger, DisplayID display, Client* c, int32_t i) Layer::~Layer() { - client->free(clientIndex()); - // this should always be called from the OpenGL thread - if (mTextureName != -1U) { - //glDeleteTextures(1, &mTextureName); - deletedTextures.add(mTextureName); + for (int i=0 ; igraphicPlane(0).getEGLDisplay()); + eglDestroyImageKHR(dpy, mTextures[i].image); + } } } @@ -79,7 +82,7 @@ void Layer::initStates(uint32_t w, uint32_t h, uint32_t flags) lcblk->flags |= eNoCopyBack; } -sp Layer::getSurface() const +sp Layer::createSurface() const { return mSurface; } @@ -92,25 +95,15 @@ status_t Layer::setBuffers( Client* client, status_t err = getPixelFormatInfo(format, &info); if (err) return err; - // TODO: if eHardware is explicitly requested, we should fail - // on systems where we can't allocate memory that can be used with - // DMA engines for instance. - - // FIXME: we always ask for hardware for now (this should come from copybit) - flags |= ISurfaceComposer::eHardware; + uint32_t bufferFlags = 0; + if (flags & ISurfaceComposer::eGPU) + bufferFlags |= Buffer::GPU; - const uint32_t memory_flags = flags & - (ISurfaceComposer::eGPU | - ISurfaceComposer::eHardware | - ISurfaceComposer::eSecure); - - // pixel-alignment. the final alignment may be bigger because - // we always force a 4-byte aligned bpr. - uint32_t alignment = 1; + if (flags & ISurfaceComposer::eSecure) + bufferFlags |= Buffer::SECURE; - if (flags & ISurfaceComposer::eGPU) { - // FIXME: this value should come from the h/w - alignment = 8; + + if (bufferFlags & Buffer::GPU) { // FIXME: this is msm7201A specific, as its GPU only supports // BGRA_8888. if (format == PIXEL_FORMAT_RGBA_8888) { @@ -118,45 +111,94 @@ status_t Layer::setBuffers( Client* client, } } - mSecure = (flags & ISurfaceComposer::eSecure) ? true : false; + mSecure = (bufferFlags & Buffer::SECURE) ? true : false; mNeedsBlending = (info.h_alpha - info.l_alpha) > 0; - sp allocators[2]; for (int i=0 ; i<2 ; i++) { - allocators[i] = client->createAllocator(memory_flags); - if (allocators[i] == 0) - return NO_MEMORY; - mBuffers[i].init(allocators[i]); - int err = mBuffers[i].setBits(w, h, alignment, format, LayerBitmap::SECURE_BITS); - if (err != NO_ERROR) + err = mBuffers[i].init(lcblk->surface + i, w, h, format, bufferFlags); + if (err != NO_ERROR) { return err; - mBuffers[i].clear(); // clear the bits for security - mBuffers[i].getInfo(lcblk->surface + i); + } } - - mSurface = new Surface(clientIndex(), - allocators[0]->getMemoryHeap(), - allocators[1]->getMemoryHeap(), - mIdentity); - + mSurface = new SurfaceLayer(clientIndex(), this); return NO_ERROR; } void Layer::reloadTexture(const Region& dirty) { - if (UNLIKELY(mTextureName == -1U)) { - // create the texture name the first time - // can't do that in the ctor, because it runs in another thread. - mTextureName = createTexture(); + const sp& buffer(frontBuffer().getBuffer()); + if (LIKELY(mFlags & DisplayHardware::DIRECT_TEXTURE)) { + int index = mFrontBufferIndex; + if (LIKELY(!mTextures[index].dirty)) { + glBindTexture(GL_TEXTURE_2D, mTextures[index].name); + } else { + // we need to recreate the texture + EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay()); + + // create the new texture name if needed + if (UNLIKELY(mTextures[index].name == -1U)) { + mTextures[index].name = createTexture(); + } else { + glBindTexture(GL_TEXTURE_2D, mTextures[index].name); + } + + // free the previous image + if (mTextures[index].image != EGL_NO_IMAGE_KHR) { + eglDestroyImageKHR(dpy, mTextures[index].image); + mTextures[index].image = EGL_NO_IMAGE_KHR; + } + + // construct an EGL_NATIVE_BUFFER_ANDROID + android_native_buffer_t* clientBuf = buffer->getNativeBuffer(); + + // create the new EGLImageKHR + const EGLint attrs[] = { + EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, + EGL_NONE, EGL_NONE + }; + mTextures[index].image = eglCreateImageKHR( + dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, + (EGLClientBuffer)clientBuf, attrs); + + LOGE_IF(mTextures[index].image == EGL_NO_IMAGE_KHR, + "eglCreateImageKHR() failed. err=0x%4x", + eglGetError()); + + if (mTextures[index].image != EGL_NO_IMAGE_KHR) { + glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, + (GLeglImageOES)mTextures[index].image); + GLint error = glGetError(); + if (UNLIKELY(error != GL_NO_ERROR)) { + // this failed, for instance, because we don't support + // NPOT. + // FIXME: do something! + mFlags &= ~DisplayHardware::DIRECT_TEXTURE; + } else { + // Everything went okay! + mTextures[index].dirty = false; + } + } + } + } else { + GGLSurface t; + if (LIKELY(buffer->getBitmapSurface(&t) == NO_ERROR)) { + if (UNLIKELY(mTextures[0].name == -1U)) { + mTextures[0].name = createTexture(); + } + loadTexture(dirty, mTextures[0].name, t, + mTextures[0].width, mTextures[0].height); + } } - const GGLSurface& t(frontBuffer().surface()); - loadTexture(dirty, mTextureName, t, mTextureWidth, mTextureHeight); } void Layer::onDraw(const Region& clip) const { - if (UNLIKELY(mTextureName == -1LU)) { - //LOGW("Layer %p doesn't have a texture", this); + const int index = (mFlags & DisplayHardware::DIRECT_TEXTURE) ? + mFrontBufferIndex : 0; + GLuint textureName = mTextures[index].name; + + if (UNLIKELY(textureName == -1LU)) { + LOGW("Layer %p doesn't have a texture", this); // the texture has not been created yet, this Layer has // in fact never been drawn into. this happens frequently with // SurfaceView. @@ -164,63 +206,66 @@ void Layer::onDraw(const Region& clip) const return; } - const DisplayHardware& hw(graphicPlane(0).displayHardware()); - const LayerBitmap& front(frontBuffer()); - const GGLSurface& t(front.surface()); - - status_t err = NO_ERROR; - const int can_use_copybit = canUseCopybit(); - if (can_use_copybit) { - // StopWatch watch("copybit"); - const State& s(drawingState()); - - copybit_image_t dst; - hw.getDisplaySurface(&dst); - const copybit_rect_t& drect - = reinterpret_cast(mTransformedBounds); - - copybit_image_t src; - front.getBitmapSurface(&src); - copybit_rect_t srect = { 0, 0, t.width, t.height }; - - copybit_device_t* copybit = mFlinger->getBlitEngine(); - copybit->set_parameter(copybit, COPYBIT_TRANSFORM, getOrientation()); - copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, s.alpha); - copybit->set_parameter(copybit, COPYBIT_DITHER, - s.flags & ISurfaceComposer::eLayerDither ? - COPYBIT_ENABLE : COPYBIT_DISABLE); - - region_iterator it(clip); - err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it); - } - - if (!can_use_copybit || err) { - drawWithOpenGL(clip, mTextureName, t); - } + GGLSurface t; + sp buffer(frontBuffer().getBuffer()); + buffer->getBitmapSurface(&t); + drawWithOpenGL(clip, textureName, t); } -status_t Layer::reallocateBuffer(int32_t index, uint32_t w, uint32_t h) +sp Layer::peekBuffer() { - LOGD_IF(DEBUG_RESIZE, - "reallocateBuffer (layer=%p), " - "requested (%dx%d), " - "index=%d, (%dx%d), (%dx%d)", - this, - int(w), int(h), - int(index), - int(mBuffers[0].width()), int(mBuffers[0].height()), - int(mBuffers[1].width()), int(mBuffers[1].height())); + /* + * This is called from the client's Surface::lock(), after it locked + * the surface successfully. We're therefore guaranteed that the + * back-buffer is not in use by ourselves. + * Of course, we need to validate all this, which is not trivial. + * + * FIXME: A resize could happen at any time here. What to do about this? + * - resize() form post() + * - resize() from doTransaction() + * + * We'll probably need an internal lock for this. + * + * + * TODO: We need to make sure that post() doesn't swap + * the buffers under us. + */ - status_t err = mBuffers[index].resize(w, h); - if (err == NO_ERROR) { - mBuffers[index].getInfo(lcblk->surface + index); - } else { - LOGE("resizing buffer %d to (%u,%u) failed [%08x] %s", - index, w, h, err, strerror(err)); - // XXX: what to do, what to do? We could try to free some - // hidden surfaces, instead of killing this one? + // it's okay to read swapState for the purpose of figuring out the + // backbuffer index, which cannot change (since the app has locked it). + const uint32_t state = lcblk->swapState; + const int32_t backBufferIndex = layer_cblk_t::backBuffer(state); + + // get rid of the EGL image, since we shouldn't need it anymore + // (note that we're in a different thread than where it is being used) + if (mTextures[backBufferIndex].image != EGL_NO_IMAGE_KHR) { + EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay()); + eglDestroyImageKHR(dpy, mTextures[backBufferIndex].image); + mTextures[backBufferIndex].image = EGL_NO_IMAGE_KHR; } - return err; + + LayerBitmap& layerBitmap(mBuffers[backBufferIndex]); + sp buffer = layerBitmap.allocate(); + + LOGD_IF(DEBUG_RESIZE, + "Layer::getBuffer(this=%p), index=%d, (%d,%d), (%d,%d)", + this, backBufferIndex, + layerBitmap.getWidth(), + layerBitmap.getHeight(), + layerBitmap.getBuffer()->getWidth(), + layerBitmap.getBuffer()->getHeight()); + + if (UNLIKELY(buffer == 0)) { + // XXX: what to do, what to do? + } else { + // texture is now dirty... + mTextures[backBufferIndex].dirty = true; + // ... so it the visible region (because we consider the surface's + // buffer size for visibility calculations) + forceVisibilityTransaction(); + mFlinger->setTransactionFlags(eTraversalNeeded); + } + return buffer; } uint32_t Layer::doTransaction(uint32_t flags) @@ -232,7 +277,7 @@ uint32_t Layer::doTransaction(uint32_t flags) // that the size changed back to its previous value before the buffer // was resized (in the eLocked case below), in which case, we still // need to execute the code below so the clients have a chance to be - // release. resze() deals with the fact that the size can be the same. + // release. resize() deals with the fact that the size can be the same. /* * Various states we could be in... @@ -276,8 +321,8 @@ uint32_t Layer::doTransaction(uint32_t flags) int(temp.w), int(temp.h), int(drawingState().w), int(drawingState().h), int(clientBackBufferIndex), - int(mBuffers[0].width()), int(mBuffers[0].height()), - int(mBuffers[1].width()), int(mBuffers[1].height())); + int(mBuffers[0].getWidth()), int(mBuffers[0].getHeight()), + int(mBuffers[1].getWidth()), int(mBuffers[1].getHeight())); // if we get there we're pretty screwed. the only reasonable // thing to do is to pretend we should do the resize since // backbufferChanged is set (this also will give a chance to @@ -299,8 +344,8 @@ uint32_t Layer::doTransaction(uint32_t flags) int(temp.w), int(temp.h), int(drawingState().w), int(drawingState().h), int(clientBackBufferIndex), - int(mBuffers[0].width()), int(mBuffers[0].height()), - int(mBuffers[1].width()), int(mBuffers[1].height())); + int(mBuffers[0].getWidth()), int(mBuffers[0].getHeight()), + int(mBuffers[1].getWidth()), int(mBuffers[1].getHeight())); if (state & eLocked) { // if the buffer is locked, we can't resize anything because @@ -314,7 +359,8 @@ uint32_t Layer::doTransaction(uint32_t flags) status_t err = resize(clientBackBufferIndex, temp.w, temp.h, "transaction"); if (err == NO_ERROR) { - const uint32_t mask = clientBackBufferIndex ? eResizeBuffer1 : eResizeBuffer0; + const uint32_t mask = clientBackBufferIndex ? + eResizeBuffer1 : eResizeBuffer0; android_atomic_and(~mask, &(lcblk->swapState)); // since a buffer became available, we can let the client go... mFlinger->scheduleBroadcast(client); @@ -353,14 +399,15 @@ status_t Layer::resize( { /* * handle resize (backbuffer and frontbuffer reallocation) + * this is called from post() or from doTransaction() */ const LayerBitmap& clientBackBuffer(mBuffers[clientBackBufferIndex]); // if the new (transaction) size is != from the the backbuffer // then we need to reallocate the backbuffer - bool backbufferChanged = (clientBackBuffer.width() != width) || - (clientBackBuffer.height() != height); + bool backbufferChanged = (clientBackBuffer.getWidth() != width) || + (clientBackBuffer.getHeight() != height); LOGD_IF(!backbufferChanged, "(%s) eResizeRequested (layer=%p), but size not changed: " @@ -372,18 +419,28 @@ status_t Layer::resize( int(currentState().w), int(currentState().h), long(lcblk->swapState), int(clientBackBufferIndex), - int(mBuffers[0].width()), int(mBuffers[0].height()), - int(mBuffers[1].width()), int(mBuffers[1].height())); + int(mBuffers[0].getWidth()), int(mBuffers[0].getHeight()), + int(mBuffers[1].getWidth()), int(mBuffers[1].getHeight())); // this can happen when changing the size back and forth quickly status_t err = NO_ERROR; if (backbufferChanged) { - err = reallocateBuffer(clientBackBufferIndex, width, height); - } - if (UNLIKELY(err != NO_ERROR)) { - // couldn't reallocate the surface - android_atomic_write(eInvalidSurface, &lcblk->swapState); - memset(lcblk->surface+clientBackBufferIndex, 0, sizeof(surface_info_t)); + + LOGD_IF(DEBUG_RESIZE, + "resize (layer=%p), requested (%dx%d), " + "index=%d, (%dx%d), (%dx%d)", + this, int(width), int(height), int(clientBackBufferIndex), + int(mBuffers[0].getWidth()), int(mBuffers[0].getHeight()), + int(mBuffers[1].getWidth()), int(mBuffers[1].getHeight())); + + err = mBuffers[clientBackBufferIndex].setSize(width, height); + if (UNLIKELY(err != NO_ERROR)) { + // This really should never happen + LOGE("resizing buffer %d to (%u,%u) failed [%08x] %s", + clientBackBufferIndex, width, height, err, strerror(err)); + // couldn't reallocate the surface + android_atomic_write(eInvalidSurface, &lcblk->swapState); + } } return err; } @@ -457,15 +514,21 @@ Region Layer::post(uint32_t* previousSate, bool& recomputeVisibleRegions) } while(android_atomic_cmpxchg(oldValue, newValue, &(lcblk->swapState))); *previousSate = oldValue; - + const int32_t index = (newValue & eIndex) ^ 1; mFrontBufferIndex = index; + /* NOTE: it's safe to set this flag here because this is only touched + * from LayerBitmap::allocate(), which by construction cannot happen + * while we're in post(). + */ + lcblk->surface[index].flags &= ~surface_info_t::eBufferDirty; + // ... post the new front-buffer Region dirty(lcblk->region + index); - dirty.andSelf(frontBuffer().bounds()); + dirty.andSelf(frontBuffer().getBounds()); - //LOGI("Did post oldValue=%08lx, newValue=%08lx, mFrontBufferIndex=%u\n", + //LOGD("Did post oldValue=%08lx, newValue=%08lx, mFrontBufferIndex=%u\n", // oldValue, newValue, mFrontBufferIndex); //dirty.dump("dirty"); @@ -476,8 +539,8 @@ Region Layer::post(uint32_t* previousSate, bool& recomputeVisibleRegions) "index=%d, (%dx%d), (%dx%d)", this, newValue, int(1-index), - int(mBuffers[0].width()), int(mBuffers[0].height()), - int(mBuffers[1].width()), int(mBuffers[1].height())); + int(mBuffers[0].getWidth()), int(mBuffers[0].getHeight()), + int(mBuffers[1].getWidth()), int(mBuffers[1].getHeight())); // here, we just posted the surface and we have resolved // the front/back buffer indices. The client is blocked, so @@ -522,8 +585,8 @@ Region Layer::post(uint32_t* previousSate, bool& recomputeVisibleRegions) Point Layer::getPhysicalSize() const { - const LayerBitmap& front(frontBuffer()); - return Point(front.width(), front.height()); + sp front(frontBuffer().getBuffer()); + return Point(front->getWidth(), front->getHeight()); } void Layer::unlockPageFlip( @@ -561,6 +624,22 @@ void Layer::finishPageFlip() mFlinger->scheduleBroadcast(client); } +// --------------------------------------------------------------------------- + +Layer::SurfaceLayer::SurfaceLayer(SurfaceID id, const sp& owner) + : Surface(id, owner->getIdentity(), owner) +{ +} + +sp Layer::SurfaceLayer::getBuffer() +{ + sp buffer = 0; + sp owner(getOwner()); + if (owner != 0) { + buffer = owner->peekBuffer(); + } + return buffer; +} // --------------------------------------------------------------------------- diff --git a/libs/surfaceflinger/Layer.h b/libs/surfaceflinger/Layer.h index 2867f2b007fdb..dc03d35f848e9 100644 --- a/libs/surfaceflinger/Layer.h +++ b/libs/surfaceflinger/Layer.h @@ -27,6 +27,11 @@ #include +#include +#include +#include +#include + #include "LayerBitmap.h" #include "LayerBase.h" #include "Transform.h" @@ -42,6 +47,8 @@ class FreezeLock; // --------------------------------------------------------------------------- +const int NUM_BUFFERS = 2; + class Layer : public LayerBaseClient { public: @@ -56,7 +63,7 @@ public: virtual ~Layer(); inline PixelFormat pixelFormat() const { - return frontBuffer().pixelFormat(); + return frontBuffer().getPixelFormat(); } status_t setBuffers( Client* client, @@ -73,8 +80,7 @@ public: virtual void finishPageFlip(); virtual bool needsBlending() const { return mNeedsBlending; } virtual bool isSecure() const { return mSecure; } - virtual GLuint getTextureName() const { return mTextureName; } - virtual sp getSurface() const; + virtual sp createSurface() const; const LayerBitmap& getBuffer(int i) const { return mBuffers[i]; } LayerBitmap& getBuffer(int i) { return mBuffers[i]; } @@ -96,21 +102,43 @@ private: status_t resize(int32_t index, uint32_t w, uint32_t h, const char* what); Region post(uint32_t* oldState, bool& recomputeVisibleRegions); - status_t reallocateBuffer(int32_t index, uint32_t w, uint32_t h); + sp peekBuffer(); + + + class SurfaceLayer : public LayerBaseClient::Surface + { + public: + SurfaceLayer(SurfaceID id, const sp& owner); + private: + virtual sp getBuffer(); + + sp getOwner() const { + return static_cast(Surface::getOwner().get()); + } + }; + friend class SurfaceLayer; + + struct Texture { + Texture() : name(-1U), width(0), height(0), image(EGL_NO_IMAGE_KHR), + dirty(true) { } + GLuint name; + GLuint width; + GLuint height; + EGLImageKHR image; + bool dirty; + }; + sp mSurface; bool mSecure; - LayerBitmap mBuffers[2]; + LayerBitmap mBuffers[NUM_BUFFERS]; + Texture mTextures[NUM_BUFFERS]; int32_t mFrontBufferIndex; bool mNeedsBlending; bool mResizeTransactionDone; Region mPostedDirtyRegion; sp mFreezeLock; - - GLuint mTextureName; - GLuint mTextureWidth; - GLuint mTextureHeight; }; // --------------------------------------------------------------------------- diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp index 0cf53f796b6b2..6da0bf77e10b8 100644 --- a/libs/surfaceflinger/LayerBase.cpp +++ b/libs/surfaceflinger/LayerBase.cpp @@ -14,14 +14,14 @@ * limitations under the License. */ -#define LOG_TAG "SurfaceFlinger" - #include #include #include #include #include +#include +#include #include #include @@ -62,7 +62,6 @@ LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display) mFlinger(flinger), mTransformed(false), mOrientation(0), - mCanUseCopyBit(false), mTransactionFlags(0), mPremultipliedAlpha(true), mIdentity(uint32_t(android_atomic_inc(&sIdentity))), @@ -265,43 +264,6 @@ void LayerBase::validateVisibility(const Transform& planeTransform) mTransformed = transformed; mLeft = tr.tx(); mTop = tr.ty(); - - // see if we can/should use 2D h/w with the new configuration - mCanUseCopyBit = false; - copybit_device_t* copybit = mFlinger->getBlitEngine(); - if (copybit) { - const int step = copybit->get(copybit, COPYBIT_ROTATION_STEP_DEG); - const int scaleBits = copybit->get(copybit, COPYBIT_SCALING_FRAC_BITS); - mCanUseCopyBit = true; - if ((mOrientation < 0) && (step > 1)) { - // arbitrary orientations not supported - mCanUseCopyBit = false; - } else if ((mOrientation > 0) && (step > 90)) { - // 90 deg rotations not supported - mCanUseCopyBit = false; - } else if ((tr.getType() & SkMatrix::kScale_Mask) && (scaleBits < 12)) { - // arbitrary scaling not supported - mCanUseCopyBit = false; - } -#if HONOR_PREMULTIPLIED_ALPHA - else if (needsBlending() && mPremultipliedAlpha) { - // pre-multiplied alpha not supported - mCanUseCopyBit = false; - } -#endif - else { - // here, we determined we can use copybit - if (tr.getType() & SkMatrix::kScale_Mask) { - // and we have scaling - if (!transparentRegionScreen.isRect()) { - // we punt because blending is cheap (h/w) and the region is - // complex, which may causes artifacts when copying - // scaled content - transparentRegionScreen.clear(); - } - } - } - } } void LayerBase::lockPageFlip(bool& recomputeVisibleRegions) @@ -565,8 +527,7 @@ void LayerBase::loadTexture(const Region& dirty, /* * In OpenGL ES we can't specify a stride with glTexImage2D (however, - * GL_UNPACK_ALIGNMENT is 4, which in essence allows a limited form of - * stride). + * GL_UNPACK_ALIGNMENT is a limited form of stride). * So if the stride here isn't representable with GL_UNPACK_ALIGNMENT, we * need to do something reasonable (here creating a bigger texture). * @@ -579,9 +540,11 @@ void LayerBase::loadTexture(const Region& dirty, * * This should never be a problem with POT textures */ - - tw += (((t.stride - tw) * bytesPerPixel(t.format)) / 4); - + + int unpack = __builtin_ctz(t.stride * bytesPerPixel(t.format)); + unpack = 1 << ((unpack > 3) ? 3 : unpack); + glPixelStorei(GL_UNPACK_ALIGNMENT, unpack); + /* * round to POT if needed */ @@ -594,108 +557,80 @@ void LayerBase::loadTexture(const Region& dirty, texture_h = 1 << (31 - clz(t.height)); if (texture_w < t.width) texture_w <<= 1; if (texture_h < t.height) texture_h <<= 1; - if (texture_w != tw || texture_h != th) { - // we can't use DIRECT_TEXTURE since we changed the size - // of the texture - flags &= ~DisplayHardware::DIRECT_TEXTURE; - } } - - if (flags & DisplayHardware::DIRECT_TEXTURE) { - // here we're guaranteed that texture_{w|h} == t{w|h} - if (t.format == GGL_PIXEL_FORMAT_RGB_565) { - glTexImage2D(GL_DIRECT_TEXTURE_2D_QUALCOMM, 0, - GL_RGB, tw, th, 0, - GL_RGB, GL_UNSIGNED_SHORT_5_6_5, t.data); - } else if (t.format == GGL_PIXEL_FORMAT_RGBA_4444) { - glTexImage2D(GL_DIRECT_TEXTURE_2D_QUALCOMM, 0, - GL_RGBA, tw, th, 0, - GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, t.data); - } else if (t.format == GGL_PIXEL_FORMAT_RGBA_8888) { - glTexImage2D(GL_DIRECT_TEXTURE_2D_QUALCOMM, 0, - GL_RGBA, tw, th, 0, - GL_RGBA, GL_UNSIGNED_BYTE, t.data); - } else if (t.format == GGL_PIXEL_FORMAT_BGRA_8888) { - // TODO: add GL_BGRA extension - } else { - // oops, we don't handle this format, try the regular path - goto regular; - } - textureWidth = tw; - textureHeight = th; - } else { + regular: - Rect bounds(dirty.bounds()); - GLvoid* data = 0; - if (texture_w!=textureWidth || texture_h!=textureHeight) { - // texture size changed, we need to create a new one + Rect bounds(dirty.bounds()); + GLvoid* data = 0; + if (texture_w!=textureWidth || texture_h!=textureHeight) { + // texture size changed, we need to create a new one - if (!textureWidth || !textureHeight) { - // this is the first time, load the whole texture - if (texture_w==tw && texture_h==th) { - // we can do it one pass - data = t.data; - } else { - // we have to create the texture first because it - // doesn't match the size of the buffer - bounds.set(Rect(tw, th)); - } - } - - if (t.format == GGL_PIXEL_FORMAT_RGB_565) { - glTexImage2D(GL_TEXTURE_2D, 0, - GL_RGB, texture_w, texture_h, 0, - GL_RGB, GL_UNSIGNED_SHORT_5_6_5, data); - } else if (t.format == GGL_PIXEL_FORMAT_RGBA_4444) { - glTexImage2D(GL_TEXTURE_2D, 0, - GL_RGBA, texture_w, texture_h, 0, - GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, data); - } else if (t.format == GGL_PIXEL_FORMAT_RGBA_8888) { - glTexImage2D(GL_TEXTURE_2D, 0, - GL_RGBA, texture_w, texture_h, 0, - GL_RGBA, GL_UNSIGNED_BYTE, data); - } else if ( t.format == GGL_PIXEL_FORMAT_YCbCr_422_SP || - t.format == GGL_PIXEL_FORMAT_YCbCr_420_SP) { - // just show the Y plane of YUV buffers + if (!textureWidth || !textureHeight) { + // this is the first time, load the whole texture + if (texture_w==tw && texture_h==th) { + // we can do it one pass data = t.data; - glTexImage2D(GL_TEXTURE_2D, 0, - GL_LUMINANCE, texture_w, texture_h, 0, - GL_LUMINANCE, GL_UNSIGNED_BYTE, data); } else { - // oops, we don't handle this format! - LOGE("layer %p, texture=%d, using format %d, which is not " - "supported by the GL", this, textureName, t.format); - textureName = -1; + // we have to create the texture first because it + // doesn't match the size of the buffer + bounds.set(Rect(tw, th)); } - textureWidth = texture_w; - textureHeight = texture_h; } - if (!data && textureName>=0) { - if (t.format == GGL_PIXEL_FORMAT_RGB_565) { - glTexSubImage2D(GL_TEXTURE_2D, 0, - 0, bounds.top, t.width, bounds.height(), - GL_RGB, GL_UNSIGNED_SHORT_5_6_5, - t.data + bounds.top*t.width*2); - } else if (t.format == GGL_PIXEL_FORMAT_RGBA_4444) { - glTexSubImage2D(GL_TEXTURE_2D, 0, - 0, bounds.top, t.width, bounds.height(), - GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, - t.data + bounds.top*t.width*2); - } else if (t.format == GGL_PIXEL_FORMAT_RGBA_8888) { - glTexSubImage2D(GL_TEXTURE_2D, 0, - 0, bounds.top, t.width, bounds.height(), - GL_RGBA, GL_UNSIGNED_BYTE, - t.data + bounds.top*t.width*4); - } + + if (t.format == GGL_PIXEL_FORMAT_RGB_565) { + glTexImage2D(GL_TEXTURE_2D, 0, + GL_RGB, texture_w, texture_h, 0, + GL_RGB, GL_UNSIGNED_SHORT_5_6_5, data); + } else if (t.format == GGL_PIXEL_FORMAT_RGBA_4444) { + glTexImage2D(GL_TEXTURE_2D, 0, + GL_RGBA, texture_w, texture_h, 0, + GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, data); + } else if (t.format == GGL_PIXEL_FORMAT_RGBA_8888) { + glTexImage2D(GL_TEXTURE_2D, 0, + GL_RGBA, texture_w, texture_h, 0, + GL_RGBA, GL_UNSIGNED_BYTE, data); + } else if ( t.format == GGL_PIXEL_FORMAT_YCbCr_422_SP || + t.format == GGL_PIXEL_FORMAT_YCbCr_420_SP) { + // just show the Y plane of YUV buffers + glTexImage2D(GL_TEXTURE_2D, 0, + GL_LUMINANCE, texture_w, texture_h, 0, + GL_LUMINANCE, GL_UNSIGNED_BYTE, data); + } else { + // oops, we don't handle this format! + LOGE("layer %p, texture=%d, using format %d, which is not " + "supported by the GL", this, textureName, t.format); + textureName = -1; + } + textureWidth = texture_w; + textureHeight = texture_h; + } + if (!data && textureName>=0) { + if (t.format == GGL_PIXEL_FORMAT_RGB_565) { + glTexSubImage2D(GL_TEXTURE_2D, 0, + 0, bounds.top, t.width, bounds.height(), + GL_RGB, GL_UNSIGNED_SHORT_5_6_5, + t.data + bounds.top*t.stride*2); + } else if (t.format == GGL_PIXEL_FORMAT_RGBA_4444) { + glTexSubImage2D(GL_TEXTURE_2D, 0, + 0, bounds.top, t.width, bounds.height(), + GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, + t.data + bounds.top*t.stride*2); + } else if (t.format == GGL_PIXEL_FORMAT_RGBA_8888) { + glTexSubImage2D(GL_TEXTURE_2D, 0, + 0, bounds.top, t.width, bounds.height(), + GL_RGBA, GL_UNSIGNED_BYTE, + t.data + bounds.top*t.stride*4); + } else if ( t.format == GGL_PIXEL_FORMAT_YCbCr_422_SP || + t.format == GGL_PIXEL_FORMAT_YCbCr_420_SP) { + // just show the Y plane of YUV buffers + glTexSubImage2D(GL_TEXTURE_2D, 0, + 0, bounds.top, t.width, bounds.height(), + GL_LUMINANCE, GL_UNSIGNED_BYTE, + t.data + bounds.top*t.stride); } } } -bool LayerBase::canUseCopybit() const -{ - return mCanUseCopyBit; -} - // --------------------------------------------------------------------------- LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display, @@ -704,9 +639,12 @@ LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display, lcblk( c ? &(c->ctrlblk->layers[i]) : 0 ), mIndex(i) { - if (client) { - client->bindLayer(this, i); +} +void LayerBaseClient::onFirstRef() +{ + if (client) { + client->bindLayer(this, mIndex); // Initialize this layer's control block memset(this->lcblk, 0, sizeof(layer_cblk_t)); this->lcblk->identity = mIdentity; @@ -729,11 +667,106 @@ int32_t LayerBaseClient::serverIndex() const { return 0xFFFF0000 | mIndex; } -sp LayerBaseClient::getSurface() const +sp LayerBaseClient::getSurface() { - return new Surface(clientIndex(), mIdentity); + sp s; + Mutex::Autolock _l(mLock); + s = mClientSurface.promote(); + if (s == 0) { + s = createSurface(); + mClientSurface = s; + } + return s; } +sp LayerBaseClient::createSurface() const +{ + return new Surface(clientIndex(), mIdentity, + const_cast(this)); +} + +// --------------------------------------------------------------------------- + +LayerBaseClient::Surface::Surface(SurfaceID id, int identity, + const sp& owner) + : mToken(id), mIdentity(identity), mOwner(owner) +{ +} + + +LayerBaseClient::Surface::~Surface() { + // TODO: We now have a point here were we can clean-up the + // client's mess. + // This is also where surface id should be recycled. + //LOGD("Surface %d, heaps={%p, %p} destroyed", + // mId, mHeap[0].get(), mHeap[1].get()); +} + +sp LayerBaseClient::Surface::getOwner() const { + sp owner(mOwner.promote()); + return owner; +} + + +void LayerBaseClient::Surface::getSurfaceData( + ISurfaceFlingerClient::surface_data_t* params) const +{ + params->token = mToken; + params->identity = mIdentity; +} + +status_t LayerBaseClient::Surface::onTransact( + uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) +{ + switch (code) { + case REGISTER_BUFFERS: + case UNREGISTER_BUFFERS: + case CREATE_OVERLAY: + { + // codes that require permission check + IPCThreadState* ipc = IPCThreadState::self(); + const int pid = ipc->getCallingPid(); + const int self_pid = getpid(); + if (LIKELY(pid != self_pid)) { + // we're called from a different process, do the real check + if (!checkCallingPermission( + String16("android.permission.ACCESS_SURFACE_FLINGER"))) + { + const int uid = ipc->getCallingUid(); + LOGE("Permission Denial: " + "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); + return PERMISSION_DENIED; + } + } + } + } + return BnSurface::onTransact(code, data, reply, flags); +} + +sp LayerBaseClient::Surface::getBuffer() +{ + return NULL; +} + +status_t LayerBaseClient::Surface::registerBuffers( + const ISurface::BufferHeap& buffers) +{ + return INVALID_OPERATION; +} + +void LayerBaseClient::Surface::postBuffer(ssize_t offset) +{ +} + +void LayerBaseClient::Surface::unregisterBuffers() +{ +} + +sp LayerBaseClient::Surface::createOverlay( + uint32_t w, uint32_t h, int32_t format) +{ + return NULL; +}; // --------------------------------------------------------------------------- diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h index a020f44e8746a..2a4e13391c25d 100644 --- a/libs/surfaceflinger/LayerBase.h +++ b/libs/surfaceflinger/LayerBase.h @@ -22,6 +22,8 @@ #include +#include + #include #include @@ -37,10 +39,11 @@ class SurfaceFlinger; class DisplayHardware; class GraphicPlane; class Client; +class SurfaceBuffer; // --------------------------------------------------------------------------- -class LayerBase +class LayerBase : public RefBase { // poor man's dynamic_cast below template @@ -72,7 +75,6 @@ public: static Vector deletedTextures; LayerBase(SurfaceFlinger* flinger, DisplayID display); - virtual ~LayerBase(); DisplayID dpy; mutable bool contentDirty; @@ -215,7 +217,9 @@ public: inline const State& currentState() const { return mCurrentState; } inline State& currentState() { return mCurrentState; } - static int compareCurrentStateZ(LayerBase*const* layerA, LayerBase*const* layerB) { + static int compareCurrentStateZ( + sp const * layerA, + sp const * layerB) { return layerA[0]->currentState().z - layerB[0]->currentState().z; } @@ -240,8 +244,6 @@ protected: GLint textureName, const GGLSurface& t, GLuint& textureWidth, GLuint& textureHeight) const; - bool canUseCopybit() const; - SurfaceFlinger* mFlinger; uint32_t mFlags; @@ -250,7 +252,6 @@ protected: int32_t mOrientation; GLfixed mVertices[4][2]; Rect mTransformedBounds; - bool mCanUseCopyBit; int mLeft; int mTop; @@ -269,9 +270,13 @@ protected: volatile int32_t mInvalidate; +protected: + virtual ~LayerBase(); + private: - void validateTexture(GLint textureName) const; - static int32_t sIdentity; + LayerBase(const LayerBase& rhs); + void validateTexture(GLint textureName) const; + static int32_t sIdentity; }; @@ -289,64 +294,55 @@ public: LayerBaseClient(SurfaceFlinger* flinger, DisplayID display, Client* client, int32_t i); virtual ~LayerBaseClient(); - + virtual void onFirstRef(); Client* const client; layer_cblk_t* const lcblk; + inline uint32_t getIdentity() const { return mIdentity; } inline int32_t clientIndex() const { return mIndex; } int32_t serverIndex() const; - virtual sp getSurface() const; - uint32_t getIdentity() const { return mIdentity; } + sp getSurface(); + virtual sp createSurface() const; + class Surface : public BnSurface { public: - Surface(SurfaceID id, int identity) { - mParams.token = id; - mParams.identity = identity; - } - Surface(SurfaceID id, - const sp& heap0, - const sp& heap1, - int identity) - { - mParams.token = id; - mParams.identity = identity; - mParams.heap[0] = heap0; - mParams.heap[1] = heap1; - } - virtual ~Surface() { - // TODO: We now have a point here were we can clean-up the - // client's mess. - // This is also where surface id should be recycled. - //LOGD("Surface %d, heaps={%p, %p} destroyed", - // mId, mHeap[0].get(), mHeap[1].get()); - } - + virtual void getSurfaceData( - ISurfaceFlingerClient::surface_data_t* params) const { - *params = mParams; - } + ISurfaceFlingerClient::surface_data_t* params) const; - virtual status_t registerBuffers(const ISurface::BufferHeap& buffers) - { return INVALID_OPERATION; } - virtual void postBuffer(ssize_t offset) { } - virtual void unregisterBuffers() { }; - virtual sp createOverlay( - uint32_t w, uint32_t h, int32_t format) { - return NULL; - }; + protected: + Surface(SurfaceID id, int identity, const sp& owner); + virtual ~Surface(); + virtual status_t onTransact(uint32_t code, const Parcel& data, + Parcel* reply, uint32_t flags); + sp getOwner() const; private: - ISurfaceFlingerClient::surface_data_t mParams; + virtual sp getBuffer(); + virtual status_t registerBuffers(const ISurface::BufferHeap& buffers); + virtual void postBuffer(ssize_t offset); + virtual void unregisterBuffers(); + virtual sp createOverlay(uint32_t w, uint32_t h, + int32_t format); + + private: + friend class LayerBaseClient; + int32_t mToken; + int32_t mIdentity; + wp mOwner; }; -private: - int32_t mIndex; + friend class Surface; +private: + int32_t mIndex; + mutable Mutex mLock; + mutable wp mClientSurface; }; // --------------------------------------------------------------------------- diff --git a/libs/surfaceflinger/LayerBitmap.cpp b/libs/surfaceflinger/LayerBitmap.cpp index e84435088a7c4..d633a2d52bf45 100644 --- a/libs/surfaceflinger/LayerBitmap.cpp +++ b/libs/surfaceflinger/LayerBitmap.cpp @@ -14,170 +14,204 @@ * limitations under the License. */ -#define LOG_TAG "SurfaceFlinger" - #include #include #include -#include #include #include #include +#include #include + #include +#include #include +#include "BufferAllocator.h" #include "LayerBitmap.h" #include "SurfaceFlinger.h" -#include "VRamHeap.h" namespace android { -// --------------------------------------------------------------------------- +// =========================================================================== +// Buffer and implementation of android_native_buffer_t +// =========================================================================== + +Buffer::Buffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) + : SurfaceBuffer(), mInitCheck(NO_INIT), mFlags(flags), + mVStride(0) +{ + this->format = format; + if (w>0 && h>0) { + mInitCheck = initSize(w, h); + } +} + +Buffer::~Buffer() +{ + if (handle) { + BufferAllocator& allocator = BufferAllocator::get(); + if (usage & BufferAllocator::USAGE_SW_READ_MASK) { + allocator.unmap(handle); + } + allocator.free(handle); + } +} + +status_t Buffer::initCheck() const { + return mInitCheck; +} + +android_native_buffer_t* Buffer::getNativeBuffer() const +{ + return static_cast(const_cast(this)); +} + +status_t Buffer::initSize(uint32_t w, uint32_t h) +{ + status_t err = NO_ERROR; + + BufferAllocator& allocator = BufferAllocator::get(); + + /* + * buffers used for software rendering, but h/w composition + * are allocated with SW_READ_OFTEN | SW_WRITE_OFTEN | HW_TEXTURE + * + * buffers used for h/w rendering and h/w composition + * are allocated with HW_RENDER | HW_TEXTURE + * + * buffers used with h/w rendering and either NPOT or no egl_image_ext + * are allocated with SW_READ_RARELY | HW_RENDER + * + */ + + if (mFlags & Buffer::SECURE) { + // secure buffer, don't store it into the GPU + usage = BufferAllocator::USAGE_SW_READ_OFTEN | + BufferAllocator::USAGE_SW_WRITE_OFTEN; + } else { + if (mFlags & Buffer::GPU) { + // the client wants to do GL rendering + usage = BufferAllocator::USAGE_HW_RENDER | + BufferAllocator::USAGE_HW_TEXTURE; + } else { + // software rendering-client, h/w composition + usage = BufferAllocator::USAGE_SW_READ_OFTEN | + BufferAllocator::USAGE_SW_WRITE_OFTEN | + BufferAllocator::USAGE_HW_TEXTURE; + } + } + + err = allocator.alloc(w, h, format, usage, &handle, &stride); + + if (err == NO_ERROR) { + if (usage & BufferAllocator::USAGE_SW_READ_MASK) { + err = allocator.map(handle, &bits); + } + if (err == NO_ERROR) { + width = w; + height = h; + mVStride = 0; + } + } + + return err; +} + +status_t Buffer::getBitmapSurface(copybit_image_t* img) const +{ + img->w = stride ?: width; + img->h = mVStride ?: height; + img->format = format; + + // FIXME: this should use a native_handle + img->offset = 0; + img->base = bits; + img->fd = getHandle()->data[0]; + + return NO_ERROR; +} + +status_t Buffer::getBitmapSurface(GGLSurface* sur) const +{ + sur->version = sizeof(GGLSurface); + sur->width = width; + sur->height = height; + sur->stride = stride; + sur->format = format; + sur->vstride = mVStride; + sur->data = static_cast(bits); + return NO_ERROR; +} + +// =========================================================================== +// LayerBitmap +// =========================================================================== + LayerBitmap::LayerBitmap() - : mAllocFlags(0), mOffset(0), mSize(-1U), mAlignment(2) + : mInfo(0), mWidth(0), mHeight(0) { - memset(&mSurface, 0, sizeof(mSurface)); } LayerBitmap::~LayerBitmap() { - mSurface.data = 0; } -status_t LayerBitmap::init(const sp& allocator) +status_t LayerBitmap::init(surface_info_t* info, + uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) { - if (mAllocator != NULL) + if (info == NULL) return BAD_VALUE; - mAllocator = allocator; + + mFormat = format; + mFlags = flags; + mWidth = w; + mHeight = h; + + mInfo = info; + memset(info, 0, sizeof(surface_info_t)); + info->flags = surface_info_t::eNeedNewBuffer; + + // init the buffer, but don't trigger an allocation + mBuffer = new Buffer(0, 0, format, flags); return NO_ERROR; } -status_t LayerBitmap::setBits(uint32_t w, uint32_t h, uint32_t alignment, - PixelFormat format, uint32_t flags) +status_t LayerBitmap::setSize(uint32_t w, uint32_t h) { - const sp& allocator(mAllocator); - if (allocator == NULL) - return NO_INIT; - - if (UNLIKELY(w == mSurface.width && h == mSurface.height && - format == mSurface.format)) - { // same format and size, do nothing. - return NO_ERROR; - } - - PixelFormatInfo info; - getPixelFormatInfo(format, &info); - - uint32_t allocFlags = MemoryDealer::PAGE_ALIGNED; - const uint32_t align = 4; // must match GL_UNPACK_ALIGNMENT - const uint32_t Bpp = info.bytesPerPixel; - uint32_t stride = (w + (alignment-1)) & ~(alignment-1); - stride = ((stride * Bpp + (align-1)) & ~(align-1)) / Bpp; - size_t size = info.getScanlineSize(stride) * h; - if (allocFlags & MemoryDealer::PAGE_ALIGNED) { - size_t pagesize = getpagesize(); - size = (size + (pagesize-1)) & ~(pagesize-1); - } - - /* FIXME: we should be able to have a h/v stride because the user of the - * surface might have stride limitation (for instance h/w codecs often do) - */ - int32_t vstride = 0; - - mAlignment = alignment; - mAllocFlags = allocFlags; - mOffset = 0; - if (mSize != size) { - // would be nice to have a reallocate() api - mBitsMemory.clear(); // free-memory - mBitsMemory = allocator->allocate(size, allocFlags); - mSize = size; - } else { - // don't erase memory if we didn't have to reallocate - flags &= ~SECURE_BITS; - } - if (mBitsMemory != 0) { - mOffset = mBitsMemory->offset(); - mSurface.data = static_cast(mBitsMemory->pointer()); - mSurface.version = sizeof(GGLSurface); - mSurface.width = w; - mSurface.height = h; - mSurface.stride = stride; - mSurface.vstride = vstride; - mSurface.format = format; - if (flags & SECURE_BITS) - clear(); - } - - if (mBitsMemory==0 || mSurface.data==0) { - LOGE("not enough memory for layer bitmap size=%u", size); - allocator->dump("LayerBitmap"); - mSurface.data = 0; - mSize = -1U; - return NO_MEMORY; + Mutex::Autolock _l(mLock); + if ((w != mWidth) || (h != mHeight)) { + mWidth = w; + mHeight = h; + // this will signal the client that it needs to asks us for a new buffer + mInfo->flags = surface_info_t::eNeedNewBuffer; } return NO_ERROR; } -void LayerBitmap::clear() +sp LayerBitmap::allocate() { - // NOTE: this memset should not be necessary, at least for - // opaque surface. However, for security reasons it's better to keep it - // (in the case of pmem, it's possible that the memory contains old - // data) - if (mSurface.data) { - memset(mSurface.data, 0, mSize); - //if (bytesPerPixel(mSurface.format) == 4) { - // android_memset32((uint32_t*)mSurface.data, 0xFF0000FF, mSize); - //} else { - // android_memset16((uint16_t*)mSurface.data, 0xF800, mSize); - //} + Mutex::Autolock _l(mLock); + sp buffer(mBuffer); + const uint32_t w = mWidth; + const uint32_t h = mHeight; + if (w != buffer->getWidth() || h != buffer->getHeight()) { + surface_info_t* info = mInfo; + buffer = new Buffer(w, h, mFormat, mFlags); + status_t err = buffer->initCheck(); + if (LIKELY(err == NO_ERROR)) { + info->flags = surface_info_t::eBufferDirty; + info->status = NO_ERROR; + } else { + memset(info, 0, sizeof(surface_info_t)); + info->status = NO_MEMORY; + } + mBuffer = buffer; } -} - -status_t LayerBitmap::getInfo(surface_info_t* info) const -{ - if (mSurface.data == 0) { - memset(info, 0, sizeof(surface_info_t)); - info->bits_offset = NO_MEMORY; - return NO_MEMORY; - } - info->w = uint16_t(width()); - info->h = uint16_t(height()); - info->stride= uint16_t(stride()); - info->bpr = uint16_t(stride() * bytesPerPixel(pixelFormat())); - info->format= uint8_t(pixelFormat()); - info->flags = surface_info_t::eBufferDirty; - info->bits_offset = ssize_t(mOffset); - return NO_ERROR; -} - -status_t LayerBitmap::resize(uint32_t w, uint32_t h) -{ - int err = setBits(w, h, mAlignment, pixelFormat(), SECURE_BITS); - return err; -} - -size_t LayerBitmap::size() const -{ - return mSize; -} - -void LayerBitmap::getBitmapSurface(copybit_image_t* img) const -{ - const sp& mh(getAllocator()->getMemoryHeap()); - void* sbase = mh->base(); - const GGLSurface& t(surface()); - img->w = t.stride ?: t.width; - img->h = t.vstride ?: t.height; - img->format = t.format; - img->offset = intptr_t(t.data) - intptr_t(sbase); - img->base = sbase; - img->fd = mh->heapID(); + return buffer; } // --------------------------------------------------------------------------- diff --git a/libs/surfaceflinger/LayerBitmap.h b/libs/surfaceflinger/LayerBitmap.h index 9ad64c40becf9..d1f78021640e8 100644 --- a/libs/surfaceflinger/LayerBitmap.h +++ b/libs/surfaceflinger/LayerBitmap.h @@ -20,63 +20,117 @@ #include #include +#include + #include + #include #include -#include +#include + +#include + #include +#include + + class copybit_image_t; +struct android_native_buffer_t; namespace android { // --------------------------------------------------------------------------- - class IMemory; class MemoryDealer; class LayerBitmap; -// --------------------------------------------------------------------------- +// =========================================================================== +// Buffer +// =========================================================================== + +class NativeBuffer; + +class Buffer : public SurfaceBuffer +{ +public: + enum { + DONT_CLEAR = 0x00000001, + GPU = 0x00000002, + SECURE = 0x00000004 + }; + + // creates w * h buffer + Buffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t flags = 0); + + // return status + status_t initCheck() const; + + uint32_t getWidth() const { return width; } + uint32_t getHeight() const { return height; } + uint32_t getStride() const { return stride; } + uint32_t getUsage() const { return usage; } + PixelFormat getPixelFormat() const { return format; } + Rect getBounds() const { return Rect(width, height); } + + status_t getBitmapSurface(copybit_image_t* img) const; + status_t getBitmapSurface(GGLSurface* surface) const; + + android_native_buffer_t* getNativeBuffer() const; + +private: + friend class LightRefBase; + Buffer(const Buffer& rhs); + ~Buffer(); + Buffer& operator = (const Buffer& rhs); + const Buffer& operator = (const Buffer& rhs) const; + + status_t initSize(uint32_t w, uint32_t h); + + ssize_t mInitCheck; + uint32_t mFlags; + uint32_t mVStride; +}; + +// =========================================================================== +// LayerBitmap +// =========================================================================== class LayerBitmap { public: - enum { - // erase memory to ensure security when necessary - SECURE_BITS = 0x00000001 + DONT_CLEAR = Buffer::DONT_CLEAR, + GPU = Buffer::GPU, + SECURE = Buffer::SECURE }; + LayerBitmap(); + ~LayerBitmap(); - LayerBitmap(); - ~LayerBitmap(); - status_t init(const sp& allocator); + status_t init(surface_info_t* info, + uint32_t w, uint32_t h, PixelFormat format, uint32_t flags = 0); - status_t setBits(uint32_t w, uint32_t h, uint32_t alignment, - PixelFormat format, uint32_t flags = 0); - void clear(); + status_t setSize(uint32_t w, uint32_t h); - status_t getInfo(surface_info_t* info) const; - status_t resize(uint32_t w, uint32_t h); - - const GGLSurface& surface() const { return mSurface; } - Rect bounds() const { return Rect(width(), height()); } - uint32_t width() const { return surface().width; } - uint32_t height() const { return surface().height; } - uint32_t stride() const { return surface().stride; } - PixelFormat pixelFormat() const { return surface().format; } - void* serverBits() const { return surface().data; } - size_t size() const; - const sp& getAllocator() const { return mAllocator; } - void getBitmapSurface(copybit_image_t* img) const; + sp allocate(); + sp getBuffer() const { return mBuffer; } + sp getBuffer() { return mBuffer; } + + uint32_t getWidth() const { return mWidth; } + uint32_t getHeight() const { return mHeight; } + PixelFormat getPixelFormat() const { return mBuffer->getPixelFormat(); } + Rect getBounds() const { return mBuffer->getBounds(); } + private: - sp mAllocator; - sp mBitsMemory; - uint32_t mAllocFlags; - ssize_t mOffset; - GGLSurface mSurface; - size_t mSize; - uint32_t mAlignment; + surface_info_t* mInfo; + sp mBuffer; + uint32_t mWidth; + uint32_t mHeight; + PixelFormat mFormat; + uint32_t mFlags; + // protects setSize() and allocate() + mutable Mutex mLock; }; }; // namespace android diff --git a/libs/surfaceflinger/LayerBlur.cpp b/libs/surfaceflinger/LayerBlur.cpp index d3e456f1bf8f5..54d5c52141335 100644 --- a/libs/surfaceflinger/LayerBlur.cpp +++ b/libs/surfaceflinger/LayerBlur.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "SurfaceFlinger" - #include #include #include diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp index 00fab70d491d0..f22ff59c6e487 100644 --- a/libs/surfaceflinger/LayerBuffer.cpp +++ b/libs/surfaceflinger/LayerBuffer.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "SurfaceFlinger" - #include #include #include @@ -25,15 +23,10 @@ #include #include -#include -#include - #include -#include #include "LayerBuffer.h" #include "SurfaceFlinger.h" -#include "VRamHeap.h" #include "DisplayHardware/DisplayHardware.h" @@ -55,30 +48,12 @@ LayerBuffer::LayerBuffer(SurfaceFlinger* flinger, DisplayID display, LayerBuffer::~LayerBuffer() { - sp s(getClientSurface()); - if (s != 0) { - s->disown(); - mClientSurface.clear(); - } } -sp LayerBuffer::getClientSurface() const +sp LayerBuffer::createSurface() const { - Mutex::Autolock _l(mLock); - return mClientSurface.promote(); -} - -sp LayerBuffer::getSurface() const -{ - sp s; - Mutex::Autolock _l(mLock); - s = mClientSurface.promote(); - if (s == 0) { - s = new SurfaceBuffer(clientIndex(), + return new SurfaceBuffer(clientIndex(), const_cast(this)); - mClientSurface = s; - } - return s; } bool LayerBuffer::needsBlending() const { @@ -192,82 +167,49 @@ sp LayerBuffer::clearSource() { // LayerBuffer::SurfaceBuffer // ============================================================================ -LayerBuffer::SurfaceBuffer::SurfaceBuffer(SurfaceID id, LayerBuffer* owner) -: LayerBaseClient::Surface(id, owner->getIdentity()), mOwner(owner) +LayerBuffer::SurfaceBuffer::SurfaceBuffer(SurfaceID id, + const sp& owner) + : LayerBaseClient::Surface(id, owner->getIdentity(), owner) { } LayerBuffer::SurfaceBuffer::~SurfaceBuffer() { unregisterBuffers(); - mOwner = 0; } -status_t LayerBuffer::SurfaceBuffer::onTransact( - uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) +status_t LayerBuffer::SurfaceBuffer::registerBuffers( + const ISurface::BufferHeap& buffers) { - switch (code) { - case REGISTER_BUFFERS: - case UNREGISTER_BUFFERS: - case CREATE_OVERLAY: - { - // codes that require permission check - IPCThreadState* ipc = IPCThreadState::self(); - const int pid = ipc->getCallingPid(); - const int self_pid = getpid(); - if (LIKELY(pid != self_pid)) { - // we're called from a different process, do the real check - if (!checkCallingPermission( - String16("android.permission.ACCESS_SURFACE_FLINGER"))) - { - const int uid = ipc->getCallingUid(); - LOGE("Permission Denial: " - "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); - return PERMISSION_DENIED; - } - } - } - } - return LayerBaseClient::Surface::onTransact(code, data, reply, flags); -} - -status_t LayerBuffer::SurfaceBuffer::registerBuffers(const ISurface::BufferHeap& buffers) -{ - LayerBuffer* owner(getOwner()); - if (owner) + sp owner(getOwner()); + if (owner != 0) return owner->registerBuffers(buffers); return NO_INIT; } void LayerBuffer::SurfaceBuffer::postBuffer(ssize_t offset) { - LayerBuffer* owner(getOwner()); - if (owner) + sp owner(getOwner()); + if (owner != 0) owner->postBuffer(offset); } void LayerBuffer::SurfaceBuffer::unregisterBuffers() { - LayerBuffer* owner(getOwner()); - if (owner) + sp owner(getOwner()); + if (owner != 0) owner->unregisterBuffers(); } sp LayerBuffer::SurfaceBuffer::createOverlay( uint32_t w, uint32_t h, int32_t format) { sp result; - LayerBuffer* owner(getOwner()); - if (owner) + sp owner(getOwner()); + if (owner != 0) result = owner->createOverlay(w, h, format); return result; } -void LayerBuffer::SurfaceBuffer::disown() -{ - Mutex::Autolock _l(mLock); - mOwner = 0; -} - // ============================================================================ // LayerBuffer::Buffer // ============================================================================ @@ -437,115 +379,27 @@ void LayerBuffer::BufferSource::onDraw(const Region& clip) const status_t err = NO_ERROR; NativeBuffer src(buffer->getBuffer()); const Rect& transformedBounds = mLayer.getTransformedBounds(); - const int can_use_copybit = mLayer.canUseCopybit(); - if (can_use_copybit) { - const int src_width = src.crop.r - src.crop.l; - const int src_height = src.crop.b - src.crop.t; - int W = transformedBounds.width(); - int H = transformedBounds.height(); - if (mLayer.getOrientation() & Transform::ROT_90) { - int t(W); W=H; H=t; - } - - /* With LayerBuffer, it is likely that we'll have to rescale the - * surface, because this is often used for video playback or - * camera-preview. Since we want these operation as fast as possible - * we make sure we can use the 2D H/W even if it doesn't support - * the requested scale factor, in which case we perform the scaling - * in several passes. */ - - copybit_device_t* copybit = mLayer.mFlinger->getBlitEngine(); - const float min = copybit->get(copybit, COPYBIT_MINIFICATION_LIMIT); - const float mag = copybit->get(copybit, COPYBIT_MAGNIFICATION_LIMIT); - - float xscale = 1.0f; - if (src_width > W*min) xscale = 1.0f / min; - else if (src_width*mag < W) xscale = mag; - - float yscale = 1.0f; - if (src_height > H*min) yscale = 1.0f / min; - else if (src_height*mag < H) yscale = mag; - - if (UNLIKELY(xscale!=1.0f || yscale!=1.0f)) { - if (UNLIKELY(mTemporaryDealer == 0)) { - // allocate a memory-dealer for this the first time - mTemporaryDealer = mLayer.mFlinger->getSurfaceHeapManager() - ->createHeap(ISurfaceComposer::eHardware); - mTempBitmap.init(mTemporaryDealer); - } - - const int tmp_w = floorf(src_width * xscale); - const int tmp_h = floorf(src_height * yscale); - err = mTempBitmap.setBits(tmp_w, tmp_h, 1, src.img.format); - - if (LIKELY(err == NO_ERROR)) { - NativeBuffer tmp; - mTempBitmap.getBitmapSurface(&tmp.img); - tmp.crop.l = 0; - tmp.crop.t = 0; - tmp.crop.r = tmp.img.w; - tmp.crop.b = tmp.img.h; - - region_iterator tmp_it(Region(Rect(tmp.crop.r, tmp.crop.b))); - copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0); - copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF); - copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE); - err = copybit->stretch(copybit, - &tmp.img, &src.img, &tmp.crop, &src.crop, &tmp_it); - src = tmp; - } - } - - const DisplayHardware& hw(mLayer.graphicPlane(0).displayHardware()); - copybit_image_t dst; - hw.getDisplaySurface(&dst); - const copybit_rect_t& drect - = reinterpret_cast(transformedBounds); - const State& s(mLayer.drawingState()); - region_iterator it(clip); - - // pick the right orientation for this buffer - int orientation = mLayer.getOrientation(); - if (UNLIKELY(mBufferHeap.transform)) { - Transform rot90; - GraphicPlane::orientationToTransfrom( - ISurfaceComposer::eOrientation90, 0, 0, &rot90); - const Transform& planeTransform(mLayer.graphicPlane(0).transform()); - const Layer::State& s(mLayer.drawingState()); - Transform tr(planeTransform * s.transform * rot90); - orientation = tr.getOrientation(); - } - - copybit->set_parameter(copybit, COPYBIT_TRANSFORM, orientation); - copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, s.alpha); - copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE); - - err = copybit->stretch(copybit, - &dst, &src.img, &drect, &src.crop, &it); - if (err != NO_ERROR) { - LOGE("copybit failed (%s)", strerror(err)); - } + // FIXME: We should model this after the overlay stuff + + if (UNLIKELY(mTextureName == -1LU)) { + mTextureName = mLayer.createTexture(); } + GLuint w = 0; + GLuint h = 0; + GGLSurface t; + t.version = sizeof(GGLSurface); + t.width = src.crop.r; + t.height = src.crop.b; + t.stride = src.img.w; + t.vstride= src.img.h; + t.format = src.img.format; + t.data = (GGLubyte*)(intptr_t(src.img.base) + src.img.offset); + const Region dirty(Rect(t.width, t.height)); - if (!can_use_copybit || err) { - if (UNLIKELY(mTextureName == -1LU)) { - mTextureName = mLayer.createTexture(); - } - GLuint w = 0; - GLuint h = 0; - GGLSurface t; - t.version = sizeof(GGLSurface); - t.width = src.crop.r; - t.height = src.crop.b; - t.stride = src.img.w; - t.vstride= src.img.h; - t.format = src.img.format; - t.data = (GGLubyte*)(intptr_t(src.img.base) + src.img.offset); - const Region dirty(Rect(t.width, t.height)); - mLayer.loadTexture(dirty, mTextureName, t, w, h); - mLayer.drawWithOpenGL(clip, mTextureName, t, mBufferHeap.transform); - } + // FIXME: Use EGLImage extension for this + mLayer.loadTexture(dirty, mTextureName, t, w, h); + mLayer.drawWithOpenGL(clip, mTextureName, t, mBufferHeap.transform); } diff --git a/libs/surfaceflinger/LayerBuffer.h b/libs/surfaceflinger/LayerBuffer.h index 2dc77f1501e9a..2d441217f94e4 100644 --- a/libs/surfaceflinger/LayerBuffer.h +++ b/libs/surfaceflinger/LayerBuffer.h @@ -22,7 +22,6 @@ #include #include -#include #include "LayerBase.h" #include "LayerBitmap.h" @@ -64,7 +63,7 @@ public: virtual bool needsBlending() const; - virtual sp getSurface() const; + virtual sp createSurface() const; virtual void onDraw(const Region& clip) const; virtual uint32_t doTransaction(uint32_t flags); virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion); @@ -126,8 +125,7 @@ private: status_t mStatus; ISurface::BufferHeap mBufferHeap; size_t mBufferSize; - mutable sp mTemporaryDealer; - mutable LayerBitmap mTempBitmap; + mutable sp mTempBitmap; mutable GLuint mTextureName; }; @@ -179,23 +177,19 @@ private: class SurfaceBuffer : public LayerBaseClient::Surface { public: - SurfaceBuffer(SurfaceID id, LayerBuffer* owner); + SurfaceBuffer(SurfaceID id, const sp& owner); virtual ~SurfaceBuffer(); - virtual status_t onTransact( - uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags); + virtual status_t registerBuffers(const ISurface::BufferHeap& buffers); virtual void postBuffer(ssize_t offset); virtual void unregisterBuffers(); + virtual sp createOverlay( uint32_t w, uint32_t h, int32_t format); - void disown(); private: - LayerBuffer* getOwner() const { - Mutex::Autolock _l(mLock); - return mOwner; + sp getOwner() const { + return static_cast(Surface::getOwner().get()); } - mutable Mutex mLock; - LayerBuffer* mOwner; }; friend class SurfaceFlinger; @@ -203,10 +197,8 @@ private: mutable Mutex mLock; sp mSource; - bool mInvalidate; bool mNeedsBlending; - mutable wp mClientSurface; }; // --------------------------------------------------------------------------- diff --git a/libs/surfaceflinger/LayerDim.cpp b/libs/surfaceflinger/LayerDim.cpp index 0c347cc518bfd..f2519c4e02801 100644 --- a/libs/surfaceflinger/LayerDim.cpp +++ b/libs/surfaceflinger/LayerDim.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "SurfaceFlinger" - #include #include #include @@ -25,7 +23,6 @@ #include "LayerDim.h" #include "SurfaceFlinger.h" -#include "VRamHeap.h" #include "DisplayHardware/DisplayHardware.h" namespace android { @@ -33,8 +30,6 @@ namespace android { const uint32_t LayerDim::typeInfo = LayerBaseClient::typeInfo | 0x10; const char* const LayerDim::typeID = "LayerDim"; -sp LayerDim::mDimmerDealer; -LayerBitmap LayerDim::mDimmerBitmap; // --------------------------------------------------------------------------- @@ -46,14 +41,6 @@ LayerDim::LayerDim(SurfaceFlinger* flinger, DisplayID display, void LayerDim::initDimmer(SurfaceFlinger* flinger, uint32_t w, uint32_t h) { - // must only be called once. - mDimmerDealer = flinger->getSurfaceHeapManager() - ->createHeap(ISurfaceComposer::eHardware); - if (mDimmerDealer != 0) { - mDimmerBitmap.init(mDimmerDealer); - mDimmerBitmap.setBits(w, h, 1, PIXEL_FORMAT_RGB_565); - mDimmerBitmap.clear(); - } } LayerDim::~LayerDim() @@ -62,48 +49,25 @@ LayerDim::~LayerDim() void LayerDim::onDraw(const Region& clip) const { + // FIXME: on some h/w (like msm7K, it will be faster to use a texture) + const State& s(drawingState()); - Region::iterator iterator(clip); if (s.alpha>0 && iterator) { const DisplayHardware& hw(graphicPlane(0).displayHardware()); - - status_t err = NO_ERROR; - const int can_use_copybit = canUseCopybit(); - if (can_use_copybit) { - // StopWatch watch("copybit"); - copybit_image_t dst; - hw.getDisplaySurface(&dst); - const copybit_rect_t& drect - = reinterpret_cast(mTransformedBounds); - - copybit_image_t src; - mDimmerBitmap.getBitmapSurface(&src); - const copybit_rect_t& srect(drect); - - copybit_device_t* copybit = mFlinger->getBlitEngine(); - copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0); - copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, s.alpha); - copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE); - region_iterator it(clip); - err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it); - } - - if (!can_use_copybit || err) { - const GGLfixed alpha = (s.alpha << 16)/255; - const uint32_t fbHeight = hw.getHeight(); - glDisable(GL_TEXTURE_2D); - glDisable(GL_DITHER); - glEnable(GL_BLEND); - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - glColor4x(0, 0, 0, alpha); - glVertexPointer(2, GL_FIXED, 0, mVertices); - Rect r; - while (iterator.iterate(&r)) { - const GLint sy = fbHeight - (r.top + r.height()); - glScissor(r.left, sy, r.width(), r.height()); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - } + const GGLfixed alpha = (s.alpha << 16)/255; + const uint32_t fbHeight = hw.getHeight(); + glDisable(GL_TEXTURE_2D); + glDisable(GL_DITHER); + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + glColor4x(0, 0, 0, alpha); + glVertexPointer(2, GL_FIXED, 0, mVertices); + Rect r; + while (iterator.iterate(&r)) { + const GLint sy = fbHeight - (r.top + r.height()); + glScissor(r.left, sy, r.width(), r.height()); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } } } diff --git a/libs/surfaceflinger/LayerDim.h b/libs/surfaceflinger/LayerDim.h index 3e37a4760dab1..0d5bb986cf099 100644 --- a/libs/surfaceflinger/LayerDim.h +++ b/libs/surfaceflinger/LayerDim.h @@ -44,10 +44,6 @@ public: virtual bool isSecure() const { return false; } static void initDimmer(SurfaceFlinger* flinger, uint32_t w, uint32_t h); - -private: - static sp mDimmerDealer; - static LayerBitmap mDimmerBitmap; }; // --------------------------------------------------------------------------- diff --git a/libs/surfaceflinger/LayerOrientationAnim.cpp b/libs/surfaceflinger/LayerOrientationAnim.cpp index 3e4035e9fc192..095fed8418aa2 100644 --- a/libs/surfaceflinger/LayerOrientationAnim.cpp +++ b/libs/surfaceflinger/LayerOrientationAnim.cpp @@ -24,10 +24,6 @@ #include #include -#include - -#include - #include "BlurFilter.h" #include "LayerBase.h" #include "LayerOrientationAnim.h" @@ -57,8 +53,8 @@ const float DIM_TARGET = 0.40f; LayerOrientationAnim::LayerOrientationAnim( SurfaceFlinger* flinger, DisplayID display, OrientationAnimation* anim, - const LayerBitmap& bitmapIn, - const LayerBitmap& bitmapOut) + const sp& bitmapIn, + const sp& bitmapOut) : LayerOrientationAnimBase(flinger, display), mAnim(anim), mBitmapIn(bitmapIn), mBitmapOut(bitmapOut), mTextureName(-1), mTextureNameIn(-1) @@ -108,11 +104,6 @@ void LayerOrientationAnim::validateVisibility(const Transform&) mTop = tr.ty(); transparentRegionScreen.clear(); mTransformed = true; - mCanUseCopyBit = false; - copybit_device_t* copybit = mFlinger->getBlitEngine(); - if (copybit) { - mCanUseCopyBit = true; - } } void LayerOrientationAnim::onOrientationCompleted() @@ -135,7 +126,7 @@ void LayerOrientationAnim::onDraw(const Region& clip) const // make a copy of what's on screen copybit_image_t image; - mBitmapOut.getBitmapSurface(&image); + mBitmapOut->getBitmapSurface(&image); const DisplayHardware& hw(graphicPlane(0).displayHardware()); hw.copyBackToImage(image); @@ -194,7 +185,7 @@ void LayerOrientationAnim::drawScaled(float scale, float alphaIn, float alphaOut copybit_image_t dst; const GraphicPlane& plane(graphicPlane(0)); const DisplayHardware& hw(plane.displayHardware()); - hw.getDisplaySurface(&dst); + //hw.getDisplaySurface(&dst); // clear screen // TODO: with update on demand, we may be able @@ -212,10 +203,10 @@ void LayerOrientationAnim::drawScaled(float scale, float alphaIn, float alphaOut } copybit_image_t src; - mBitmapIn.getBitmapSurface(&src); + mBitmapIn->getBitmapSurface(&src); copybit_image_t srcOut; - mBitmapOut.getBitmapSurface(&srcOut); + mBitmapOut->getBitmapSurface(&srcOut); const int w = dst.w*scale; const int h = dst.h*scale; @@ -225,78 +216,54 @@ void LayerOrientationAnim::drawScaled(float scale, float alphaIn, float alphaOut const copybit_rect_t srect = { 0, 0, src.w, src.h }; const Region reg(Rect( drect.l, drect.t, drect.r, drect.b )); - int err = NO_ERROR; - const int can_use_copybit = canUseCopybit(); - if (can_use_copybit) { - copybit_device_t* copybit = mFlinger->getBlitEngine(); - copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0); - copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE); - - if (alphaIn > 0) { - region_iterator it(reg); - copybit->set_parameter(copybit, COPYBIT_BLUR, COPYBIT_ENABLE); - copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, int(alphaIn*255)); - err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it); - } + GGLSurface t; + t.version = sizeof(GGLSurface); + t.width = src.w; + t.height = src.h; + t.stride = src.w; + t.vstride= src.h; + t.format = src.format; + t.data = (GGLubyte*)(intptr_t(src.base) + src.offset); - if (!err && alphaOut > 0.0f) { - region_iterator it(reg); - copybit->set_parameter(copybit, COPYBIT_BLUR, COPYBIT_DISABLE); - copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, int(alphaOut*255)); - err = copybit->stretch(copybit, &dst, &srcOut, &drect, &srect, &it); - } - LOGE_IF(err != NO_ERROR, "copybit failed (%s)", strerror(err)); + Transform tr; + tr.set(scale,0,0,scale); + tr.set(xc, yc); + + // FIXME: we should not access mVertices and mDrawingState like that, + // but since we control the animation, we know it's going to work okay. + // eventually we'd need a more formal way of doing things like this. + LayerOrientationAnim& self(const_cast(*this)); + tr.transform(self.mVertices[0], 0, 0); + tr.transform(self.mVertices[1], 0, src.h); + tr.transform(self.mVertices[2], src.w, src.h); + tr.transform(self.mVertices[3], src.w, 0); + if (!(mFlags & DisplayHardware::SLOW_CONFIG)) { + // Too slow to do this in software + self.mDrawingState.flags |= ISurfaceComposer::eLayerFilter; } - if (!can_use_copybit || err) { - GGLSurface t; - t.version = sizeof(GGLSurface); - t.width = src.w; - t.height = src.h; - t.stride = src.w; - t.vstride= src.h; - t.format = src.format; + + if (alphaIn > 0.0f) { t.data = (GGLubyte*)(intptr_t(src.base) + src.offset); - - Transform tr; - tr.set(scale,0,0,scale); - tr.set(xc, yc); - - // FIXME: we should not access mVertices and mDrawingState like that, - // but since we control the animation, we know it's going to work okay. - // eventually we'd need a more formal way of doing things like this. - LayerOrientationAnim& self(const_cast(*this)); - tr.transform(self.mVertices[0], 0, 0); - tr.transform(self.mVertices[1], 0, src.h); - tr.transform(self.mVertices[2], src.w, src.h); - tr.transform(self.mVertices[3], src.w, 0); - if (!(mFlags & DisplayHardware::SLOW_CONFIG)) { - // Too slow to do this in software - self.mDrawingState.flags |= ISurfaceComposer::eLayerFilter; + if (UNLIKELY(mTextureNameIn == -1LU)) { + mTextureNameIn = createTexture(); + GLuint w=0, h=0; + const Region dirty(Rect(t.width, t.height)); + loadTexture(dirty, mTextureNameIn, t, w, h); } + self.mDrawingState.alpha = int(alphaIn*255); + drawWithOpenGL(reg, mTextureNameIn, t); + } - if (alphaIn > 0.0f) { - t.data = (GGLubyte*)(intptr_t(src.base) + src.offset); - if (UNLIKELY(mTextureNameIn == -1LU)) { - mTextureNameIn = createTexture(); - GLuint w=0, h=0; - const Region dirty(Rect(t.width, t.height)); - loadTexture(dirty, mTextureNameIn, t, w, h); - } - self.mDrawingState.alpha = int(alphaIn*255); - drawWithOpenGL(reg, mTextureNameIn, t); - } - - if (alphaOut > 0.0f) { - t.data = (GGLubyte*)(intptr_t(srcOut.base) + srcOut.offset); - if (UNLIKELY(mTextureName == -1LU)) { - mTextureName = createTexture(); - GLuint w=0, h=0; - const Region dirty(Rect(t.width, t.height)); - loadTexture(dirty, mTextureName, t, w, h); - } - self.mDrawingState.alpha = int(alphaOut*255); - drawWithOpenGL(reg, mTextureName, t); + if (alphaOut > 0.0f) { + t.data = (GGLubyte*)(intptr_t(srcOut.base) + srcOut.offset); + if (UNLIKELY(mTextureName == -1LU)) { + mTextureName = createTexture(); + GLuint w=0, h=0; + const Region dirty(Rect(t.width, t.height)); + loadTexture(dirty, mTextureName, t, w, h); } + self.mDrawingState.alpha = int(alphaOut*255); + drawWithOpenGL(reg, mTextureName, t); } } diff --git a/libs/surfaceflinger/LayerOrientationAnim.h b/libs/surfaceflinger/LayerOrientationAnim.h index 365c6aeed4d75..472c45a1afefc 100644 --- a/libs/surfaceflinger/LayerOrientationAnim.h +++ b/libs/surfaceflinger/LayerOrientationAnim.h @@ -52,8 +52,8 @@ public: LayerOrientationAnim(SurfaceFlinger* flinger, DisplayID display, OrientationAnimation* anim, - const LayerBitmap& bitmapIn, - const LayerBitmap& bitmapOut); + const sp& bitmapIn, + const sp& bitmapOut); virtual ~LayerOrientationAnim(); void onOrientationCompleted(); @@ -90,8 +90,8 @@ private: }; OrientationAnimation* mAnim; - LayerBitmap mBitmapIn; - LayerBitmap mBitmapOut; + sp mBitmapIn; + sp mBitmapOut; nsecs_t mStartTime; nsecs_t mFinishTime; bool mOrientationCompleted; diff --git a/libs/surfaceflinger/LayerOrientationAnimRotate.cpp b/libs/surfaceflinger/LayerOrientationAnimRotate.cpp index 89ffb19ffb00c..a3bf0149c0e31 100644 --- a/libs/surfaceflinger/LayerOrientationAnimRotate.cpp +++ b/libs/surfaceflinger/LayerOrientationAnimRotate.cpp @@ -23,10 +23,6 @@ #include #include -#include - -#include - #include "LayerBase.h" #include "LayerOrientationAnim.h" #include "LayerOrientationAnimRotate.h" @@ -51,10 +47,10 @@ const float BOUNCES_AMPLITUDE = (5.0f/180.f) * M_PI; LayerOrientationAnimRotate::LayerOrientationAnimRotate( SurfaceFlinger* flinger, DisplayID display, OrientationAnimation* anim, - const LayerBitmap& bitmap, - const LayerBitmap& bitmapIn) + const sp& bitmapIn, + const sp& bitmapOut) : LayerOrientationAnimBase(flinger, display), mAnim(anim), - mBitmap(bitmap), mBitmapIn(bitmapIn), + mBitmapIn(bitmapIn), mBitmapOut(bitmapOut), mTextureName(-1), mTextureNameIn(-1) { mStartTime = systemTime(); @@ -103,7 +99,6 @@ void LayerOrientationAnimRotate::validateVisibility(const Transform&) mTop = tr.ty(); transparentRegionScreen.clear(); mTransformed = true; - mCanUseCopyBit = false; } void LayerOrientationAnimRotate::onOrientationCompleted() @@ -126,7 +121,7 @@ void LayerOrientationAnimRotate::onDraw(const Region& clip) const if (mFirstRedraw) { // make a copy of what's on screen copybit_image_t image; - mBitmapIn.getBitmapSurface(&image); + mBitmapIn->getBitmapSurface(&image); const DisplayHardware& hw(graphicPlane(0).displayHardware()); hw.copyBackToImage(image); @@ -185,7 +180,7 @@ void LayerOrientationAnimRotate::drawScaled(float f, float s, float alpha) const copybit_image_t dst; const GraphicPlane& plane(graphicPlane(0)); const DisplayHardware& hw(plane.displayHardware()); - hw.getDisplaySurface(&dst); + //hw.getDisplaySurface(&dst); // clear screen // TODO: with update on demand, we may be able @@ -200,7 +195,7 @@ void LayerOrientationAnimRotate::drawScaled(float f, float s, float alpha) const const int h = dst.h; copybit_image_t src; - mBitmap.getBitmapSurface(&src); + mBitmapIn->getBitmapSurface(&src); const copybit_rect_t srect = { 0, 0, src.w, src.h }; @@ -255,7 +250,7 @@ void LayerOrientationAnimRotate::drawScaled(float f, float s, float alpha) const tr.transform(self.mVertices[3], src.w, 0); copybit_image_t src; - mBitmapIn.getBitmapSurface(&src); + mBitmapIn->getBitmapSurface(&src); t.data = (GGLubyte*)(intptr_t(src.base) + src.offset); if (UNLIKELY(mTextureNameIn == -1LU)) { mTextureNameIn = createTexture(); diff --git a/libs/surfaceflinger/LayerOrientationAnimRotate.h b/libs/surfaceflinger/LayerOrientationAnimRotate.h index 5fbbd428d6716..a675c79b5176e 100644 --- a/libs/surfaceflinger/LayerOrientationAnimRotate.h +++ b/libs/surfaceflinger/LayerOrientationAnimRotate.h @@ -40,8 +40,8 @@ public: LayerOrientationAnimRotate(SurfaceFlinger* flinger, DisplayID display, OrientationAnimation* anim, - const LayerBitmap& zoomOut, - const LayerBitmap& zoomIn); + const sp& bitmapIn, + const sp& bitmapOut); virtual ~LayerOrientationAnimRotate(); void onOrientationCompleted(); @@ -55,8 +55,8 @@ private: void drawScaled(float angle, float scale, float alpha) const; OrientationAnimation* mAnim; - LayerBitmap mBitmap; - LayerBitmap mBitmapIn; + sp mBitmapIn; + sp mBitmapOut; nsecs_t mStartTime; nsecs_t mFinishTime; bool mOrientationCompleted; diff --git a/libs/surfaceflinger/OrientationAnimation.cpp b/libs/surfaceflinger/OrientationAnimation.cpp index 70eec8d68e1fe..a6c9c28d0ba8b 100644 --- a/libs/surfaceflinger/OrientationAnimation.cpp +++ b/libs/surfaceflinger/OrientationAnimation.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "SurfaceFlinger" - #include #include #include @@ -24,7 +22,6 @@ #include "LayerOrientationAnimRotate.h" #include "OrientationAnimation.h" #include "SurfaceFlinger.h" -#include "VRamHeap.h" #include "DisplayHardware/DisplayHardware.h" @@ -35,9 +32,6 @@ namespace android { OrientationAnimation::OrientationAnimation(const sp& flinger) : mFlinger(flinger), mLayerOrientationAnim(NULL), mState(DONE) { - // allocate a memory-dealer for this the first time - mTemporaryDealer = mFlinger->getSurfaceHeapManager()->createHeap( - ISurfaceComposer::eHardware); } OrientationAnimation::~OrientationAnimation() @@ -98,19 +92,14 @@ bool OrientationAnimation::prepare() const uint32_t w = hw.getWidth(); const uint32_t h = hw.getHeight(); - LayerBitmap bitmap; - bitmap.init(mTemporaryDealer); - bitmap.setBits(w, h, 1, hw.getFormat()); - - LayerBitmap bitmapIn; - bitmapIn.init(mTemporaryDealer); - bitmapIn.setBits(w, h, 1, hw.getFormat()); + sp bitmap = new Buffer(w, h, hw.getFormat()); + sp bitmapIn = new Buffer(w, h, hw.getFormat()); copybit_image_t front; - bitmap.getBitmapSurface(&front); - hw.copyFrontToImage(front); + bitmap->getBitmapSurface(&front); + hw.copyFrontToImage(front); // FIXME: we need an extension to do this - LayerOrientationAnimBase* l; + sp l; if (mType & 0x80) { l = new LayerOrientationAnimRotate( @@ -152,7 +141,7 @@ bool OrientationAnimation::finished() { mState = DONE; mFlinger->removeLayer(mLayerOrientationAnim); - mLayerOrientationAnim = NULL; + mLayerOrientationAnim.clear(); return true; } diff --git a/libs/surfaceflinger/OrientationAnimation.h b/libs/surfaceflinger/OrientationAnimation.h index cafa38d2e4717..8ba66210e873a 100644 --- a/libs/surfaceflinger/OrientationAnimation.h +++ b/libs/surfaceflinger/OrientationAnimation.h @@ -72,8 +72,7 @@ private: bool finished(); sp mFlinger; - sp mTemporaryDealer; - LayerOrientationAnimBase* mLayerOrientationAnim; + sp< LayerOrientationAnimBase > mLayerOrientationAnim; int mState; uint32_t mType; }; diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp index de64f55fbdc64..b4f443fda81c3 100644 --- a/libs/surfaceflinger/SurfaceFlinger.cpp +++ b/libs/surfaceflinger/SurfaceFlinger.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "SurfaceFlinger" - #include #include #include @@ -40,12 +38,12 @@ #include #include -#include #include #include #include "clz.h" +#include "BufferAllocator.h" #include "CPUGauge.h" #include "Layer.h" #include "LayerBlur.h" @@ -55,10 +53,8 @@ #include "LayerOrientationAnim.h" #include "OrientationAnimation.h" #include "SurfaceFlinger.h" -#include "VRamHeap.h" #include "DisplayHardware/DisplayHardware.h" -#include "GPUHardware/GPUHardware.h" #define DISPLAY_COUNT 1 @@ -86,30 +82,30 @@ SurfaceFlinger::LayerVector::LayerVector(const SurfaceFlinger::LayerVector& rhs) } ssize_t SurfaceFlinger::LayerVector::indexOf( - LayerBase* key, size_t guess) const + const sp& key, size_t guess) const { if (guess=0) { const size_t idx = lookup.valueAt(i); - LOG_ASSERT(layers[idx]==key, + LOGE_IF(layers[idx]!=key, "LayerVector[%p]: layers[%d]=%p, key=%p", - this, int(idx), layers[idx], key); + this, int(idx), layers[idx].get(), key.get()); return idx; } return i; } ssize_t SurfaceFlinger::LayerVector::add( - LayerBase* layer, - Vector::compar_t cmp) + const sp& layer, + Vector< sp >::compar_t cmp) { size_t count = layers.size(); ssize_t l = 0; ssize_t h = count-1; ssize_t mid; - LayerBase* const* a = layers.array(); + sp const* a = layers.array(); while (l <= h) { mid = l + (h - l)/2; const int c = cmp(a+mid, &layer); @@ -132,14 +128,14 @@ ssize_t SurfaceFlinger::LayerVector::add( return order; } -ssize_t SurfaceFlinger::LayerVector::remove(LayerBase* layer) +ssize_t SurfaceFlinger::LayerVector::remove(const sp& layer) { const ssize_t keyIndex = lookup.indexOfKey(layer); if (keyIndex >= 0) { const size_t index = lookup.valueAt(keyIndex); - LOG_ASSERT(layers[index]==layer, + LOGE_IF(layers[index]!=layer, "LayerVector[%p]: layers[%u]=%p, layer=%p", - this, int(index), layers[index], layer); + this, int(index), layers[index].get(), layer.get()); layers.removeItemsAt(index); lookup.removeItemsAt(keyIndex); const size_t count = lookup.size(); @@ -154,8 +150,8 @@ ssize_t SurfaceFlinger::LayerVector::remove(LayerBase* layer) } ssize_t SurfaceFlinger::LayerVector::reorder( - LayerBase* layer, - Vector::compar_t cmp) + const sp& layer, + Vector< sp >::compar_t cmp) { // XXX: it's a little lame. but oh well... ssize_t err = remove(layer); @@ -173,6 +169,7 @@ SurfaceFlinger::SurfaceFlinger() : BnSurfaceComposer(), Thread(false), mTransactionFlags(0), mTransactionCount(0), + mLayersRemoved(false), mBootTime(systemTime()), mLastScheduledBroadcast(NULL), mVisibleRegionsDirty(false), @@ -223,11 +220,6 @@ SurfaceFlinger::~SurfaceFlinger() delete mOrientationAnimation; } -copybit_device_t* SurfaceFlinger::getBlitEngine() const -{ - return graphicPlane(0).displayHardware().getBlitEngine(); -} - overlay_control_device_t* SurfaceFlinger::getOverlayEngine() const { return graphicPlane(0).displayHardware().getOverlayEngine(); @@ -238,20 +230,6 @@ sp SurfaceFlinger::getCblk() const return mServerCblkMemory; } -status_t SurfaceFlinger::requestGPU(const sp& callback, - gpu_info_t* gpu) -{ - IPCThreadState* ipc = IPCThreadState::self(); - const int pid = ipc->getCallingPid(); - status_t err = mGPU->request(pid, callback, gpu); - return err; -} - -status_t SurfaceFlinger::revokeGPU() -{ - return mGPU->friendlyRevoke(); -} - sp SurfaceFlinger::createConnection() { Mutex::Autolock _l(mStateLock); @@ -279,11 +257,13 @@ void SurfaceFlinger::destroyConnection(ClientID cid) Client* const client = mClientsMap.valueFor(cid); if (client) { // free all the layers this client owns - const Vector& layers = client->getLayers(); + const Vector< wp >& layers = client->getLayers(); const size_t count = layers.size(); for (size_t i=0 ; i layer(layers[i].promote()); + if (layer != 0) { + removeLayer_l(layer); + } } // the resources associated with this client will be freed @@ -338,9 +318,6 @@ static inline uint16_t pack565(int r, int g, int b) { return (r<<11)|(g<<5)|b; } -// this is defined in libGLES_CM.so -extern ISurfaceComposer* GLES_localSurfaceManager; - status_t SurfaceFlinger::readyToRun() { LOGI( "SurfaceFlinger's main thread ready to run. " @@ -357,17 +334,6 @@ status_t SurfaceFlinger::readyToRun() LOGE_IF(mServerCblk==0, "can't get to shared control block's address"); new(mServerCblk) surface_flinger_cblk_t; - // get a reference to the GPU if we have one - mGPU = GPUFactory::getGPU(); - - // create the surface Heap manager, which manages the heaps - // (be it in RAM or VRAM) where surfaces are allocated - // We give 8 MB per client. - mSurfaceHeapManager = new SurfaceHeapManager(this, 8 << 20); - - - GLES_localSurfaceManager = static_cast(this); - // we only support one display currently int dpy = 0; @@ -597,13 +563,11 @@ void SurfaceFlinger::handleConsoleEvents() if (mDeferReleaseConsole && hw.canDraw()) { // We got the release signal before the aquire signal mDeferReleaseConsole = false; - revokeGPU(); hw.releaseScreen(); } if (what & eConsoleReleased) { if (hw.canDraw()) { - revokeGPU(); hw.releaseScreen(); } else { mDeferReleaseConsole = true; @@ -628,7 +592,7 @@ void SurfaceFlinger::handleTransaction(uint32_t transactionFlags) const bool layersNeedTransaction = transactionFlags & eTraversalNeeded; if (layersNeedTransaction) { for (size_t i=0 ; i& layer = currentLayers[i]; uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded); if (!trFlags) continue; @@ -685,8 +649,7 @@ void SurfaceFlinger::handleTransaction(uint32_t transactionFlags) // some layers might have been removed, so // we need to update the regions they're exposing. - size_t c = mRemovedLayers.size(); - if (c) { + if (mLayersRemoved) { mVisibleRegionsDirty = true; } @@ -723,7 +686,7 @@ void SurfaceFlinger::computeVisibleRegions( size_t i = currentLayers.size(); while (i--) { - LayerBase* const layer = currentLayers[i]; + const sp& layer = currentLayers[i]; layer->validateVisibility(planeTransform); // start with the whole surface at its current location @@ -823,9 +786,9 @@ bool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers) { bool recomputeVisibleRegions = false; size_t count = currentLayers.size(); - LayerBase* const* layers = currentLayers.array(); + sp const* layers = currentLayers.array(); for (size_t i=0 ; i& layer = layers[i]; layer->lockPageFlip(recomputeVisibleRegions); } return recomputeVisibleRegions; @@ -836,9 +799,9 @@ void SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers) const GraphicPlane& plane(graphicPlane(0)); const Transform& planeTransform(plane.transform()); size_t count = currentLayers.size(); - LayerBase* const* layers = currentLayers.array(); + sp const* layers = currentLayers.array(); for (size_t i=0 ; i& layer = layers[i]; layer->unlockPageFlip(planeTransform, mDirtyRegion); } } @@ -889,9 +852,9 @@ void SurfaceFlinger::composeSurfaces(const Region& dirty) const SurfaceFlinger& flinger(*this); const LayerVector& drawingLayers(mDrawingState.layersSortedByZ); const size_t count = drawingLayers.size(); - LayerBase const* const* const layers = drawingLayers.array(); + sp const* const layers = drawingLayers.array(); for (size_t i=0 ; i& layer = layers[i]; const Region& visibleRegion(layer->visibleRegionScreen); if (!visibleRegion.isEmpty()) { const Region clip(dirty.intersect(visibleRegion)); @@ -906,9 +869,9 @@ void SurfaceFlinger::unlockClients() { const LayerVector& drawingLayers(mDrawingState.layersSortedByZ); const size_t count = drawingLayers.size(); - LayerBase* const* const layers = drawingLayers.array(); + sp const* const layers = drawingLayers.array(); for (size_t i=0 ; i& layer = layers[i]; layer->finishPageFlip(); } } @@ -1051,7 +1014,7 @@ void SurfaceFlinger::debugShowFPS() const // XXX: mFPS has the value we want } -status_t SurfaceFlinger::addLayer(LayerBase* layer) +status_t SurfaceFlinger::addLayer(const sp& layer) { Mutex::Autolock _l(mStateLock); addLayer_l(layer); @@ -1059,7 +1022,7 @@ status_t SurfaceFlinger::addLayer(LayerBase* layer) return NO_ERROR; } -status_t SurfaceFlinger::removeLayer(LayerBase* layer) +status_t SurfaceFlinger::removeLayer(const sp& layer) { Mutex::Autolock _l(mStateLock); removeLayer_l(layer); @@ -1067,32 +1030,31 @@ status_t SurfaceFlinger::removeLayer(LayerBase* layer) return NO_ERROR; } -status_t SurfaceFlinger::invalidateLayerVisibility(LayerBase* layer) +status_t SurfaceFlinger::invalidateLayerVisibility(const sp& layer) { layer->forceVisibilityTransaction(); setTransactionFlags(eTraversalNeeded); return NO_ERROR; } -status_t SurfaceFlinger::addLayer_l(LayerBase* layer) +status_t SurfaceFlinger::addLayer_l(const sp& layer) { ssize_t i = mCurrentState.layersSortedByZ.add( layer, &LayerBase::compareCurrentStateZ); - LayerBaseClient* lbc = LayerBase::dynamicCast(layer); - if (lbc) { + sp lbc = LayerBase::dynamicCast< LayerBaseClient* >(layer.get()); + if (lbc != 0) { mLayerMap.add(lbc->serverIndex(), lbc); } - mRemovedLayers.remove(layer); return NO_ERROR; } -status_t SurfaceFlinger::removeLayer_l(LayerBase* layerBase) +status_t SurfaceFlinger::removeLayer_l(const sp& layerBase) { ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase); if (index >= 0) { - mRemovedLayers.add(layerBase); - LayerBaseClient* layer = LayerBase::dynamicCast(layerBase); - if (layer) { + mLayersRemoved = true; + sp layer = LayerBase::dynamicCast< LayerBaseClient* >(layerBase.get()); + if (layer != 0) { mLayerMap.removeItem(layer->serverIndex()); } return NO_ERROR; @@ -1107,8 +1069,8 @@ status_t SurfaceFlinger::removeLayer_l(LayerBase* layerBase) void SurfaceFlinger::free_resources_l() { // Destroy layers that were removed - destroy_all_removed_layers_l(); - + mLayersRemoved = false; + // free resources associated with disconnected clients SortedVector& scheduledBroadcasts(mScheduledBroadcasts); Vector& disconnectedClients(mDisconnectedClients); @@ -1128,22 +1090,6 @@ void SurfaceFlinger::free_resources_l() disconnectedClients.clear(); } -void SurfaceFlinger::destroy_all_removed_layers_l() -{ - size_t c = mRemovedLayers.size(); - while (c--) { - LayerBase* const removed_layer = mRemovedLayers[c]; - - LOGE_IF(mCurrentState.layersSortedByZ.indexOf(removed_layer) >= 0, - "layer %p removed but still in the current state list", - removed_layer); - - delete removed_layer; - } - mRemovedLayers.clear(); -} - - uint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) { return android_atomic_and(~flags, &mTransactionFlags) & flags; @@ -1227,7 +1173,7 @@ sp SurfaceFlinger::createSurface(ClientID clientId, int pid, DisplayID d, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) { - LayerBaseClient* layer = 0; + sp layer; sp surfaceHandle; Mutex::Autolock _l(mStateLock); Client* const c = mClientsMap.valueFor(clientId); @@ -1259,7 +1205,7 @@ sp SurfaceFlinger::createSurface(ClientID clientId, int pid, break; } - if (layer) { + if (layer != 0) { setTransactionFlags(eTransactionNeeded); surfaceHandle = layer->getSurface(); if (surfaceHandle != 0) @@ -1269,7 +1215,7 @@ sp SurfaceFlinger::createSurface(ClientID clientId, int pid, return surfaceHandle; } -LayerBaseClient* SurfaceFlinger::createNormalSurfaceLocked( +sp SurfaceFlinger::createNormalSurfaceLocked( Client* client, DisplayID display, int32_t id, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) { @@ -1284,44 +1230,43 @@ LayerBaseClient* SurfaceFlinger::createNormalSurfaceLocked( break; } - Layer* layer = new Layer(this, display, client, id); + sp layer = new Layer(this, display, client, id); status_t err = layer->setBuffers(client, w, h, format, flags); if (LIKELY(err == NO_ERROR)) { layer->initStates(w, h, flags); addLayer_l(layer); } else { LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err)); - delete layer; - return 0; + layer.clear(); } return layer; } -LayerBaseClient* SurfaceFlinger::createBlurSurfaceLocked( +sp SurfaceFlinger::createBlurSurfaceLocked( Client* client, DisplayID display, int32_t id, uint32_t w, uint32_t h, uint32_t flags) { - LayerBlur* layer = new LayerBlur(this, display, client, id); + sp layer = new LayerBlur(this, display, client, id); layer->initStates(w, h, flags); addLayer_l(layer); return layer; } -LayerBaseClient* SurfaceFlinger::createDimSurfaceLocked( +sp SurfaceFlinger::createDimSurfaceLocked( Client* client, DisplayID display, int32_t id, uint32_t w, uint32_t h, uint32_t flags) { - LayerDim* layer = new LayerDim(this, display, client, id); + sp layer = new LayerDim(this, display, client, id); layer->initStates(w, h, flags); addLayer_l(layer); return layer; } -LayerBaseClient* SurfaceFlinger::createPushBuffersSurfaceLocked( +sp SurfaceFlinger::createPushBuffersSurfaceLocked( Client* client, DisplayID display, int32_t id, uint32_t w, uint32_t h, uint32_t flags) { - LayerBuffer* layer = new LayerBuffer(this, display, client, id); + sp layer = new LayerBuffer(this, display, client, id); layer->initStates(w, h, flags); addLayer_l(layer); return layer; @@ -1330,7 +1275,7 @@ LayerBaseClient* SurfaceFlinger::createPushBuffersSurfaceLocked( status_t SurfaceFlinger::destroySurface(SurfaceID index) { Mutex::Autolock _l(mStateLock); - LayerBaseClient* const layer = getLayerUser_l(index); + const sp& layer = getLayerUser_l(index); status_t err = removeLayer_l(layer); if (err < 0) return err; @@ -1348,8 +1293,8 @@ status_t SurfaceFlinger::setClientState( cid <<= 16; for (int i=0 ; i& layer = getLayerUser_l(s.surface | cid); + if (layer != 0) { const uint32_t what = s.what; // check if it has been destroyed first if (what & eDestroyed) { @@ -1401,9 +1346,10 @@ status_t SurfaceFlinger::setClientState( return NO_ERROR; } -LayerBaseClient* SurfaceFlinger::getLayerUser_l(SurfaceID s) const +sp SurfaceFlinger::getLayerUser_l(SurfaceID s) const { - return mLayerMap.valueFor(s); + sp layer = mLayerMap.valueFor(s); + return layer; } void SurfaceFlinger::screenReleased(int dpy) @@ -1446,7 +1392,7 @@ status_t SurfaceFlinger::dump(int fd, const Vector& args) const size_t count = currentLayers.size(); for (size_t i=0 ; i& layer = currentLayers[i]; const Layer::State& s = layer->drawingState(); snprintf(buffer, SIZE, "+ %s %p\n" @@ -1454,7 +1400,7 @@ status_t SurfaceFlinger::dump(int fd, const Vector& args) "z=%9d, pos=(%4d,%4d), size=(%4d,%4d), " "needsBlending=%1d, invalidate=%1d, " "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n", - layer->getTypeID(), layer, + layer->getTypeID(), layer.get(), s.z, layer->tx(), layer->ty(), s.w, s.h, layer->needsBlending(), layer->contentDirty, s.alpha, s.flags, @@ -1463,9 +1409,9 @@ status_t SurfaceFlinger::dump(int fd, const Vector& args) result.append(buffer); buffer[0] = 0; /*** LayerBaseClient ***/ - LayerBaseClient* const lbc = - LayerBase::dynamicCast((LayerBase*)layer); - if (lbc) { + sp lbc = + LayerBase::dynamicCast< LayerBaseClient* >(layer.get()); + if (lbc != 0) { snprintf(buffer, SIZE, " " "id=0x%08x, client=0x%08x, identity=%u\n", @@ -1475,18 +1421,20 @@ status_t SurfaceFlinger::dump(int fd, const Vector& args) result.append(buffer); buffer[0] = 0; /*** Layer ***/ - Layer* const l = LayerBase::dynamicCast((LayerBase*)layer); - if (l) { + sp l = LayerBase::dynamicCast< Layer* >(layer.get()); + if (l != 0) { const LayerBitmap& buf0(l->getBuffer(0)); const LayerBitmap& buf1(l->getBuffer(1)); snprintf(buffer, SIZE, " " - "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u], mTextureName=%d," + "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u]," " freezeLock=%p, swapState=0x%08x\n", l->pixelFormat(), - buf0.width(), buf0.height(), buf0.stride(), - buf1.width(), buf1.height(), buf1.stride(), - l->getTextureName(), l->getFreezeLock().get(), + buf0.getWidth(), buf0.getHeight(), + buf0.getBuffer()->getStride(), + buf1.getWidth(), buf1.getHeight(), + buf1.getBuffer()->getStride(), + l->getFreezeLock().get(), l->lcblk->swapState); } result.append(buffer); @@ -1503,19 +1451,8 @@ status_t SurfaceFlinger::dump(int fd, const Vector& args) mCurrentState.orientation, hw.canDraw()); result.append(buffer); - sp allocator; - if (mGPU != 0) { - snprintf(buffer, SIZE, " GPU owner: %d\n", mGPU->getOwner()); - result.append(buffer); - allocator = mGPU->getAllocator(); - if (allocator != 0) { - allocator->dump(result, "GPU Allocator"); - } - } - allocator = mSurfaceHeapManager->getAllocator(NATIVE_MEMORY_TYPE_PMEM); - if (allocator != 0) { - allocator->dump(result, "PMEM Allocator"); - } + const BufferAllocator& alloc(BufferAllocator::get()); + alloc.dump(result); } write(fd, result.string(), result.size()); return NO_ERROR; @@ -1532,7 +1469,6 @@ status_t SurfaceFlinger::onTransact( case FREEZE_DISPLAY: case UNFREEZE_DISPLAY: case BOOT_FINISHED: - case REVOKE_GPU: { // codes that require permission check IPCThreadState* ipc = IPCThreadState::self(); @@ -1599,12 +1535,6 @@ status_t SurfaceFlinger::onTransact( signalEvent(); } return NO_ERROR; - case 1005: // ask GPU revoke - mGPU->friendlyRevoke(); - return NO_ERROR; - case 1006: // revoke GPU - mGPU->unconditionalRevoke(); - return NO_ERROR; case 1007: // set mFreezeCount mFreezeCount = data.readInt32(); return NO_ERROR; @@ -1633,7 +1563,6 @@ status_t SurfaceFlinger::onTransact( Client::Client(ClientID clientID, const sp& flinger) : ctrlblk(0), cid(clientID), mPid(0), mBitmap(0), mFlinger(flinger) { - mSharedHeapAllocator = getSurfaceHeapManager()->createHeap(); const int pgsize = getpagesize(); const int cblksize=((sizeof(per_client_cblk_t)+(pgsize-1))&~(pgsize-1)); mCblkHeap = new MemoryDealer(cblksize); @@ -1653,10 +1582,6 @@ Client::~Client() { } } -const sp& Client::getSurfaceHeapManager() const { - return mFlinger->getSurfaceHeapManager(); -} - int32_t Client::generateId(int pid) { const uint32_t i = clz( ~mBitmap ); @@ -1668,13 +1593,15 @@ int32_t Client::generateId(int pid) mBitmap |= 1<<(31-i); return i; } -status_t Client::bindLayer(LayerBaseClient* layer, int32_t id) + +status_t Client::bindLayer(const sp& layer, int32_t id) { ssize_t idx = mInUse.indexOf(id); if (idx < 0) return NAME_NOT_FOUND; return mLayers.insertAt(layer, idx); } + void Client::free(int32_t id) { ssize_t idx = mInUse.remove(uint8_t(id)); @@ -1684,27 +1611,18 @@ void Client::free(int32_t id) } } -sp Client::createAllocator(uint32_t flags) -{ - sp allocator; - allocator = getSurfaceHeapManager()->createHeap( - flags, getClientPid(), mSharedHeapAllocator); - return allocator; -} - bool Client::isValid(int32_t i) const { return (uint32_t(i) Client::getLayerUser(int32_t i) const { + sp lbc; ssize_t idx = mInUse.indexOf(uint8_t(i)); - if (idx<0) return 0; - return mLayers[idx]; + if (idx >= 0) { + lbc = mLayers[idx].promote(); + LOGE_IF(lbc==0, "getLayerUser(i=%d), idx=%d is dead", int(i), int(idx)); + } + return lbc; } void Client::dump(const char* what) @@ -1841,6 +1759,10 @@ const Transform& GraphicPlane::transform() const { return mGlobalTransform; } +EGLDisplay GraphicPlane::getEGLDisplay() const { + return mHw->getEGLDisplay(); +} + // --------------------------------------------------------------------------- }; // namespace android diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h index e02318259108e..57c6ca8503a7a 100644 --- a/libs/surfaceflinger/SurfaceFlinger.h +++ b/libs/surfaceflinger/SurfaceFlinger.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -52,13 +53,10 @@ class Client; class BClient; class DisplayHardware; class FreezeLock; -class GPUHardwareInterface; -class IGPUCallback; class Layer; class LayerBuffer; class LayerOrientationAnim; class OrientationAnimation; -class SurfaceHeapManager; typedef int32_t ClientID; @@ -75,17 +73,13 @@ public: int32_t generateId(int pid); void free(int32_t id); - status_t bindLayer(LayerBaseClient* layer, int32_t id); - sp createAllocator(uint32_t memory_type); + status_t bindLayer(const sp& layer, int32_t id); inline bool isValid(int32_t i) const; - inline const uint8_t* inUseArray() const; - inline size_t numActiveLayers() const; - LayerBaseClient* getLayerUser(int32_t i) const; - const Vector& getLayers() const { return mLayers; } + sp getLayerUser(int32_t i) const; + const Vector< wp >& getLayers() const { return mLayers; } const sp& controlBlockMemory() const { return mCblkMemory; } void dump(const char* what); - const sp& getSurfaceHeapManager() const; // pointer to this client's control block per_client_cblk_t* ctrlblk; @@ -95,15 +89,13 @@ public: private: int getClientPid() const { return mPid; } - int mPid; - uint32_t mBitmap; - SortedVector mInUse; - Vector mLayers; - sp mCblkHeap; - sp mFlinger; - sp mSharedHeapAllocator; - sp mPMemAllocator; - sp mCblkMemory; + int mPid; + uint32_t mBitmap; + SortedVector mInUse; + Vector< wp > mLayers; + sp mCblkHeap; + sp mFlinger; + sp mCblkMemory; }; // --------------------------------------------------------------------------- @@ -126,6 +118,8 @@ public: const DisplayHardware& displayHardware() const; const Transform& transform() const; + EGLDisplay getEGLDisplay() const; + private: GraphicPlane(const GraphicPlane&); GraphicPlane operator = (const GraphicPlane&); @@ -169,28 +163,16 @@ public: virtual status_t unfreezeDisplay(DisplayID dpy, uint32_t flags); virtual int setOrientation(DisplayID dpy, int orientation, uint32_t flags); virtual void signal() const; - virtual status_t requestGPU(const sp& callback, - gpu_info_t* gpu); - virtual status_t revokeGPU(); void screenReleased(DisplayID dpy); void screenAcquired(DisplayID dpy); - const sp& getSurfaceHeapManager() const { - return mSurfaceHeapManager; - } - - const sp& getGPU() const { - return mGPU; - } - - copybit_device_t* getBlitEngine() const; overlay_control_device_t* getOverlayEngine() const; - status_t removeLayer(LayerBase* layer); - status_t addLayer(LayerBase* layer); - status_t invalidateLayerVisibility(LayerBase* layer); + status_t removeLayer(const sp& layer); + status_t addLayer(const sp& layer); + status_t invalidateLayerVisibility(const sp& layer); private: friend class BClient; @@ -205,20 +187,25 @@ private: DisplayID display, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags); - LayerBaseClient* createNormalSurfaceLocked(Client* client, DisplayID display, - int32_t id, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags); + sp createNormalSurfaceLocked( + Client* client, DisplayID display, + int32_t id, uint32_t w, uint32_t h, + PixelFormat format, uint32_t flags); - LayerBaseClient* createBlurSurfaceLocked(Client* client, DisplayID display, + sp createBlurSurfaceLocked( + Client* client, DisplayID display, int32_t id, uint32_t w, uint32_t h, uint32_t flags); - LayerBaseClient* createDimSurfaceLocked(Client* client, DisplayID display, + sp createDimSurfaceLocked( + Client* client, DisplayID display, int32_t id, uint32_t w, uint32_t h, uint32_t flags); - LayerBaseClient* createPushBuffersSurfaceLocked(Client* client, DisplayID display, + sp createPushBuffersSurfaceLocked( + Client* client, DisplayID display, int32_t id, uint32_t w, uint32_t h, uint32_t flags); - status_t destroySurface(SurfaceID surface_id); - status_t setClientState(ClientID cid, int32_t count, const layer_state_t* states); + status_t destroySurface(SurfaceID surface_id); + status_t setClientState(ClientID cid, int32_t count, const layer_state_t* states); class LayerVector { @@ -226,15 +213,15 @@ private: inline LayerVector() { } LayerVector(const LayerVector&); inline size_t size() const { return layers.size(); } - inline LayerBase*const* array() const { return layers.array(); } - ssize_t add(LayerBase*, Vector::compar_t); - ssize_t remove(LayerBase*); - ssize_t reorder(LayerBase*, Vector::compar_t); - ssize_t indexOf(LayerBase* key, size_t guess=0) const; - inline LayerBase* operator [] (size_t i) const { return layers[i]; } + inline sp const* array() const { return layers.array(); } + ssize_t add(const sp&, Vector< sp >::compar_t); + ssize_t remove(const sp&); + ssize_t reorder(const sp&, Vector< sp >::compar_t); + ssize_t indexOf(const sp& key, size_t guess=0) const; + inline sp operator [] (size_t i) const { return layers[i]; } private: - KeyedVector lookup; - Vector layers; + KeyedVector< sp , size_t> lookup; + Vector< sp > layers; }; struct State { @@ -299,10 +286,9 @@ private: void destroyConnection(ClientID cid); - LayerBaseClient* getLayerUser_l(SurfaceID index) const; - status_t addLayer_l(LayerBase* layer); - status_t removeLayer_l(LayerBase* layer); - void destroy_all_removed_layers_l(); + sp getLayerUser_l(SurfaceID index) const; + status_t addLayer_l(const sp& layer); + status_t removeLayer_l(const sp& layer); void free_resources_l(); uint32_t getTransactionFlags(uint32_t flags); @@ -335,17 +321,15 @@ private: // protected by mStateLock (but we could use another lock) Tokenizer mTokens; DefaultKeyedVector mClientsMap; - DefaultKeyedVector mLayerMap; + DefaultKeyedVector > mLayerMap; GraphicPlane mGraphicPlanes[1]; - SortedVector mRemovedLayers; + bool mLayersRemoved; Vector mDisconnectedClients; // constant members (no synchronization needed for access) sp mServerHeap; sp mServerCblkMemory; surface_flinger_cblk_t* mServerCblk; - sp mSurfaceHeapManager; - sp mGPU; GLuint mWormholeTexName; sp mBootAnimation; nsecs_t mBootTime; diff --git a/libs/surfaceflinger/Tokenizer.cpp b/libs/surfaceflinger/Tokenizer.cpp index ef51d6abc9169..be3a239836b7c 100644 --- a/libs/surfaceflinger/Tokenizer.cpp +++ b/libs/surfaceflinger/Tokenizer.cpp @@ -162,9 +162,10 @@ void Tokenizer::dump() const { const run_t* ranges = mRanges.array(); const size_t c = mRanges.size(); - printf("Tokenizer (%p, size = %lu)\n", this, c); + printf("Tokenizer (%p, size = %d)\n", this, int(c)); for (size_t i=0 ; i +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include "GPUHardware/GPUHardware.h" +#include "SurfaceFlinger.h" +#include "VRamHeap.h" + +#if HAVE_ANDROID_OS +#include +#endif + + +namespace android { + +// --------------------------------------------------------------------------- + +/* + * Amount of memory we reserve for surface, per client in PMEM + * (PMEM is used for 2D acceleration) + * 8 MB of address space per client should be enough. + */ +static const int PMEM_SIZE = int(8 * 1024 * 1024); + +int SurfaceHeapManager::global_pmem_heap = 0; + +// --------------------------------------------------------------------------- + +SurfaceHeapManager::SurfaceHeapManager(const sp& flinger, + size_t clientHeapSize) + : mFlinger(flinger), mClientHeapSize(clientHeapSize) +{ + SurfaceHeapManager::global_pmem_heap = 1; +} + +SurfaceHeapManager::~SurfaceHeapManager() +{ +} + +void SurfaceHeapManager::onFirstRef() +{ + if (global_pmem_heap) { + const char* device = "/dev/pmem"; + mPMemHeap = new PMemHeap(device, PMEM_SIZE); + if (mPMemHeap->base() == MAP_FAILED) { + mPMemHeap.clear(); + global_pmem_heap = 0; + } + } +} + +sp SurfaceHeapManager::createHeap( + uint32_t flags, + pid_t client_pid, + const sp& defaultAllocator) +{ + sp dealer; + + if (flags & ISurfaceComposer::eGPU) { + // don't grant GPU memory if GPU is disabled + char value[PROPERTY_VALUE_MAX]; + property_get("debug.egl.hw", value, "1"); + if (atoi(value) == 0) { + flags &= ~ISurfaceComposer::eGPU; + } + } + + if (flags & ISurfaceComposer::eGPU) { + // FIXME: this is msm7201A specific, where gpu surfaces may not be secure + if (!(flags & ISurfaceComposer::eSecure)) { + // if GPU doesn't work, we try eHardware + flags |= ISurfaceComposer::eHardware; + // asked for GPU memory, try that first + dealer = mFlinger->getGPU()->request(client_pid); + } + } + + if (dealer == NULL) { + if (defaultAllocator != NULL) + // if a default allocator is given, use that + dealer = defaultAllocator; + } + + if (dealer == NULL) { + // always try h/w accelerated memory first + if (global_pmem_heap) { + const sp& heap(mPMemHeap); + if (dealer == NULL && heap != NULL) { + dealer = new MemoryDealer( + heap->createClientHeap(), + heap->getAllocator()); + } + } + } + + if (dealer == NULL) { + // return the ashmem allocator (software rendering) + dealer = new MemoryDealer(mClientHeapSize, 0, "SFNativeHeap"); + } + return dealer; +} + +sp SurfaceHeapManager::getAllocator(int type) const +{ + Mutex::Autolock _l(mLock); + sp allocator; + + // this is only used for debugging + switch (type) { + case NATIVE_MEMORY_TYPE_PMEM: + if (mPMemHeap != 0) { + allocator = mPMemHeap->getAllocator(); + } + break; + } + return allocator; +} + +// --------------------------------------------------------------------------- + +PMemHeap::PMemHeap(const char* const device, size_t size, size_t reserved) + : MemoryHeapBase(device, size) +{ + //LOGD("%s, %p, mFD=%d", __PRETTY_FUNCTION__, this, heapID()); + if (base() != MAP_FAILED) { + //LOGD("%s, %u bytes", device, virtualSize()); + if (reserved == 0) + reserved = virtualSize(); + mAllocator = new SimpleBestFitAllocator(reserved); + } +} + +PMemHeap::~PMemHeap() { + //LOGD("%s, %p, mFD=%d", __PRETTY_FUNCTION__, this, heapID()); +} + +sp PMemHeap::createClientHeap() { + sp parentHeap(this); + return new MemoryHeapPmem(parentHeap); +} + +// --------------------------------------------------------------------------- +}; // namespace android diff --git a/libs/surfaceflinger/purgatory/VRamHeap.h b/libs/surfaceflinger/purgatory/VRamHeap.h new file mode 100644 index 0000000000000..91401679cb2cc --- /dev/null +++ b/libs/surfaceflinger/purgatory/VRamHeap.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2008 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. + */ + +#ifndef ANDROID_VRAM_HEAP_H +#define ANDROID_VRAM_HEAP_H + +#include +#include +#include + +namespace android { + +// --------------------------------------------------------------------------- + +class PMemHeap; +class MemoryHeapPmem; +class SurfaceFlinger; + +// --------------------------------------------------------------------------- + +class SurfaceHeapManager : public RefBase +{ +public: + SurfaceHeapManager(const sp& flinger, size_t clientHeapSize); + virtual ~SurfaceHeapManager(); + virtual void onFirstRef(); + /* use ISurfaceComposer flags eGPU|eHArdware|eSecure */ + sp createHeap(uint32_t flags=0, pid_t client_pid = 0, + const sp& defaultAllocator = 0); + + // used for debugging only... + sp getAllocator(int type) const; + +private: + sp getHeap(int type) const; + + sp mFlinger; + mutable Mutex mLock; + size_t mClientHeapSize; + sp mPMemHeap; + static int global_pmem_heap; +}; + +// --------------------------------------------------------------------------- + +class PMemHeap : public MemoryHeapBase +{ +public: + PMemHeap(const char* const vram, + size_t size=0, size_t reserved=0); + virtual ~PMemHeap(); + + virtual const sp& getAllocator() const { + return mAllocator; + } + virtual sp createClientHeap(); + +private: + sp mAllocator; +}; + +// --------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_VRAM_HEAP_H diff --git a/libs/surfaceflinger/tests/resize/Android.mk b/libs/surfaceflinger/tests/resize/Android.mk new file mode 100644 index 0000000000000..ef1532f6e136a --- /dev/null +++ b/libs/surfaceflinger/tests/resize/Android.mk @@ -0,0 +1,16 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + resize.cpp + +LOCAL_SHARED_LIBRARIES := \ + libcutils \ + libutils \ + libui + +LOCAL_MODULE:= test-resize + +LOCAL_MODULE_TAGS := tests + +include $(BUILD_EXECUTABLE) diff --git a/libs/surfaceflinger/tests/resize/resize.cpp b/libs/surfaceflinger/tests/resize/resize.cpp new file mode 100644 index 0000000000000..21c6ab654b276 --- /dev/null +++ b/libs/surfaceflinger/tests/resize/resize.cpp @@ -0,0 +1,60 @@ +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +using namespace android; + +namespace android { +class Test { +public: + static const sp& getISurface(const sp& s) { + return s->getISurface(); + } +}; +}; + +int main(int argc, char** argv) +{ + // set up the thread-pool + sp proc(ProcessState::self()); + ProcessState::self()->startThreadPool(); + + // create a client to surfaceflinger + sp client = new SurfaceComposerClient(); + + // create pushbuffer surface + sp surface = client->createSurface(getpid(), 0, 160, 240, + PIXEL_FORMAT_RGB_565); + + + client->openTransaction(); + surface->setLayer(100000); + client->closeTransaction(); + + Surface::SurfaceInfo info; + surface->lock(&info); + ssize_t bpr = info.s * bytesPerPixel(info.format); + android_memset16((uint16_t*)info.bits, 0xF800, bpr*info.h); + surface->unlockAndPost(); + + surface->lock(&info); + android_memset16((uint16_t*)info.bits, 0x07E0, bpr*info.h); + surface->unlockAndPost(); + + client->openTransaction(); + surface->setSize(320, 240); + client->closeTransaction(); + + + IPCThreadState::self()->joinThreadPool(); + + return 0; +} diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk index f9443579af000..577dd4bf79044 100644 --- a/libs/ui/Android.mk +++ b/libs/ui/Android.mk @@ -2,9 +2,9 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ + BufferMapper.cpp \ Camera.cpp \ CameraParameters.cpp \ - EGLDisplaySurface.cpp \ EGLNativeWindowSurface.cpp \ EventHub.cpp \ EventRecurrence.cpp \ diff --git a/libs/ui/BufferMapper.cpp b/libs/ui/BufferMapper.cpp new file mode 100644 index 0000000000000..a97188e73d851 --- /dev/null +++ b/libs/ui/BufferMapper.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2007 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. + */ + +#define LOG_TAG "BufferMapper" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include + +#include + +namespace android { +// --------------------------------------------------------------------------- + +BufferMapper::BufferMapper() + : mAllocMod(0) +{ + hw_module_t const* module; + int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module); + LOGE_IF(err, "FATAL: can't find the %s module", GRALLOC_HARDWARE_MODULE_ID); + if (err == 0) { + mAllocMod = (gralloc_module_t const *)module; + } +} + +status_t BufferMapper::map(buffer_handle_t handle, void** addr) +{ + Mutex::Autolock _l(mLock); + status_t err = mAllocMod->map(mAllocMod, handle, addr); + LOGW_IF(err, "map(...) failed %d (%s)", err, strerror(-err)); + return err; +} + +status_t BufferMapper::unmap(buffer_handle_t handle) +{ + Mutex::Autolock _l(mLock); + status_t err = mAllocMod->unmap(mAllocMod, handle); + LOGW_IF(err, "unmap(...) failed %d (%s)", err, strerror(-err)); + return err; +} + +status_t BufferMapper::lock(buffer_handle_t handle, int usage, const Rect& bounds) +{ + status_t err = mAllocMod->lock(mAllocMod, handle, usage, + bounds.left, bounds.top, bounds.width(), bounds.height()); + LOGW_IF(err, "unlock(...) failed %d (%s)", err, strerror(-err)); + return err; +} + +status_t BufferMapper::unlock(buffer_handle_t handle) +{ + status_t err = mAllocMod->unlock(mAllocMod, handle); + LOGW_IF(err, "unlock(...) failed %d (%s)", err, strerror(-err)); + return err; +} + +// --------------------------------------------------------------------------- +}; // namespace android diff --git a/libs/ui/EGLDisplaySurface.cpp b/libs/ui/EGLDisplaySurface.cpp deleted file mode 100644 index d06c98b9bb4db..0000000000000 --- a/libs/ui/EGLDisplaySurface.cpp +++ /dev/null @@ -1,519 +0,0 @@ -/* - ** - ** Copyright 2007 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. - */ - -#define LOG_TAG "EGLDisplaySurface" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - -#if HAVE_ANDROID_OS -#include -#endif - -#include - -#include - - -// ---------------------------------------------------------------------------- - -egl_native_window_t* android_createDisplaySurface() -{ - egl_native_window_t* s = new android::EGLDisplaySurface(); - s->memory_type = NATIVE_MEMORY_TYPE_GPU; - return s; -} - -#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true )) -#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false )) - -// ---------------------------------------------------------------------------- -namespace android { -// ---------------------------------------------------------------------------- - -EGLDisplaySurface::EGLDisplaySurface() - : EGLNativeSurface() -{ - egl_native_window_t::version = sizeof(egl_native_window_t); - egl_native_window_t::ident = 0; - egl_native_window_t::incRef = &EGLDisplaySurface::hook_incRef; - egl_native_window_t::decRef = &EGLDisplaySurface::hook_decRef; - egl_native_window_t::swapBuffers = &EGLDisplaySurface::hook_swapBuffers; - egl_native_window_t::connect = 0; - egl_native_window_t::disconnect = 0; - - mFb[0].data = 0; - mFb[1].data = 0; - mBlitEngine = 0; - egl_native_window_t::fd = mapFrameBuffer(); - if (egl_native_window_t::fd >= 0) { - - hw_module_t const* module; - if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) { - copybit_open(module, &mBlitEngine); - } - - const float in2mm = 25.4f; - float refreshRate = 1000000000000000LLU / ( - float( mInfo.upper_margin + mInfo.lower_margin + mInfo.yres ) - * ( mInfo.left_margin + mInfo.right_margin + mInfo.xres ) - * mInfo.pixclock); - - const GGLSurface& buffer = mFb[1 - mIndex]; - egl_native_window_t::width = buffer.width; - egl_native_window_t::height = buffer.height; - egl_native_window_t::stride = buffer.stride; - egl_native_window_t::format = buffer.format; - egl_native_window_t::base = intptr_t(mFb[0].data); - egl_native_window_t::offset = - intptr_t(buffer.data) - egl_native_window_t::base; - egl_native_window_t::flags = 0; - egl_native_window_t::xdpi = (mInfo.xres * in2mm) / mInfo.width; - egl_native_window_t::ydpi = (mInfo.yres * in2mm) / mInfo.height; - egl_native_window_t::fps = refreshRate; - egl_native_window_t::memory_type = NATIVE_MEMORY_TYPE_FB; - // no error, set the magic word - egl_native_window_t::magic = 0x600913; - } - mSwapCount = -1; - mPageFlipCount = 0; -} - -EGLDisplaySurface::~EGLDisplaySurface() -{ - magic = 0; - copybit_close(mBlitEngine); - mBlitEngine = 0; - close(egl_native_window_t::fd); - munmap(mFb[0].data, mSize); - if (!(mFlags & PAGE_FLIP)) - free((void*)mFb[1].data); -} - -void EGLDisplaySurface::hook_incRef(NativeWindowType window) { - EGLDisplaySurface* that = static_cast(window); - that->incStrong(that); -} -void EGLDisplaySurface::hook_decRef(NativeWindowType window) { - EGLDisplaySurface* that = static_cast(window); - that->decStrong(that); -} -uint32_t EGLDisplaySurface::hook_swapBuffers(NativeWindowType window) { - EGLDisplaySurface* that = static_cast(window); - return that->swapBuffers(); -} - -void EGLDisplaySurface::setSwapRectangle(int l, int t, int w, int h) -{ - mInfo.reserved[0] = 0x54445055; // "UPDT"; - mInfo.reserved[1] = (uint16_t)l | ((uint32_t)t << 16); - mInfo.reserved[2] = (uint16_t)(l+w) | ((uint32_t)(t+h) << 16); -} - -uint32_t EGLDisplaySurface::swapBuffers() -{ -#define SHOW_FPS 0 -#if SHOW_FPS - nsecs_t now = systemTime(); - if (mSwapCount == -1) { - mTime = now; - mSwapCount = 0; - mSleep = 0; - } else { - nsecs_t d = now-mTime; - if (d >= seconds(1)) { - double fps = (mSwapCount * double(seconds(1))) / double(d); - LOGD("%f fps, sleep=%d / frame", - fps, (int)ns2us(mSleep / mSwapCount)); - mSwapCount = 0; - mTime = now; - mSleep = 0; - } else { - mSwapCount++; - } - } -#endif - /* If we can't do the page_flip, just copy the back buffer to the front */ - if (!(mFlags & PAGE_FLIP)) { - memcpy(mFb[0].data, mFb[1].data, mInfo.xres*mInfo.yres*2); - return 0; - } - - // do the actual flip - mIndex = 1 - mIndex; - mInfo.activate = FB_ACTIVATE_VBL; - mInfo.yoffset = mIndex ? mInfo.yres : 0; - if (ioctl(egl_native_window_t::fd, FBIOPUT_VSCREENINFO, &mInfo) == -1) { - LOGE("FBIOPUT_VSCREENINFO failed"); - return 0; - } - - /* - * this is a monstrous hack: Because the h/w accelerator is not able - * to render directly into the framebuffer, we need to copy its - * internal framebuffer out to the fb. - * oem[0] is used to access the fd of internal fb. - * All this is needed only in standalone mode, in SurfaceFlinger mode - * we control where the GPU renders. - * We do this only if we have copybit, since this hack is needed only - * with msm7k. - */ - if (egl_native_window_t::memory_type == NATIVE_MEMORY_TYPE_GPU && oem[0] && mBlitEngine) { - copybit_device_t *copybit = mBlitEngine; - copybit_rect_t sdrect = { 0, 0, - egl_native_window_t::width, egl_native_window_t::height }; - copybit_image_t dst = { - egl_native_window_t::width, - egl_native_window_t::height, - egl_native_window_t::format, - egl_native_window_t::offset, - (void*)egl_native_window_t::base, - egl_native_window_t::fd - }; - copybit_image_t src = { - egl_native_window_t::width, - egl_native_window_t::height, - egl_native_window_t::format, // XXX: use proper format - egl_native_window_t::offset, - (void*)egl_native_window_t::base, // XXX: use proper base - egl_native_window_t::oem[0] - }; - region_iterator it(Region(Rect( - egl_native_window_t::width, egl_native_window_t::height))); - copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0); - copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF); - copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE); - copybit->stretch(copybit, &dst, &src, &sdrect, &sdrect, &it); - } - - // update the address of the buffer to draw to next - const GGLSurface& buffer = mFb[1 - mIndex]; - egl_native_window_t::offset = - intptr_t(buffer.data) - egl_native_window_t::base; - -#if SHOW_FPS - mSleep += systemTime()-now; -#endif - - mPageFlipCount++; - - // We don't support screen-size changes for now - return 0; -} - -int32_t EGLDisplaySurface::getPageFlipCount() const -{ - return mPageFlipCount; -} - -void EGLDisplaySurface::copyFrontToBack(const Region& copyback) -{ -#if HAVE_ANDROID_OS - if (mBlitEngine) { - copybit_image_t dst = { - w: egl_native_window_t::stride, - h: egl_native_window_t::height, - format: egl_native_window_t::format, - offset: mFb[1-mIndex].data - mFb[0].data, - base: (void*)egl_native_window_t::base, - fd: egl_native_window_t::fd - }; - copybit_image_t src = { - w: egl_native_window_t::stride, - h: egl_native_window_t::height, - format: egl_native_window_t::format, - offset: mFb[mIndex].data - mFb[0].data, - base: (void*)egl_native_window_t::base, - fd: egl_native_window_t::fd - }; - region_iterator it(copyback); - mBlitEngine->blit(mBlitEngine, &dst, &src, &it); - } else -#endif - { - /* no extra copy needed since we copied back to front instead of - * flipping */ - if (!(mFlags & PAGE_FLIP)) { - return; - } - - Region::iterator iterator(copyback); - if (iterator) { - Rect r; - uint8_t* const screen_src = mFb[ mIndex].data; - uint8_t* const screen_dst = mFb[1-mIndex].data; - const size_t bpp = bytesPerPixel(egl_native_window_t::format); - const size_t bpr = egl_native_window_t::stride * bpp; - while (iterator.iterate(&r)) { - ssize_t h = r.bottom - r.top; - if (h) { - size_t size = (r.right - r.left) * bpp; - size_t o = (r.left + egl_native_window_t::stride * r.top) * bpp; - uint8_t* s = screen_src + o; - uint8_t* d = screen_dst + o; - if (size == bpr) { - size *= h; - h = 1; - } - do { - memcpy(d, s, size); - d += bpr; - s += bpr; - } while (--h > 0); - } - } - } - } -} - -void EGLDisplaySurface::copyFrontToImage(const copybit_image_t& dst) -{ -#if HAVE_ANDROID_OS - if (mBlitEngine) { - copybit_image_t src = { - w: egl_native_window_t::stride, - h: egl_native_window_t::height, - format: egl_native_window_t::format, - offset: mFb[mIndex].data - mFb[0].data, - base: (void*)egl_native_window_t::base, - fd: egl_native_window_t::fd - }; - region_iterator it(Region(Rect( - egl_native_window_t::width, egl_native_window_t::height))); - mBlitEngine->blit(mBlitEngine, &dst, &src, &it); - } else -#endif - { - uint8_t* const screen_src = mFb[ mIndex].data; - const size_t bpp = bytesPerPixel(egl_native_window_t::format); - const size_t bpr = egl_native_window_t::stride * bpp; - memcpy((char*)dst.base + dst.offset, screen_src, - bpr*egl_native_window_t::height); - } -} - -void EGLDisplaySurface::copyBackToImage(const copybit_image_t& dst) -{ -#if HAVE_ANDROID_OS - if (mBlitEngine) { - copybit_image_t src = { - w: egl_native_window_t::stride, - h: egl_native_window_t::height, - format: egl_native_window_t::format, - offset: mFb[1-mIndex].data - mFb[0].data, - base: (void*)egl_native_window_t::base, - fd: egl_native_window_t::fd - }; - region_iterator it(Region(Rect( - egl_native_window_t::width, egl_native_window_t::height))); - mBlitEngine->blit(mBlitEngine, &dst, &src, &it); - } else -#endif - { - uint8_t* const screen_src = mFb[1-mIndex].data; - const size_t bpp = bytesPerPixel(egl_native_window_t::format); - const size_t bpr = egl_native_window_t::stride * bpp; - memcpy((char*)dst.base + dst.offset, screen_src, - bpr*egl_native_window_t::height); - } -} - - -status_t EGLDisplaySurface::mapFrameBuffer() -{ - char const * const device_template[] = { - "/dev/graphics/fb%u", - "/dev/fb%u", - 0 }; - int fd = -1; - int i=0; - char name[64]; - while ((fd==-1) && device_template[i]) { - snprintf(name, 64, device_template[i], 0); - fd = open(name, O_RDWR, 0); - i++; - } - if (fd < 0) - return -errno; - - struct fb_fix_screeninfo finfo; - if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1) - return -errno; - - struct fb_var_screeninfo info; - if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1) - return -errno; - - info.reserved[0] = 0; - info.reserved[1] = 0; - info.reserved[2] = 0; - info.xoffset = 0; - info.yoffset = 0; - info.yres_virtual = info.yres * 2; - info.bits_per_pixel = 16; - /* Explicitly request 5/6/5 */ - info.red.offset = 11; - info.red.length = 5; - info.green.offset = 5; - info.green.length = 6; - info.blue.offset = 0; - info.blue.length = 5; - info.transp.offset = 0; - info.transp.length = 0; - info.activate = FB_ACTIVATE_NOW; - - uint32_t flags = PAGE_FLIP; - if (ioctl(fd, FBIOPUT_VSCREENINFO, &info) == -1) { - info.yres_virtual = info.yres; - flags &= ~PAGE_FLIP; - LOGW("FBIOPUT_VSCREENINFO failed, page flipping not supported"); - } - - if (info.yres_virtual < info.yres * 2) { - info.yres_virtual = info.yres; - flags &= ~PAGE_FLIP; - LOGW("page flipping not supported (yres_virtual=%d, requested=%d)", - info.yres_virtual, info.yres*2); - } - - if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1) - return -errno; - - int refreshRate = 1000000000000000LLU / - ( - uint64_t( info.upper_margin + info.lower_margin + info.yres ) - * ( info.left_margin + info.right_margin + info.xres ) - * info.pixclock - ); - - if (refreshRate == 0) { - // bleagh, bad info from the driver - refreshRate = 60*1000; // 60 Hz - } - if (int(info.width) <= 0 || int(info.height) <= 0) { - // the driver doesn't return that information - // default to 160 dpi - info.width = ((info.xres * 25.4f)/160.0f + 0.5f); - info.height = ((info.yres * 25.4f)/160.0f + 0.5f); - } - - float xdpi = (info.xres * 25.4f) / info.width; - float ydpi = (info.yres * 25.4f) / info.height; - float fps = refreshRate / 1000.0f; - - LOGI( "using (fd=%d)\n" - "id = %s\n" - "xres = %d px\n" - "yres = %d px\n" - "xres_virtual = %d px\n" - "yres_virtual = %d px\n" - "bpp = %d\n" - "r = %2u:%u\n" - "g = %2u:%u\n" - "b = %2u:%u\n", - fd, - finfo.id, - info.xres, - info.yres, - info.xres_virtual, - info.yres_virtual, - info.bits_per_pixel, - info.red.offset, info.red.length, - info.green.offset, info.green.length, - info.blue.offset, info.blue.length - ); - - LOGI( "width = %d mm (%f dpi)\n" - "height = %d mm (%f dpi)\n" - "refresh rate = %.2f Hz\n", - info.width, xdpi, - info.height, ydpi, - fps - ); - - - if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1) - return -errno; - - if (finfo.smem_len <= 0) - return -errno; - - /* - * Open and map the display. - */ - - void* buffer = (uint16_t*) mmap( - 0, finfo.smem_len, - PROT_READ | PROT_WRITE, - MAP_SHARED, - fd, 0); - - if (buffer == MAP_FAILED) - return -errno; - - // at least for now, always clear the fb - memset(buffer, 0, finfo.smem_len); - - uint8_t* offscreen[2]; - offscreen[0] = (uint8_t*)buffer; - if (flags & PAGE_FLIP) { - offscreen[1] = (uint8_t*)buffer + finfo.line_length*info.yres; - } else { - offscreen[1] = (uint8_t*)malloc(finfo.smem_len); - if (offscreen[1] == 0) { - munmap(buffer, finfo.smem_len); - return NO_MEMORY; - } - } - - mFlags = flags; - mInfo = info; - mFinfo = finfo; - mSize = finfo.smem_len; - mIndex = 0; - for (int i=0 ; i<2 ; i++) { - mFb[i].version = sizeof(GGLSurface); - mFb[i].width = info.xres; - mFb[i].height = info.yres; - mFb[i].stride = finfo.line_length / (info.bits_per_pixel >> 3); - mFb[i].data = (GGLubyte*)(offscreen[i]); - mFb[i].format = GGL_PIXEL_FORMAT_RGB_565; - } - return fd; -} - -// ---------------------------------------------------------------------------- -}; // namespace android -// ---------------------------------------------------------------------------- diff --git a/libs/ui/EGLNativeWindowSurface.cpp b/libs/ui/EGLNativeWindowSurface.cpp index f1071cf9097b4..5d9d6a4328aa0 100644 --- a/libs/ui/EGLNativeWindowSurface.cpp +++ b/libs/ui/EGLNativeWindowSurface.cpp @@ -20,142 +20,225 @@ #include #include #include +#include #include #include +#include #include -#include #include +#include #include #include +#include -#include +#include +#include // ---------------------------------------------------------------------------- namespace android { // ---------------------------------------------------------------------------- -EGLNativeWindowSurface::EGLNativeWindowSurface(const sp& surface) - : EGLNativeSurface(), - mSurface(surface), mConnected(false) -{ - egl_native_window_t::magic = 0x600913; - egl_native_window_t::version = sizeof(egl_native_window_t); - egl_native_window_t::ident = 0; - egl_native_window_t::incRef = &EGLNativeWindowSurface::hook_incRef; - egl_native_window_t::decRef = &EGLNativeWindowSurface::hook_decRef; - egl_native_window_t::swapBuffers = &EGLNativeWindowSurface::hook_swapBuffers; - egl_native_window_t::connect = &EGLNativeWindowSurface::hook_connect; - egl_native_window_t::disconnect = &EGLNativeWindowSurface::hook_disconnect; - - DisplayInfo dinfo; - SurfaceComposerClient::getDisplayInfo(0, &dinfo); - egl_native_window_t::xdpi = dinfo.xdpi; - egl_native_window_t::ydpi = dinfo.ydpi; - egl_native_window_t::fps = dinfo.fps; - egl_native_window_t::flags= EGL_NATIVES_FLAG_DESTROY_BACKBUFFER; -} +/* + * This implements the (main) framebuffer management. This class is used + * mostly by SurfaceFlinger, but also by command line GL application. + * + * In fact this is an implementation of android_native_window_t on top of + * the framebuffer. + * + * Currently it is pretty simple, it manages only two buffers (the front and + * back buffer). + * + */ -EGLNativeWindowSurface::~EGLNativeWindowSurface() +FramebufferNativeWindow::FramebufferNativeWindow() + : BASE(), fbDev(0), grDev(0) { - disconnect(); - mSurface.clear(); - magic = 0; -} + hw_module_t const* module; + if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) { + int stride; + framebuffer_open(module, &fbDev); + gralloc_open(module, &grDev); + int err; -void EGLNativeWindowSurface::hook_incRef(NativeWindowType window) -{ - EGLNativeWindowSurface* that = static_cast(window); - that->incStrong(that); -} + + // initialize the buffer FIFO + mNumBuffers = 2; + mNumFreeBuffers = 2; + mBufferHead = mNumBuffers-1; + buffers[0] = new NativeBuffer( + fbDev->width, fbDev->height, fbDev->format, GRALLOC_USAGE_HW_FB); + buffers[1] = new NativeBuffer( + fbDev->width, fbDev->height, fbDev->format, GRALLOC_USAGE_HW_FB); + + err = grDev->alloc(grDev, + fbDev->width, fbDev->height, fbDev->format, + GRALLOC_USAGE_HW_FB, &buffers[0]->handle, &buffers[0]->stride); -void EGLNativeWindowSurface::hook_decRef(NativeWindowType window) -{ - EGLNativeWindowSurface* that = static_cast(window); - that->decStrong(that); -} + LOGE_IF(err, "fb buffer 0 allocation failed w=%d, h=%d, err=%s", + fbDev->width, fbDev->height, strerror(-err)); -void EGLNativeWindowSurface::hook_connect(NativeWindowType window) -{ - EGLNativeWindowSurface* that = static_cast(window); - that->connect(); -} + err = grDev->alloc(grDev, + fbDev->width, fbDev->height, fbDev->format, + GRALLOC_USAGE_HW_FB, &buffers[1]->handle, &buffers[1]->stride); -void EGLNativeWindowSurface::hook_disconnect(NativeWindowType window) -{ - EGLNativeWindowSurface* that = static_cast(window); - that->disconnect(); -} + LOGE_IF(err, "fb buffer 1 allocation failed w=%d, h=%d, err=%s", + fbDev->width, fbDev->height, strerror(-err)); -uint32_t EGLNativeWindowSurface::hook_swapBuffers(NativeWindowType window) -{ - EGLNativeWindowSurface* that = static_cast(window); - return that->swapBuffers(); -} + gralloc_module_t* m = + reinterpret_cast(grDev->common.module); -void EGLNativeWindowSurface::setSwapRectangle(int l, int t, int w, int h) -{ - mSurface->setSwapRectangle(Rect(l, t, l+w, t+h)); -} - -uint32_t EGLNativeWindowSurface::swapBuffers() -{ - const int w = egl_native_window_t::width; - const int h = egl_native_window_t::height; - const sp& surface(mSurface); - Surface::SurfaceInfo info; - surface->unlockAndPost(); - surface->lock(&info); - // update the address of the buffer to draw to next - egl_native_window_t::base = intptr_t(info.base); - egl_native_window_t::offset = intptr_t(info.bits) - intptr_t(info.base); - - // update size if it changed - if (w != int(info.w) || h != int(info.h)) { - egl_native_window_t::width = info.w; - egl_native_window_t::height = info.h; - egl_native_window_t::stride = info.bpr / bytesPerPixel(info.format); - egl_native_window_t::format = info.format; - return EGL_NATIVES_FLAG_SIZE_CHANGED; + // FIXME: do we actually need to map the framebuffer? + m->map(m, buffers[0]->handle, &buffers[0]->bits); + m->map(m, buffers[1]->handle, &buffers[1]->bits); } + + uint32_t flags = fbDev->flags & SURFACE_FLAG_MAPPED; + + /* + * FIXME: SURFACE_FLAG_PRESERVE_CONTENT + * how to implement this, there is no concept of preserve content in + * the framebuffer, which just "posts" buffer. + * + * It looks like what we need is a way to know if the posted buffer can + * be reused. But if so, why allocating 2 buffers?... + * + * should the lock/unlock calls take care of the copy-back? + * + * + * In the end, the client wants to know if the backbuffer is preserved + * though... it's complicated. + * + */ + + //flags |= SURFACE_FLAG_PRESERVE_CONTENT; + + + const_cast(android_native_window_t::flags) = flags; + const_cast(android_native_window_t::xdpi) = fbDev->xdpi; + const_cast(android_native_window_t::ydpi) = fbDev->ydpi; + const_cast(android_native_window_t::minSwapInterval) = + fbDev->minSwapInterval; + const_cast(android_native_window_t::maxSwapInterval) = + fbDev->maxSwapInterval; + + android_native_window_t::connect = connect; + android_native_window_t::disconnect = disconnect; + android_native_window_t::setSwapInterval = setSwapInterval; + android_native_window_t::setSwapRectangle = setSwapRectangle; + android_native_window_t::dequeueBuffer = dequeueBuffer; + android_native_window_t::lockBuffer = lockBuffer; + android_native_window_t::queueBuffer = queueBuffer; +} + +FramebufferNativeWindow::~FramebufferNativeWindow() { + grDev->free(grDev, buffers[0]->handle); + grDev->free(grDev, buffers[1]->handle); + gralloc_module_t* m = + reinterpret_cast(grDev->common.module); + m->unmap(m, buffers[0]->handle); + m->unmap(m, buffers[1]->handle); + gralloc_close(grDev); + framebuffer_close(fbDev); +} + +void FramebufferNativeWindow::connect(android_native_window_t* window) +{ +} + +void FramebufferNativeWindow::disconnect(android_native_window_t* window) +{ +} + +int FramebufferNativeWindow::setSwapInterval( + android_native_window_t* window, int interval) +{ + framebuffer_device_t* fb = getSelf(window)->fbDev; + return fb->setSwapInterval(fb, interval); +} + +int FramebufferNativeWindow::setSwapRectangle(android_native_window_t* window, + int l, int t, int w, int h) +{ + FramebufferNativeWindow* self = getSelf(window); + Mutex::Autolock _l(self->mutex); + self->mDirty = Rect(l, t, l+w, t+h); return 0; } -void EGLNativeWindowSurface::connect() -{ - if (!mConnected) { - Surface::SurfaceInfo info; - mSurface->lock(&info); - mSurface->setSwapRectangle(Rect(info.w, info.h)); - mConnected = true; +int FramebufferNativeWindow::dequeueBuffer(android_native_window_t* window, + android_native_buffer_t** buffer) +{ + FramebufferNativeWindow* self = getSelf(window); + Mutex::Autolock _l(self->mutex); + framebuffer_device_t* fb = self->fbDev; - egl_native_window_t::width = info.w; - egl_native_window_t::height = info.h; - egl_native_window_t::stride = info.bpr / bytesPerPixel(info.format); - egl_native_window_t::format = info.format; - egl_native_window_t::base = intptr_t(info.base); - egl_native_window_t::offset = intptr_t(info.bits) - intptr_t(info.base); - // FIXME: egl_native_window_t::memory_type used to be set from - // mSurface, but we wanted to break this dependency. We set it to - // GPU because the software rendered doesn't care, but the h/w - // accelerator needs it. Eventually, this value should go away - // completely, since memory will be managed by OpenGL. - egl_native_window_t::memory_type = NATIVE_MEMORY_TYPE_GPU; - egl_native_window_t::fd = 0; + // wait for a free buffer + while (!self->mNumFreeBuffers) { + self->mCondition.wait(self->mutex); } + // get this buffer + self->mNumFreeBuffers--; + int index = self->mBufferHead++; + if (self->mBufferHead >= self->mNumBuffers) + self->mBufferHead = 0; + + *buffer = self->buffers[index].get(); + + return 0; } -void EGLNativeWindowSurface::disconnect() +int FramebufferNativeWindow::lockBuffer(android_native_window_t* window, + android_native_buffer_t* buffer) { - if (mConnected) { - mSurface->unlock(); - mConnected = false; + FramebufferNativeWindow* self = getSelf(window); + Mutex::Autolock _l(self->mutex); + + // wait that the buffer we're locking is not front anymore + while (self->front == buffer) { + self->mCondition.wait(self->mutex); } + + gralloc_module_t* m = + reinterpret_cast(self->grDev->common.module); + const Rect& dirty(self->mDirty); + + buffer_handle_t handle = static_cast(buffer)->handle; + int res = m->lock(m, handle, GRALLOC_USAGE_HW_FB, + dirty.left, dirty.right, dirty.width(), dirty.height()); + + return res; +} + +int FramebufferNativeWindow::queueBuffer(android_native_window_t* window, + android_native_buffer_t* buffer) +{ + FramebufferNativeWindow* self = getSelf(window); + Mutex::Autolock _l(self->mutex); + framebuffer_device_t* fb = self->fbDev; + gralloc_module_t* m = + reinterpret_cast(self->grDev->common.module); + + buffer_handle_t handle = static_cast(buffer)->handle; + m->unlock(m, handle); + int res = fb->post(fb, handle); + + self->front = static_cast(buffer); + self->mNumFreeBuffers++; + self->mCondition.broadcast(); + return res; } // ---------------------------------------------------------------------------- }; // namespace android // ---------------------------------------------------------------------------- + + +EGLNativeWindowType android_createDisplaySurface(void) +{ + return new android::FramebufferNativeWindow(); +} + diff --git a/libs/ui/ISurface.cpp b/libs/ui/ISurface.cpp index d5e9f812a40b1..fcea8ec70121b 100644 --- a/libs/ui/ISurface.cpp +++ b/libs/ui/ISurface.cpp @@ -14,6 +14,8 @@ * limitations under the License. */ +#define LOG_TAG "ISurface" + #include #include #include @@ -23,10 +25,13 @@ #include #include +#include namespace android { +// ---------------------------------------------------------------------- + ISurface::BufferHeap::BufferHeap() : w(0), h(0), hor_stride(0), ver_stride(0), format(0), transform(0), flags(0) @@ -55,6 +60,8 @@ ISurface::BufferHeap::~BufferHeap() { } +// ---------------------------------------------------------------------- + class BpSurface : public BpInterface { public: @@ -63,6 +70,15 @@ public: { } + virtual sp getBuffer() + { + Parcel data, reply; + data.writeInterfaceToken(ISurface::getInterfaceDescriptor()); + remote()->transact(GET_BUFFER, data, &reply); + sp buffer = new SurfaceBuffer(reply); + return buffer; + } + virtual status_t registerBuffers(const BufferHeap& buffers) { Parcel data, reply; @@ -122,6 +138,11 @@ status_t BnSurface::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { switch(code) { + case GET_BUFFER: { + CHECK_INTERFACE(ISurface, data, reply); + sp buffer(getBuffer()); + return SurfaceBuffer::writeToParcel(reply, buffer.get()); + } case REGISTER_BUFFERS: { CHECK_INTERFACE(ISurface, data, reply); BufferHeap buffer; diff --git a/libs/ui/ISurfaceComposer.cpp b/libs/ui/ISurfaceComposer.cpp index 76597e1712592..1932bf90b2e92 100644 --- a/libs/ui/ISurfaceComposer.cpp +++ b/libs/ui/ISurfaceComposer.cpp @@ -114,36 +114,6 @@ public: remote()->transact(BnSurfaceComposer::BOOT_FINISHED, data, &reply); } - virtual status_t requestGPU( - const sp& callback, gpu_info_t* gpu) - { - Parcel data, reply; - data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); - data.writeStrongBinder(callback->asBinder()); - remote()->transact(BnSurfaceComposer::REQUEST_GPU, data, &reply); - gpu->regs = interface_cast(reply.readStrongBinder()); - gpu->count = reply.readInt32(); - - // FIXME: for now, we don't dynamically allocate the regions array - size_t maxCount = sizeof(gpu->regions)/sizeof(*gpu->regions); - if (gpu->count > maxCount) - return BAD_VALUE; - - for (size_t i=0 ; icount ; i++) { - gpu->regions[i].region = interface_cast(reply.readStrongBinder()); - gpu->regions[i].reserved = reply.readInt32(); - } - return reply.readInt32(); - } - - virtual status_t revokeGPU() - { - Parcel data, reply; - data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); - remote()->transact(BnSurfaceComposer::REVOKE_GPU, data, &reply); - return reply.readInt32(); - } - virtual void signal() const { Parcel data, reply; @@ -201,9 +171,6 @@ status_t BnSurfaceComposer::onTransact( case BOOT_FINISHED: { bootFinished(); } break; - case REVOKE_GPU: { - reply->writeInt32( revokeGPU() ); - } break; case SIGNAL: { signal(); } break; @@ -211,26 +178,6 @@ status_t BnSurfaceComposer::onTransact( sp b = getCblk()->asBinder(); reply->writeStrongBinder(b); } break; - case REQUEST_GPU: { - // TODO: this should be protected by a permission - gpu_info_t info; - sp callback - = interface_cast(data.readStrongBinder()); - status_t res = requestGPU(callback, &info); - - // FIXME: for now, we don't dynamically allocate the regions array - size_t maxCount = sizeof(info.regions)/sizeof(*info.regions); - if (info.count > maxCount) - return BAD_VALUE; - - reply->writeStrongBinder(info.regs->asBinder()); - reply->writeInt32(info.count); - for (size_t i=0 ; iwriteStrongBinder(info.regions[i].region->asBinder()); - reply->writeInt32(info.regions[i].reserved); - } - reply->writeInt32(res); - } break; default: return UNKNOWN_TRANSACTION; } @@ -239,41 +186,4 @@ status_t BnSurfaceComposer::onTransact( // ---------------------------------------------------------------------------- -enum { - // Note: BOOT_FINISHED must remain this value, it is called by ActivityManagerService. - GPU_LOST = IBinder::FIRST_CALL_TRANSACTION -}; - -class BpGPUCallback : public BpInterface -{ -public: - BpGPUCallback(const sp& impl) - : BpInterface(impl) - { - } - - virtual void gpuLost() - { - Parcel data, reply; - data.writeInterfaceToken(IGPUCallback::getInterfaceDescriptor()); - remote()->transact(GPU_LOST, data, &reply, IBinder::FLAG_ONEWAY); - } -}; - -IMPLEMENT_META_INTERFACE(GPUCallback, "android.ui.IGPUCallback"); - -status_t BnGPUCallback::onTransact( - uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) -{ - switch(code) { - case GPU_LOST: { - CHECK_INTERFACE(IGPUCallback, data, reply); - gpuLost(); - return NO_ERROR; - } break; - default: - return BBinder::onTransact(code, data, reply, flags); - } -} - }; diff --git a/libs/ui/ISurfaceFlingerClient.cpp b/libs/ui/ISurfaceFlingerClient.cpp index dd6a798b9899a..597b87eb471f2 100644 --- a/libs/ui/ISurfaceFlingerClient.cpp +++ b/libs/ui/ISurfaceFlingerClient.cpp @@ -191,8 +191,6 @@ status_t ISurfaceFlingerClient::surface_data_t::readFromParcel(const Parcel& par { token = parcel.readInt32(); identity = parcel.readInt32(); - heap[0] = interface_cast(parcel.readStrongBinder()); - heap[1] = interface_cast(parcel.readStrongBinder()); return NO_ERROR; } @@ -200,8 +198,6 @@ status_t ISurfaceFlingerClient::surface_data_t::writeToParcel(Parcel* parcel) co { parcel->writeInt32(token); parcel->writeInt32(identity); - parcel->writeStrongBinder(heap[0]!=0 ? heap[0]->asBinder() : NULL); - parcel->writeStrongBinder(heap[1]!=0 ? heap[1]->asBinder() : NULL); return NO_ERROR; } diff --git a/libs/ui/Overlay.cpp b/libs/ui/Overlay.cpp index b236edc290f58..59c65146e5d33 100644 --- a/libs/ui/Overlay.cpp +++ b/libs/ui/Overlay.cpp @@ -129,12 +129,8 @@ OverlayRef::OverlayRef(overlay_handle_t handle, const sp& channel, OverlayRef::~OverlayRef() { if (mOwnHandle) { - /* FIXME: handles should be promoted to "real" API and be handled by - * the framework */ - for (int i=0 ; inumFds ; i++) { - close(mOverlayHandle->data[i]); - } - free((void*)mOverlayHandle); + native_handle_close(mOverlayHandle); + native_handle_delete(const_cast(mOverlayHandle)); } } @@ -147,7 +143,7 @@ sp OverlayRef::readFromParcel(const Parcel& data) { uint32_t f = data.readInt32(); uint32_t ws = data.readInt32(); uint32_t hs = data.readInt32(); - native_handle* handle = data.readNativeHandle(NULL, NULL); + native_handle* handle = data.readNativeHandle(); result = new OverlayRef(); result->mOverlayHandle = handle; @@ -169,7 +165,7 @@ status_t OverlayRef::writeToParcel(Parcel* reply, const sp& o) { reply->writeInt32(o->mFormat); reply->writeInt32(o->mWidthStride); reply->writeInt32(o->mHeightStride); - reply->writeNativeHandle(*(o->mOverlayHandle)); + reply->writeNativeHandle(o->mOverlayHandle); } else { reply->writeStrongBinder(NULL); } diff --git a/libs/ui/Surface.cpp b/libs/ui/Surface.cpp index 4ea9ae2edbc0a..357e4d0d5e5b3 100644 --- a/libs/ui/Surface.cpp +++ b/libs/ui/Surface.cpp @@ -23,24 +23,126 @@ #include #include -#include #include #include #include #include #include +#include +#include +#include #include #include #include #include +#include + #include #include +#include + namespace android { -// --------------------------------------------------------------------------- +// ============================================================================ +// SurfaceBuffer +// ============================================================================ + +SurfaceBuffer::SurfaceBuffer() + : BASE(), handle(0), mOwner(false) +{ + width = + height = + stride = + format = + usage = 0; + android_native_buffer_t::getHandle = getHandle; +} + +SurfaceBuffer::SurfaceBuffer(const Parcel& data) + : BASE(), handle(0), mOwner(true) +{ + // we own the handle in this case + width = data.readInt32(); + height = data.readInt32(); + stride = data.readInt32(); + format = data.readInt32(); + usage = data.readInt32(); + handle = data.readNativeHandle(); + android_native_buffer_t::getHandle = getHandle; +} + +SurfaceBuffer::~SurfaceBuffer() +{ + if (handle && mOwner) { + native_handle_close(handle); + native_handle_delete(const_cast(handle)); + } +} + +int SurfaceBuffer::getHandle(android_native_buffer_t const * base, + buffer_handle_t* handle) +{ + *handle = getSelf(base)->handle; + return 0; +} + +status_t SurfaceBuffer::writeToParcel(Parcel* reply, + android_native_buffer_t const* buffer) +{ + buffer_handle_t handle; + status_t err = buffer->getHandle(buffer, &handle); + if (err < 0) { + return err; + } + reply->writeInt32(buffer->width); + reply->writeInt32(buffer->height); + reply->writeInt32(buffer->stride); + reply->writeInt32(buffer->format); + reply->writeInt32(buffer->usage); + reply->writeNativeHandle(handle); + return NO_ERROR; +} + +// ---------------------------------------------------------------------- + +static void copyBlt(const android_native_buffer_t* dst, + const android_native_buffer_t* src, const Region& reg) +{ + Region::iterator iterator(reg); + if (iterator) { + // NOTE: dst and src must be the same format + Rect r; + const size_t bpp = bytesPerPixel(src->format); + const size_t dbpr = dst->stride * bpp; + const size_t sbpr = src->stride * bpp; + while (iterator.iterate(&r)) { + ssize_t h = r.bottom - r.top; + if (h) { + size_t size = (r.right - r.left) * bpp; + uint8_t* s = (GGLubyte*)src->bits + + (r.left + src->stride * r.top) * bpp; + uint8_t* d = (GGLubyte*)dst->bits + + (r.left + dst->stride * r.top) * bpp; + if (dbpr==sbpr && size==sbpr) { + size *= h; + h = 1; + } + do { + memcpy(d, s, size); + d += dbpr; + s += sbpr; + } while (--h > 0); + } + } + } +} + +// ============================================================================ +// Surface +// ============================================================================ Surface::Surface(const sp& client, const sp& surface, @@ -51,26 +153,44 @@ Surface::Surface(const sp& client, mToken(data.token), mIdentity(data.identity), mFormat(format), mFlags(flags), mOwner(owner) { + android_native_window_t::connect = connect; + android_native_window_t::disconnect = disconnect; + android_native_window_t::setSwapInterval = setSwapInterval; + android_native_window_t::setSwapRectangle = setSwapRectangle; + android_native_window_t::dequeueBuffer = dequeueBuffer; + android_native_window_t::lockBuffer = lockBuffer; + android_native_window_t::queueBuffer = queueBuffer; + mSwapRectangle.makeInvalid(); - mSurfaceHeapBase[0] = 0; - mSurfaceHeapBase[1] = 0; - mHeap[0] = data.heap[0]; - mHeap[1] = data.heap[1]; + + DisplayInfo dinfo; + SurfaceComposerClient::getDisplayInfo(0, &dinfo); + const_cast(android_native_window_t::xdpi) = dinfo.xdpi; + const_cast(android_native_window_t::ydpi) = dinfo.ydpi; + // FIXME: set real values here + const_cast(android_native_window_t::minSwapInterval) = 1; + const_cast(android_native_window_t::maxSwapInterval) = 1; + const_cast(android_native_window_t::flags) = 0; } Surface::Surface(Surface const* rhs) : mOwner(false) { - mToken = rhs->mToken; - mIdentity= rhs->mIdentity; - mClient = rhs->mClient; - mSurface = rhs->mSurface; - mHeap[0] = rhs->mHeap[0]; - mHeap[1] = rhs->mHeap[1]; - mFormat = rhs->mFormat; - mFlags = rhs->mFlags; - mSurfaceHeapBase[0] = rhs->mSurfaceHeapBase[0]; - mSurfaceHeapBase[1] = rhs->mSurfaceHeapBase[1]; + // FIXME: we really should get rid of this ctor. the memcpy below + //should be safe for now, but android_native_window_t is not supposed + // to be clonable. + memcpy( static_cast(this), + static_cast(rhs), + sizeof(android_native_window_t)); + + mToken = rhs->mToken; + mIdentity = rhs->mIdentity; + mClient = rhs->mClient; + mSurface = rhs->mSurface; + mBuffers[0] = rhs->mBuffers[0]; + mBuffers[1] = rhs->mBuffers[1]; + mFormat = rhs->mFormat; + mFlags = rhs->mFlags; mSwapRectangle.makeInvalid(); } @@ -78,21 +198,26 @@ Surface::~Surface() { if (mOwner && mToken>=0 && mClient!=0) { mClient->destroySurface(mToken); + if (mBuffers[0] != 0) { + BufferMapper::get().unmap(mBuffers[0]->getHandle()); + } + if (mBuffers[1] != 0) { + BufferMapper::get().unmap(mBuffers[1]->getHandle()); + } } mClient.clear(); mSurface.clear(); - mHeap[0].clear(); - mHeap[1].clear(); IPCThreadState::self()->flushCommands(); } sp Surface::dup() const { + // FIXME: we should get rid of Surface::dup() Surface const * r = this; if (this && mOwner) { // the only reason we need to do this is because of Java's garbage // collector: because we're creating a copy of the Surface - // instead of a reference, we can garantee that when our last + // instead of a reference, we can guarantee that when our last // reference goes away, the real surface will be deleted. // Without this hack (the code is correct too), we'd have to // wait for a GC for the surface to go away. @@ -101,31 +226,244 @@ sp Surface::dup() const return const_cast(r); } -status_t Surface::nextBuffer(SurfaceInfo* info) { - return mClient->nextBuffer(this, info); +status_t Surface::validate(per_client_cblk_t const* cblk) const +{ + if (cblk == 0) { + LOGE("cblk is null (surface id=%d, identity=%u)", mToken, mIdentity); + return NO_INIT; + } + status_t err = cblk->validate(mToken); + if (err != NO_ERROR) { + LOGE("surface (id=%d, identity=%u) is invalid, err=%d (%s)", + mToken, mIdentity, err, strerror(-err)); + return err; + } + if (mIdentity != uint32_t(cblk->layers[mToken].identity)) { + LOGE("using an invalid surface id=%d, identity=%u should be %d", + mToken, mIdentity, cblk->layers[mToken].identity); + return NO_INIT; + } + return NO_ERROR; } +// ---------------------------------------------------------------------------- + +int Surface::setSwapRectangle(android_native_window_t* window, + int l, int t, int w, int h) +{ + Surface* self = getSelf(window); + self->setSwapRectangle(Rect(l, t, l+w, t+h)); + return 0; +} + +void Surface::connect(android_native_window_t* window) +{ +} + +void Surface::disconnect(android_native_window_t* window) +{ +} + +int Surface::setSwapInterval(android_native_window_t* window, int interval) +{ + return 0; +} + +int Surface::dequeueBuffer(android_native_window_t* window, + android_native_buffer_t** buffer) +{ + Surface* self = getSelf(window); + return self->dequeueBuffer(buffer); +} + +int Surface::lockBuffer(android_native_window_t* window, + android_native_buffer_t* buffer) +{ + Surface* self = getSelf(window); + return self->lockBuffer(buffer); +} + +int Surface::queueBuffer(android_native_window_t* window, + android_native_buffer_t* buffer) +{ + Surface* self = getSelf(window); + return self->queueBuffer(buffer); +} + +// ---------------------------------------------------------------------------- + +int Surface::dequeueBuffer(android_native_buffer_t** buffer) +{ + // FIXME: dequeueBuffer() needs proper implementation + + Mutex::Autolock _l(mSurfaceLock); + + per_client_cblk_t* const cblk = mClient->mControl; + status_t err = validate(cblk); + if (err != NO_ERROR) + return err; + + SurfaceID index(mToken); + + int32_t backIdx = cblk->lock_layer(size_t(index), + per_client_cblk_t::BLOCKING); + + if (backIdx < 0) + return status_t(backIdx); + + mBackbufferIndex = backIdx; + layer_cblk_t* const lcblk = &(cblk->layers[index]); + + volatile const surface_info_t* const back = lcblk->surface + backIdx; + if (back->flags & surface_info_t::eNeedNewBuffer) { + getBufferLocked(backIdx); + } + + const sp& backBuffer(mBuffers[backIdx]); + *buffer = backBuffer.get(); + + return NO_ERROR; +} + +int Surface::lockBuffer(android_native_buffer_t* buffer) +{ + // FIXME: lockBuffer() needs proper implementation + return 0; +} + +int Surface::queueBuffer(android_native_buffer_t* buffer) +{ + Mutex::Autolock _l(mSurfaceLock); + + per_client_cblk_t* const cblk = mClient->mControl; + status_t err = validate(cblk); + if (err != NO_ERROR) + return err; + + // transmit the dirty region + const Region dirty(swapRectangle()); + SurfaceID index(mToken); + layer_cblk_t* const lcblk = &(cblk->layers[index]); + _send_dirty_region(lcblk, dirty); + + uint32_t newstate = cblk->unlock_layer_and_post(size_t(index)); + if (!(newstate & eNextFlipPending)) + mClient->signalServer(); + + return NO_ERROR; +} + +// ---------------------------------------------------------------------------- + status_t Surface::lock(SurfaceInfo* info, bool blocking) { return Surface::lock(info, NULL, blocking); } -status_t Surface::lock(SurfaceInfo* info, Region* dirty, bool blocking) { - if (heapBase(0) == 0) return INVALID_OPERATION; - if (heapBase(1) == 0) return INVALID_OPERATION; - return mClient->lockSurface(this, info, dirty, blocking); +status_t Surface::lock(SurfaceInfo* other, Region* dirty, bool blocking) +{ + // FIXME: needs some locking here + android_native_buffer_t* backBuffer; + status_t err = dequeueBuffer(&backBuffer); + if (err == NO_ERROR) { + err = lockBuffer(backBuffer); + if (err == NO_ERROR) { + backBuffer->common.incRef(&backBuffer->common); + mLockedBuffer = backBuffer; + other->w = backBuffer->width; + other->h = backBuffer->height; + other->s = backBuffer->stride; + other->usage = backBuffer->usage; + other->format = backBuffer->format; + other->bits = backBuffer->bits; + + // we handle copy-back here... + + const Rect bounds(backBuffer->width, backBuffer->height); + Region newDirtyRegion; + + per_client_cblk_t* const cblk = mClient->mControl; + layer_cblk_t* const lcblk = &(cblk->layers[SurfaceID(mToken)]); + volatile const surface_info_t* const back = lcblk->surface + mBackbufferIndex; + if (back->flags & surface_info_t::eBufferDirty) { + // content is meaningless in this case and the whole surface + // needs to be redrawn. + newDirtyRegion.set(bounds); + if (dirty) { + *dirty = newDirtyRegion; + } + } else + { + if (dirty) { + dirty->andSelf(Region(bounds)); + newDirtyRegion = *dirty; + } else { + newDirtyRegion.set(bounds); + } + Region copyback; + if (!(lcblk->flags & eNoCopyBack)) { + const Region previousDirtyRegion(dirtyRegion()); + copyback = previousDirtyRegion.subtract(newDirtyRegion); + } + const sp& frontBuffer(mBuffers[1-mBackbufferIndex]); + if (!copyback.isEmpty() && frontBuffer!=0) { + // copy front to back + copyBlt(backBuffer, frontBuffer.get(), copyback); + } + } + setDirtyRegion(newDirtyRegion); + + + Rect lockBounds(backBuffer->width, backBuffer->height); + if (dirty) { + lockBounds = dirty->bounds(); + } + buffer_handle_t handle; + backBuffer->getHandle(backBuffer, &handle); + status_t res = BufferMapper::get().lock(handle, + GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, + lockBounds); + LOGW_IF(res, "failed locking buffer %d (%p)", + mBackbufferIndex, handle); + setSwapRectangle(lockBounds); + } + } + return err; +} + +status_t Surface::unlockAndPost() +{ + // FIXME: needs some locking here + + if (mLockedBuffer == 0) + return BAD_VALUE; + + buffer_handle_t handle; + mLockedBuffer->getHandle(mLockedBuffer, &handle); + status_t res = BufferMapper::get().unlock(handle); + LOGW_IF(res, "failed unlocking buffer %d (%p)", + mBackbufferIndex, handle); + + const Rect dirty(dirtyRegion().bounds()); + setSwapRectangle(dirty); + status_t err = queueBuffer(mLockedBuffer); + mLockedBuffer->common.decRef(&mLockedBuffer->common); + mLockedBuffer = 0; + return err; } -status_t Surface::unlockAndPost() { - if (heapBase(0) == 0) return INVALID_OPERATION; - if (heapBase(1) == 0) return INVALID_OPERATION; - return mClient->unlockAndPostSurface(this); +void Surface::_send_dirty_region( + layer_cblk_t* lcblk, const Region& dirty) +{ + const int32_t index = (lcblk->flags & eBufferIndex) >> eBufferIndexShift; + flat_region_t* flat_region = lcblk->region + index; + status_t err = dirty.write(flat_region, sizeof(flat_region_t)); + if (err < NO_ERROR) { + // region doesn't fit, use the bounds + const Region reg(dirty.bounds()); + reg.write(flat_region, sizeof(flat_region_t)); + } } -status_t Surface::unlock() { - if (heapBase(0) == 0) return INVALID_OPERATION; - if (heapBase(1) == 0) return INVALID_OPERATION; - return mClient->unlockSurface(this); -} status_t Surface::setLayer(int32_t layer) { return mClient->setLayer(this, layer); @@ -183,8 +521,6 @@ sp Surface::readFromParcel(Parcel* parcel) ISurfaceFlingerClient::surface_data_t data; sp clientBinder= parcel->readStrongBinder(); sp surface = interface_cast(parcel->readStrongBinder()); - data.heap[0] = interface_cast(parcel->readStrongBinder()); - data.heap[1] = interface_cast(parcel->readStrongBinder()); data.token = parcel->readInt32(); data.identity = parcel->readInt32(); PixelFormat format = parcel->readInt32(); @@ -204,21 +540,16 @@ status_t Surface::writeToParcel(const sp& surface, Parcel* parcel) uint32_t identity = 0; sp client; sp sur; - sp heap[2]; if (surface->isValid()) { token = surface->mToken; identity = surface->mIdentity; client = surface->mClient; sur = surface->mSurface; - heap[0] = surface->mHeap[0]; - heap[1] = surface->mHeap[1]; format = surface->mFormat; flags = surface->mFlags; } parcel->writeStrongBinder(client!=0 ? client->connection() : NULL); parcel->writeStrongBinder(sur!=0 ? sur->asBinder() : NULL); - parcel->writeStrongBinder(heap[0]!=0 ? heap[0]->asBinder() : NULL); - parcel->writeStrongBinder(heap[1]!=0 ? heap[1]->asBinder() : NULL); parcel->writeInt32(token); parcel->writeInt32(identity); parcel->writeInt32(format); @@ -233,23 +564,24 @@ bool Surface::isSameSurface(const sp& lhs, const sp& rhs) return lhs->mSurface->asBinder() == rhs->mSurface->asBinder(); } -void* Surface::heapBase(int i) const +status_t Surface::getBufferLocked(int index) { - void* heapBase = mSurfaceHeapBase[i]; - // map lazily so it doesn't get mapped in clients that don't need it - if (heapBase == 0) { - const sp& heap(mHeap[i]); - if (heap != 0) { - heapBase = static_cast(heap->base()); - if (heapBase == MAP_FAILED) { - heapBase = NULL; - LOGE("Couldn't map Surface's heap (binder=%p, heap=%p)", - heap->asBinder().get(), heap.get()); - } - mSurfaceHeapBase[i] = heapBase; + status_t err = NO_MEMORY; + sp buffer = mSurface->getBuffer(); + LOGE_IF(buffer==0, "ISurface::getBuffer() returned NULL"); + if (buffer != 0) { + sp& currentBuffer(mBuffers[index]); + if (currentBuffer != 0) { + BufferMapper::get().unmap(currentBuffer->getHandle()); + currentBuffer.clear(); + } + err = BufferMapper::get().map(buffer->getHandle(), &buffer->bits); + LOGW_IF(err, "map(...) failed %d (%s)", err, strerror(-err)); + if (err == NO_ERROR) { + currentBuffer = buffer; } } - return heapBase; + return err; } }; // namespace android diff --git a/libs/ui/SurfaceComposerClient.cpp b/libs/ui/SurfaceComposerClient.cpp index fe803ff24964f..e1b13c7b8eed9 100644 --- a/libs/ui/SurfaceComposerClient.cpp +++ b/libs/ui/SurfaceComposerClient.cpp @@ -29,27 +29,21 @@ #include #include #include -#include #include #include #include +#include #include #include #include #include -#include #include -#include #include #include #include -#include - -#include - #define VERBOSE(...) ((void)0) //#define VERBOSE LOGD @@ -109,50 +103,8 @@ static volatile surface_flinger_cblk_t const * get_cblk() // --------------------------------------------------------------------------- -static void copyBlt(const GGLSurface& dst, - const GGLSurface& src, const Region& reg) -{ - Region::iterator iterator(reg); - if (iterator) { - // NOTE: dst and src must be the same format - Rect r; - const size_t bpp = bytesPerPixel(src.format); - const size_t dbpr = dst.stride * bpp; - const size_t sbpr = src.stride * bpp; - while (iterator.iterate(&r)) { - ssize_t h = r.bottom - r.top; - if (h) { - size_t size = (r.right - r.left) * bpp; - uint8_t* s = src.data + (r.left + src.stride * r.top) * bpp; - uint8_t* d = dst.data + (r.left + dst.stride * r.top) * bpp; - if (dbpr==sbpr && size==sbpr) { - size *= h; - h = 1; - } - do { - memcpy(d, s, size); - d += dbpr; - s += sbpr; - } while (--h > 0); - } - } - } -} - -// --------------------------------------------------------------------------- - -surface_flinger_cblk_t::surface_flinger_cblk_t() -{ -} - -// --------------------------------------------------------------------------- - -per_client_cblk_t::per_client_cblk_t() -{ -} - // these functions are used by the clients -inline status_t per_client_cblk_t::validate(size_t i) const { +status_t per_client_cblk_t::validate(size_t i) const { if (uint32_t(i) >= NUM_LAYERS_MAX) return BAD_INDEX; if (layers[i].swapState & eInvalidSurface) @@ -248,8 +200,9 @@ int32_t per_client_cblk_t::lock_layer(size_t i, uint32_t flags) index = (state&eIndex) ^ ((state&eFlipRequested)>>1); // make sure this buffer is valid - if (layer->surface[index].bits_offset < 0) { - return status_t(layer->surface[index].bits_offset); + status_t err = layer->surface[index].status; + if (err < 0) { + return err; } if (inspect) { @@ -273,7 +226,7 @@ done: uint32_t per_client_cblk_t::unlock_layer_and_post(size_t i) { - // atomically set eFlipRequested and clear eLocked and optionnaly + // atomically set eFlipRequested and clear eLocked and optionally // set eNextFlipPending if eFlipRequested was already set layer_cblk_t * const layer = layers + i; @@ -290,7 +243,7 @@ uint32_t per_client_cblk_t::unlock_layer_and_post(size_t i) if (oldvalue & eFlipRequested) newvalue |= eNextFlipPending; - // if eFlipRequested was alread set, set eNextFlipPending + // if eFlipRequested was already set, set eNextFlipPending } while (android_atomic_cmpxchg(oldvalue, newvalue, &(layer->swapState))); @@ -298,9 +251,9 @@ uint32_t per_client_cblk_t::unlock_layer_and_post(size_t i) int(i), int((layer->flags & eBufferIndex) >> eBufferIndexShift), int(newvalue)); - // from this point, the server can kick in at anytime and use the first + // from this point, the server can kick in at any time and use the first // buffer, so we cannot use it anymore, and we must use the 'other' - // buffer instead (or wait if it is not availlable yet, see lock_layer). + // buffer instead (or wait if it is not available yet, see lock_layer). return newvalue; } @@ -376,32 +329,6 @@ status_t SurfaceComposerClient::initCheck() const return mStatus; } -status_t SurfaceComposerClient::validateSurface( - per_client_cblk_t const* cblk, Surface const * surface) -{ - SurfaceID index = surface->ID(); - if (cblk == 0) { - LOGE("cblk is null (surface id=%d, identity=%u)", - index, surface->getIdentity()); - return NO_INIT; - } - - status_t err = cblk->validate(index); - if (err != NO_ERROR) { - LOGE("surface (id=%d, identity=%u) is invalid, err=%d (%s)", - index, surface->getIdentity(), err, strerror(-err)); - return err; - } - - if (surface->getIdentity() != uint32_t(cblk->layers[index].identity)) { - LOGE("using an invalid surface id=%d, identity=%u should be %d", - index, surface->getIdentity(), cblk->layers[index].identity); - return NO_INIT; - } - - return NO_ERROR; -} - sp SurfaceComposerClient::connection() const { return (mClient != 0) ? mClient->asBinder() : 0; @@ -439,7 +366,6 @@ void SurfaceComposerClient::dispose() sp controlMemory; sp client; - sp surfaceHeap; { Mutex::Autolock _lg(gLock); @@ -462,9 +388,7 @@ void SurfaceComposerClient::dispose() delete mPrebuiltLayerState; mPrebuiltLayerState = 0; controlMemory = mControlMemory; - surfaceHeap = mSurfaceHeap; mControlMemory.clear(); - mSurfaceHeap.clear(); mControl = 0; mStatus = NO_INIT; } @@ -528,6 +452,12 @@ ssize_t SurfaceComposerClient::getNumberOfDisplays() return n; } + +void SurfaceComposerClient::signalServer() +{ + mSignalServer->signal(); +} + sp SurfaceComposerClient::createSurface( int pid, DisplayID display, @@ -568,186 +498,6 @@ status_t SurfaceComposerClient::destroySurface(SurfaceID sid) return err; } -status_t SurfaceComposerClient::nextBuffer(Surface* surface, - Surface::SurfaceInfo* info) -{ - SurfaceID index = surface->ID(); - per_client_cblk_t* const cblk = mControl; - status_t err = validateSurface(cblk, surface); - if (err != NO_ERROR) - return err; - - int32_t backIdx = surface->mBackbufferIndex; - layer_cblk_t* const lcblk = &(cblk->layers[index]); - const surface_info_t* const front = lcblk->surface + (1-backIdx); - info->w = front->w; - info->h = front->h; - info->format = front->format; - info->base = surface->heapBase(1-backIdx); - info->bits = reinterpret_cast(intptr_t(info->base) + front->bits_offset); - info->bpr = front->bpr; - - return 0; -} - -status_t SurfaceComposerClient::lockSurface( - Surface* surface, - Surface::SurfaceInfo* other, - Region* dirty, - bool blocking) -{ - Mutex::Autolock _l(surface->getLock()); - - SurfaceID index = surface->ID(); - per_client_cblk_t* const cblk = mControl; - status_t err = validateSurface(cblk, surface); - if (err != NO_ERROR) - return err; - - int32_t backIdx = cblk->lock_layer(size_t(index), - per_client_cblk_t::BLOCKING); - if (backIdx >= 0) { - surface->mBackbufferIndex = backIdx; - layer_cblk_t* const lcblk = &(cblk->layers[index]); - const surface_info_t* const back = lcblk->surface + backIdx; - const surface_info_t* const front = lcblk->surface + (1-backIdx); - other->w = back->w; - other->h = back->h; - other->format = back->format; - other->base = surface->heapBase(backIdx); - other->bits = reinterpret_cast(intptr_t(other->base) + back->bits_offset); - other->bpr = back->bpr; - - const Rect bounds(other->w, other->h); - Region newDirtyRegion; - - if (back->flags & surface_info_t::eBufferDirty) { - /* it is safe to write *back here, because we're guaranteed - * SurfaceFlinger is not touching it (since it just granted - * access to us) */ - const_cast(back)->flags &= - ~surface_info_t::eBufferDirty; - - // content is meaningless in this case and the whole surface - // needs to be redrawn. - - newDirtyRegion.set(bounds); - if (dirty) { - *dirty = newDirtyRegion; - } - - //if (bytesPerPixel(other->format) == 4) { - // android_memset32( - // (uint32_t*)other->bits, 0xFF00FF00, other->h * other->bpr); - //} else { - // android_memset16( // fill with green - // (uint16_t*)other->bits, 0x7E0, other->h * other->bpr); - //} - } - else - { - if (dirty) { - dirty->andSelf(Region(bounds)); - newDirtyRegion = *dirty; - } else { - newDirtyRegion.set(bounds); - } - - Region copyback; - if (!(lcblk->flags & eNoCopyBack)) { - const Region previousDirtyRegion(surface->dirtyRegion()); - copyback = previousDirtyRegion.subtract(newDirtyRegion); - } - - if (!copyback.isEmpty()) { - // copy front to back - GGLSurface cb; - cb.version = sizeof(GGLSurface); - cb.width = back->w; - cb.height = back->h; - cb.stride = back->stride; - cb.data = (GGLubyte*)surface->heapBase(backIdx); - cb.data += back->bits_offset; - cb.format = back->format; - - GGLSurface t; - t.version = sizeof(GGLSurface); - t.width = front->w; - t.height = front->h; - t.stride = front->stride; - t.data = (GGLubyte*)surface->heapBase(1-backIdx); - t.data += front->bits_offset; - t.format = front->format; - - //const Region copyback(lcblk->region + 1-backIdx); - copyBlt(cb, t, copyback); - } - } - - // update dirty region - surface->setDirtyRegion(newDirtyRegion); - } - return (backIdx < 0) ? status_t(backIdx) : status_t(NO_ERROR); -} - -void SurfaceComposerClient::_signal_server() -{ - mSignalServer->signal(); -} - -void SurfaceComposerClient::_send_dirty_region( - layer_cblk_t* lcblk, const Region& dirty) -{ - const int32_t index = (lcblk->flags & eBufferIndex) >> eBufferIndexShift; - flat_region_t* flat_region = lcblk->region + index; - status_t err = dirty.write(flat_region, sizeof(flat_region_t)); - if (err < NO_ERROR) { - // region doesn't fit, use the bounds - const Region reg(dirty.bounds()); - reg.write(flat_region, sizeof(flat_region_t)); - } -} - -status_t SurfaceComposerClient::unlockAndPostSurface(Surface* surface) -{ - Mutex::Autolock _l(surface->getLock()); - - SurfaceID index = surface->ID(); - per_client_cblk_t* const cblk = mControl; - status_t err = validateSurface(cblk, surface); - if (err != NO_ERROR) - return err; - - Region dirty(surface->dirtyRegion()); - const Rect& swapRect(surface->swapRectangle()); - if (swapRect.isValid()) { - dirty.set(swapRect); - } - - // transmit the dirty region - layer_cblk_t* const lcblk = &(cblk->layers[index]); - _send_dirty_region(lcblk, dirty); - uint32_t newstate = cblk->unlock_layer_and_post(size_t(index)); - if (!(newstate & eNextFlipPending)) - _signal_server(); - return NO_ERROR; -} - -status_t SurfaceComposerClient::unlockSurface(Surface* surface) -{ - Mutex::Autolock _l(surface->getLock()); - - SurfaceID index = surface->ID(); - per_client_cblk_t* const cblk = mControl; - status_t err = validateSurface(cblk, surface); - if (err != NO_ERROR) - return err; - - layer_cblk_t* const lcblk = &(cblk->layers[index]); - cblk->unlock_layer(size_t(index)); - return NO_ERROR; -} - void SurfaceComposerClient::openGlobalTransaction() { Mutex::Autolock _l(gLock); @@ -870,7 +620,7 @@ layer_state_t* SurfaceComposerClient::_get_state_l(const sp& surface) { SurfaceID index = surface->ID(); per_client_cblk_t* const cblk = mControl; - status_t err = validateSurface(cblk, surface.get()); + status_t err = surface->validate(cblk); if (err != NO_ERROR) return 0; @@ -973,7 +723,6 @@ status_t SurfaceComposerClient::setFlags(Surface* surface, return NO_ERROR; } - status_t SurfaceComposerClient::setTransparentRegionHint( Surface* surface, const Region& transparentRegion) { diff --git a/libs/utils/Parcel.cpp b/libs/utils/Parcel.cpp index 0f4b6473008d3..e74ad4ad8ea5c 100644 --- a/libs/utils/Parcel.cpp +++ b/libs/utils/Parcel.cpp @@ -650,28 +650,26 @@ status_t Parcel::writeWeakBinder(const wp& val) return flatten_binder(ProcessState::self(), val, this); } -status_t Parcel::writeNativeHandle(const native_handle& handle) +status_t Parcel::writeNativeHandle(const native_handle* handle) { - if (handle.version != sizeof(native_handle)) + if (handle->version != sizeof(native_handle)) return BAD_TYPE; status_t err; - err = writeInt32(handle.numFds); + err = writeInt32(handle->numFds); if (err != NO_ERROR) return err; - err = writeInt32(handle.numInts); + err = writeInt32(handle->numInts); if (err != NO_ERROR) return err; - for (int i=0 ; err==NO_ERROR && inumFds ; i++) + err = writeDupFileDescriptor(handle->data[i]); if (err != NO_ERROR) { LOGD("write native handle, write dup fd failed"); return err; } - - err = write(handle.data + handle.numFds, sizeof(int)*handle.numInts); - + err = write(handle->data + handle->numFds, sizeof(int)*handle->numInts); return err; } @@ -928,7 +926,7 @@ wp Parcel::readWeakBinder() const } -native_handle* Parcel::readNativeHandle(native_handle* (*alloc)(void*, int, int), void* cookie) const +native_handle* Parcel::readNativeHandle() const { int numFds, numInts; status_t err; @@ -937,31 +935,15 @@ native_handle* Parcel::readNativeHandle(native_handle* (*alloc)(void*, int, int) err = readInt32(&numInts); if (err != NO_ERROR) return 0; - native_handle* h; - if (alloc == 0) { - size_t size = sizeof(native_handle) + sizeof(int)*(numFds + numInts); - h = (native_handle*)malloc(size); - h->version = sizeof(native_handle); - h->numFds = numFds; - h->numInts = numInts; - } else { - h = alloc(cookie, numFds, numInts); - if (h->version != sizeof(native_handle)) { - return 0; - } - } - + native_handle* h = native_handle_create(numFds, numInts); for (int i=0 ; err==NO_ERROR && idata[i] = dup(readFileDescriptor()); if (h->data[i] < 0) err = BAD_VALUE; } - err = read(h->data + numFds, sizeof(int)*numInts); - if (err != NO_ERROR) { - if (alloc == 0) { - free(h); - } + native_handle_close(h); + native_handle_delete(h); h = 0; } return h; diff --git a/opengl/include/EGL/android_natives.h b/opengl/include/EGL/android_natives.h new file mode 100644 index 0000000000000..e3c3b86e49f40 --- /dev/null +++ b/opengl/include/EGL/android_natives.h @@ -0,0 +1,265 @@ +/* + * Copyright (C) 2009 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. + */ + +#ifndef ANDROID_ANDROID_NATIVES_H +#define ANDROID_ANDROID_NATIVES_H + +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*****************************************************************************/ + +#define ANDROID_NATIVE_MAKE_CONSTANT(a,b,c,d) \ + (((unsigned)(a)<<24)|((unsigned)(b)<<16)|((unsigned)(c)<<8)|(unsigned)(d)) + +#define ANDROID_NATIVE_WINDOW_MAGIC \ + ANDROID_NATIVE_MAKE_CONSTANT('_','w','n','d') + +#define ANDROID_NATIVE_BUFFER_MAGIC \ + ANDROID_NATIVE_MAKE_CONSTANT('_','b','f','r') + +// --------------------------------------------------------------------------- + +struct android_native_buffer_t; + +enum { + /* attributes of this surface or its updater */ + SURFACE_FLAG_PRESERVE_CONTENT = FRAMEBUFFER_RESERVED0, + SURFACE_FLAG_MAPPED = FRAMEBUFFER_FLAG_MAPPED, +}; + + +// --------------------------------------------------------------------------- + +struct android_native_base_t +{ + /* a magic value defined by the actual EGL native type */ + int magic; + + /* the sizeof() of the actual EGL native type */ + int version; + + void* reserved[4]; + + /* reference-counting interface */ + void (*incRef)(struct android_native_base_t* base); + void (*decRef)(struct android_native_base_t* base); +}; + + +struct android_native_window_t +{ +#ifdef __cplusplus + android_native_window_t() + : flags(0), minSwapInterval(0), maxSwapInterval(0), xdpi(0), ydpi(0) + { + common.magic = ANDROID_NATIVE_WINDOW_MAGIC; + common.version = sizeof(android_native_window_t); + memset(common.reserved, 0, sizeof(common.reserved)); + } +#endif + + struct android_native_base_t common; + + /* flags describing some attributes of this surface or its updater */ + const uint32_t flags; + + /* min swap interval supported by this updated */ + const int minSwapInterval; + + /* max swap interval supported by this updated */ + const int maxSwapInterval; + + /* horizontal and vertical resolution in DPI */ + const float xdpi; + const float ydpi; + + /* Some storage reserved for the OEM's driver. */ + intptr_t oem[4]; + + /* + * hook called by EGL when the native surface is made current + * (eglMakeCurrent()). This hook can be NULL. + */ + void (*connect)(struct android_native_window_t* window); + + /* + * hook called by EGL when the native surface in not current any-longer. + * This hook can be NULL. + */ + void (*disconnect)(struct android_native_window_t* window); + + + /* + * Set the swap interval for this surface. + * + * Returns 0 on success or -errno on error. + */ + int (*setSwapInterval)(struct android_native_window_t* window, + int interval); + + + /* + * FIXME: needs documentation for setSwapRectangle + * tentative: rect used during queueBuffer to indicate which part of + * the screen needs updating. + */ + int (*setSwapRectangle)(struct android_native_window_t* window, + int left, int top, int width, int height); + + + /* + * hook called by EGL to acquire a buffer. After this call, the buffer + * is not locked, so its content cannot be modified. + * this call may block if no buffers are availlable. + * + * Returns 0 on success or -errno on error. + */ + int (*dequeueBuffer)(struct android_native_window_t* window, + struct android_native_buffer_t** buffer); + + /* + * hook called by EGL to lock a buffer. This MUST be called before modifying + * the content of a buffer. The buffer must have been acquired with + * dequeueBuffer first. + * + * Returns 0 on success or -errno on error. + */ + int (*lockBuffer)(struct android_native_window_t* window, + struct android_native_buffer_t* buffer); + /* + * hook called by EGL when modifications to the render buffer are done. + * This unlocks and post the buffer. + * + * Buffers MUST be queued in the same order than they were dequeued. + * + * Returns 0 on success or -errno on error. + */ + int (*queueBuffer)(struct android_native_window_t* window, + struct android_native_buffer_t* buffer); + + + void* reserved_proc[5]; +}; + + +struct android_native_buffer_t +{ +#ifdef __cplusplus + android_native_buffer_t() { + common.magic = ANDROID_NATIVE_BUFFER_MAGIC; + common.version = sizeof(android_native_buffer_t); + memset(common.reserved, 0, sizeof(common.reserved)); + } +#endif + + struct android_native_base_t common; + + int width; + int height; + int stride; + int format; + int usage; + void* bits; // non-zero if buffer is mmaped + + void* reserved[2]; + + int (*getHandle)(struct android_native_buffer_t const * base, + buffer_handle_t* handle); + + void* reserved_proc[7]; +}; + + +/* FIXME: this is legacy for pixmaps */ +struct egl_native_pixmap_t +{ + int32_t version; /* must be 32 */ + int32_t width; + int32_t height; + int32_t stride; + uint8_t* data; + uint8_t format; + uint8_t rfu[3]; + union { + uint32_t compressedFormat; + int32_t vstride; + }; + int32_t reserved; +}; + +/*****************************************************************************/ + +#ifdef __cplusplus +} +#endif + + +/*****************************************************************************/ + +#ifdef __cplusplus + +#include + +namespace android { + +/* + * This helper class turns an EGL android_native_xxx type into a C++ + * reference-counted object; with proper type conversions. + */ +template +class EGLNativeBase : public NATIVE_TYPE, public REF +{ +protected: + typedef EGLNativeBase BASE; + EGLNativeBase() : NATIVE_TYPE(), REF() { + NATIVE_TYPE::common.incRef = incRef; + NATIVE_TYPE::common.decRef = decRef; + } + static inline TYPE* getSelf(NATIVE_TYPE* self) { + return static_cast(self); + } + static inline TYPE const* getSelf(NATIVE_TYPE const* self) { + return static_cast(self); + } + static inline TYPE* getSelf(android_native_base_t* base) { + return getSelf(reinterpret_cast(base)); + } + static inline TYPE const * getSelf(android_native_base_t const* base) { + return getSelf(reinterpret_cast(base)); + } + static void incRef(android_native_base_t* base) { + EGLNativeBase* self = getSelf(base); + self->incStrong(self); + } + static void decRef(android_native_base_t* base) { + EGLNativeBase* self = getSelf(base); + self->decStrong(self); + } +}; + +} // namespace android +#endif // __cplusplus + +/*****************************************************************************/ + +#endif /* ANDROID_ANDROID_NATIVES_H */ diff --git a/opengl/include/EGL/eglplatform.h b/opengl/include/EGL/eglplatform.h index ac0090102c31f..d42808704dd67 100644 --- a/opengl/include/EGL/eglplatform.h +++ b/opengl/include/EGL/eglplatform.h @@ -89,12 +89,17 @@ typedef Window EGLNativeWindowType; #elif defined(ANDROID) -#include +#include -typedef struct egl_native_window_t* EGLNativeWindowType; +typedef struct android_native_window_t* EGLNativeWindowType; typedef struct egl_native_pixmap_t* EGLNativePixmapType; typedef void* EGLNativeDisplayType; +#ifndef EGL_ANDROID_image_native_buffer +#define EGL_ANDROID_image_native_buffer 1 +#define EGL_NATIVE_BUFFER_ANDROID 0x6000 /* eglCreateImageKHR target */ +#endif + #else #error "Platform not recognized" #endif diff --git a/opengl/include/GLES/glplatform.h b/opengl/include/GLES/glplatform.h index 0924caeaffe92..198e679db270f 100644 --- a/opengl/include/GLES/glplatform.h +++ b/opengl/include/GLES/glplatform.h @@ -28,12 +28,6 @@ #define GL_APIENTRY KHRONOS_APIENTRY -// XXX: this should probably not be here -#define GL_DIRECT_TEXTURE_2D_QUALCOMM 0x7E80 - -// XXX: not sure how this is intended to be used -#define GL_GLEXT_PROTOTYPES - #endif #endif /* __glplatform_h_ */ diff --git a/opengl/libagl/Android.mk b/opengl/libagl/Android.mk index 99efe4c41de8e..af5a700be377d 100644 --- a/opengl/libagl/Android.mk +++ b/opengl/libagl/Android.mk @@ -6,6 +6,9 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) +# Set to 1 to use gralloc and copybits +LIBAGL_USE_GRALLOC_COPYBITS := 1 + LOCAL_SRC_FILES:= \ egl.cpp \ state.cpp \ @@ -32,7 +35,15 @@ ifneq ($(TARGET_SIMULATOR),true) LOCAL_CFLAGS += -I$(LOCAL_PATH)/../../../../bionic/libc/private endif -LOCAL_SHARED_LIBRARIES := libcutils libutils libpixelflinger +ifeq ($(LIBAGL_USE_GRALLOC_COPYBITS),1) + LOCAL_CFLAGS += -DLIBAGL_USE_GRALLOC_COPYBITS -I$(LOCAL_PATH)/../../../../hardware/libhardware/modules/gralloc + LOCAL_SRC_FILES += copybit.cpp +endif + +LOCAL_CFLAGS += -DLOG_TAG=\"libagl\" +LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES + +LOCAL_SHARED_LIBRARIES := libcutils libhardware libutils libpixelflinger LOCAL_LDLIBS := -lpthread -ldl LOCAL_MODULE:= libagl diff --git a/opengl/libagl/TextureObjectManager.cpp b/opengl/libagl/TextureObjectManager.cpp index ce31854172d34..f927de95ecae1 100644 --- a/opengl/libagl/TextureObjectManager.cpp +++ b/opengl/libagl/TextureObjectManager.cpp @@ -1,16 +1,16 @@ /* ** Copyright 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 + ** 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 + ** 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 + ** 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. */ @@ -53,6 +53,9 @@ void EGLTextureObject::init() memset(crop_rect, 0, sizeof(crop_rect)); generate_mipmap = GL_FALSE; direct = GL_FALSE; +#ifdef LIBAGL_USE_GRALLOC_COPYBITS + copybits_fd = -1; +#endif // LIBAGL_USE_GRALLOC_COPYBITS } void EGLTextureObject::copyParameters(const sp& old) @@ -146,7 +149,7 @@ status_t EGLTextureObject::reallocate( int format, int compressedFormat, int bpr) { const size_t size = h * bpr; - if (level == 0) + if (level == 0) { if (size!=mSize || !surface.data) { if (mSize && surface.data) { @@ -177,9 +180,9 @@ status_t EGLTextureObject::reallocate( return NO_MEMORY; } - LOGW_IF(level-1 >= mNumExtraLod, + LOGW_IF(level-1 >= mNumExtraLod, "specifying mipmap level %d, but # of level is %d", - level, mNumExtraLod+1); + level, mNumExtraLod+1); GGLSurface& mipmap = editMip(level); if (mipmap.data) diff --git a/opengl/libagl/TextureObjectManager.h b/opengl/libagl/TextureObjectManager.h index 74ed1a45b24cc..497528c76b0e9 100644 --- a/opengl/libagl/TextureObjectManager.h +++ b/opengl/libagl/TextureObjectManager.h @@ -1,16 +1,16 @@ /* ** Copyright 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 +** 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 +** 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 +** 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. */ @@ -81,6 +81,9 @@ public: GLint crop_rect[4]; GLint generate_mipmap; GLint direct; +#ifdef LIBAGL_USE_GRALLOC_COPYBITS + int copybits_fd; +#endif // LIBAGL_USE_GRALLOC_COPYBITS }; void EGLTextureObject::incStrong(const void* id) const { diff --git a/opengl/libagl/array.cpp b/opengl/libagl/array.cpp index 8fa7566aacc04..eefe614c2fb75 100644 --- a/opengl/libagl/array.cpp +++ b/opengl/libagl/array.cpp @@ -1,16 +1,16 @@ -/* +/* ** Copyright 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 +** 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 +** 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 +** 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. */ @@ -26,6 +26,9 @@ #include "primitives.h" #include "texture.h" #include "BufferObjectManager.h" +#ifdef LIBAGL_USE_GRALLOC_COPYBITS +#include "copybit.h" +#endif // LIBAGL_USE_GRALLOC_COPYBITS // ---------------------------------------------------------------------------- @@ -250,7 +253,7 @@ static void fetchExpand3s(ogles_context_t*, GLfixed* v, const GLshort* p) { v[2] = GGL_S_TO_X(p[2]); } -typedef array_t::fetcher_t fn_t; +typedef array_t::fetcher_t fn_t; static const fn_t color_fct[2][16] = { // size={3,4}, type={ub,f,x} { 0, (fn_t)fetchExpand3ub, 0, 0, 0, 0, @@ -334,7 +337,7 @@ void array_t::init( this->bounds = count; } -inline void array_t::resolve() +inline void array_t::resolve() { physical_pointer = (bo) ? (bo->data + uintptr_t(pointer)) : pointer; } @@ -465,7 +468,7 @@ vertex_t* cache_vertex(ogles_context_t* c, vertex_t* v, uint32_t index) // We compute directly the index of a "free" entry from the locked // state of v[2] and v[3]. v = c->vc.vBuffer + 2; - v += v[0].locked | (v[1].locked<<1); + v += v[0].locked | (v[1].locked<<1); } // note: compileElement clears v->flags c->arrays.compileElement(c, v, index); @@ -480,7 +483,7 @@ vertex_t* fetch_vertex(ogles_context_t* c, size_t index) #if VC_CACHE_TYPE == VC_CACHE_TYPE_INDEXED - vertex_t* const v = c->vc.vCache + + vertex_t* const v = c->vc.vCache + (index & (vertex_cache_t::VERTEX_CACHE_SIZE-1)); if (ggl_likely(v->index == index)) { @@ -491,7 +494,7 @@ vertex_t* fetch_vertex(ogles_context_t* c, size_t index) #elif VC_CACHE_TYPE == VC_CACHE_TYPE_LRU - vertex_t* v = c->vc.vCache + + vertex_t* v = c->vc.vCache + (index & ((vertex_cache_t::VERTEX_CACHE_SIZE-1)>>1))*2; // always record LRU in v[0] @@ -532,12 +535,12 @@ void drawPrimitivesPoints(ogles_context_t* c, GLint first, GLsizei count) return; // vertex cache size must be multiple of 1 - const GLsizei vcs = + const GLsizei vcs = (vertex_cache_t::VERTEX_BUFFER_SIZE + vertex_cache_t::VERTEX_CACHE_SIZE); do { vertex_t* v = c->vc.vBuffer; - GLsizei num = count > vcs ? vcs : count; + GLsizei num = count > vcs ? vcs : count; c->arrays.cull = vertex_t::CLIP_ALL; c->arrays.compileElements(c, v, first, num); first += num; @@ -569,13 +572,13 @@ void drawPrimitivesLineStrip(ogles_context_t* c, GLint first, GLsizei count) count -= 1; // vertex cache size must be multiple of 1 - const GLsizei vcs = + const GLsizei vcs = (vertex_cache_t::VERTEX_BUFFER_SIZE + vertex_cache_t::VERTEX_CACHE_SIZE - 1); do { - v0 = c->vc.vBuffer + 0; + v0 = c->vc.vBuffer + 0; v = c->vc.vBuffer + 1; - GLsizei num = count > vcs ? vcs : count; + GLsizei num = count > vcs ? vcs : count; c->arrays.compileElements(c, v, first, num); first += num; count -= num; @@ -602,7 +605,7 @@ void drawPrimitivesLineLoop(ogles_context_t* c, GLint first, GLsizei count) return; drawPrimitivesLineStrip(c, first, count); if (ggl_likely(count >= 3)) { - vertex_t* v0 = c->vc.vBuffer; + vertex_t* v0 = c->vc.vBuffer; vertex_t* v1 = c->vc.vBuffer + 1; c->arrays.compileElement(c, v1, first); const uint32_t cc = v0->flags & v1->flags; @@ -617,12 +620,12 @@ void drawPrimitivesLines(ogles_context_t* c, GLint first, GLsizei count) return; // vertex cache size must be multiple of 2 - const GLsizei vcs = + const GLsizei vcs = ((vertex_cache_t::VERTEX_BUFFER_SIZE + vertex_cache_t::VERTEX_CACHE_SIZE) / 2) * 2; do { vertex_t* v = c->vc.vBuffer; - GLsizei num = count > vcs ? vcs : count; + GLsizei num = count > vcs ? vcs : count; c->arrays.cull = vertex_t::CLIP_ALL; c->arrays.compileElements(c, v, first, num); first += num; @@ -662,14 +665,14 @@ static void drawPrimitivesTriangleFanOrStrip(ogles_context_t* c, // because it allows us to preserve the same winding when the whole // batch is culled. We also need 2 extra vertices in the array, because // we always keep the two first ones. - const GLsizei vcs = + const GLsizei vcs = ((vertex_cache_t::VERTEX_BUFFER_SIZE + vertex_cache_t::VERTEX_CACHE_SIZE - 2) / 2) * 2; do { - v0 = c->vc.vBuffer + 0; - v1 = c->vc.vBuffer + 1; + v0 = c->vc.vBuffer + 0; + v1 = c->vc.vBuffer + 1; v = c->vc.vBuffer + 2; - GLsizei num = count > vcs ? vcs : count; + GLsizei num = count > vcs ? vcs : count; c->arrays.compileElements(c, v, first, num); first += num; count -= num; @@ -697,13 +700,19 @@ static void drawPrimitivesTriangleFanOrStrip(ogles_context_t* c, } while (count > 0); } -void drawPrimitivesTriangleStrip(ogles_context_t* c, +void drawPrimitivesTriangleStrip(ogles_context_t* c, GLint first, GLsizei count) { drawPrimitivesTriangleFanOrStrip(c, first, count, 1); } void drawPrimitivesTriangleFan(ogles_context_t* c, GLint first, GLsizei count) { +#ifdef LIBAGL_USE_GRALLOC_COPYBITS + if (drawTrangleFanWithCopybit(c, first, count)) { + return; + } +#endif // LIBAGL_USE_GRALLOC_COPYBITS + drawPrimitivesTriangleFanOrStrip(c, first, count, 2); } @@ -713,12 +722,12 @@ void drawPrimitivesTriangles(ogles_context_t* c, GLint first, GLsizei count) return; // vertex cache size must be multiple of 3 - const GLsizei vcs = + const GLsizei vcs = ((vertex_cache_t::VERTEX_BUFFER_SIZE + vertex_cache_t::VERTEX_CACHE_SIZE) / 3) * 3; do { vertex_t* v = c->vc.vBuffer; - GLsizei num = count > vcs ? vcs : count; + GLsizei num = count > vcs ? vcs : count; c->arrays.cull = vertex_t::CLIP_ALL; c->arrays.compileElements(c, v, first, num); first += num; @@ -779,11 +788,11 @@ void drawIndexedPrimitivesLineStrip(ogles_context_t* c, { if (ggl_unlikely(count < 2)) return; - + vertex_t * const v = c->vc.vBuffer; vertex_t* v0 = v; vertex_t* v1; - + const int type = (c->arrays.indicesType == GL_UNSIGNED_BYTE); c->arrays.compileElement(c, v0, read_index(type, indices)); count -= 1; @@ -806,11 +815,11 @@ void drawIndexedPrimitivesLineLoop(ogles_context_t* c, drawIndexedPrimitivesLines(c, count, indices); return; } - + vertex_t * const v = c->vc.vBuffer; vertex_t* v0 = v; vertex_t* v1; - + const int type = (c->arrays.indicesType == GL_UNSIGNED_BYTE); c->arrays.compileElement(c, v0, read_index(type, indices)); count -= 1; @@ -825,7 +834,7 @@ void drawIndexedPrimitivesLineLoop(ogles_context_t* c, } while (count); v1->locked = 0; - v1 = c->vc.vBuffer; + v1 = c->vc.vBuffer; const uint32_t cc = v0->flags & v1->flags; if (ggl_likely(!(cc & vertex_t::CLIP_ALL))) c->prims.renderLine(c, v0, v1); @@ -861,7 +870,7 @@ static void drawIndexedPrimitivesTriangleFanOrStrip(ogles_context_t* c, if (ggl_unlikely(count < 3)) return; - + vertex_t * const v = c->vc.vBuffer; vertex_t* v0 = v; vertex_t* v1 = v+1; @@ -981,17 +990,17 @@ void compileElements__3x_full(ogles_context_t* c, const GLfixed* vp = (const GLfixed*)c->arrays.vertex.element(first); const size_t stride = c->arrays.vertex.stride / 4; // const GLfixed* const& m = c->transforms.mvp.matrix.m; - + GLfixed m[16]; memcpy(&m, c->transforms.mvp.matrix.m, sizeof(m)); - + do { const GLfixed rx = vp[0]; const GLfixed ry = vp[1]; const GLfixed rz = vp[2]; vp += stride; v->index = first++; - v->clip.x = mla3a(rx, m[ 0], ry, m[ 4], rz, m[ 8], m[12]); + v->clip.x = mla3a(rx, m[ 0], ry, m[ 4], rz, m[ 8], m[12]); v->clip.y = mla3a(rx, m[ 1], ry, m[ 5], rz, m[ 9], m[13]); v->clip.z = mla3a(rx, m[ 2], ry, m[ 6], rz, m[10], m[14]); v->clip.w = mla3a(rx, m[ 3], ry, m[ 7], rz, m[11], m[15]); @@ -1019,7 +1028,7 @@ void compileElements__3x_full(ogles_context_t* c, #pragma mark clippers #endif -static void clipVec4(vec4_t& nv, +static void clipVec4(vec4_t& nv, GLfixed t, const vec4_t& s, const vec4_t& p) { for (int i=0; i<4 ; i++) @@ -1082,10 +1091,10 @@ void validate_arrays(ogles_context_t* c, GLenum mode) // automatically turn it off (in fact we could when the 4th coordinate // is not spcified in the vertex array). // W interpolation is never needed for points. - GLboolean perspective = + GLboolean perspective = c->perspective && mode!=GL_POINTS && (enables & GGL_ENABLE_TMUS); c->rasterizer.procs.enableDisable(c, GGL_W_LERP, perspective); - + // set anti-aliasing GLboolean smooth = GL_FALSE; switch (mode) { @@ -1116,7 +1125,7 @@ void validate_arrays(ogles_context_t* c, GLenum mode) if (enables & GGL_ENABLE_TMUS) { // needs texture transforms want |= transform_state_t::TEXTURE; } - if (c->clipPlanes.enable || (enables & GGL_ENABLE_FOG)) { + if (c->clipPlanes.enable || (enables & GGL_ENABLE_FOG)) { want |= transform_state_t::MODELVIEW; // needs eye coords } ogles_validate_transform(c, want); @@ -1135,18 +1144,18 @@ void validate_arrays(ogles_context_t* c, GLenum mode) c->arrays.mv_transform = c->transforms.modelview.transform.pointv[c->arrays.vertex.size - 2]; - + /* * *********************************************************************** * pick fetchers * *********************************************************************** */ - + array_machine_t& am = c->arrays; am.vertex.fetch = fetchNop; am.normal.fetch = currentNormal; am.color.fetch = currentColor; - + if (am.vertex.enable) { am.vertex.resolve(); if (am.vertex.bo || am.vertex.pointer) { @@ -1409,7 +1418,7 @@ void glDrawElements( // clear the vertex-cache c->vc.clear(); validate_arrays(c, mode); - + // if indices are in a buffer object, the pointer is treated as an // offset in that buffer. if (c->arrays.element_array_buffer) { @@ -1444,7 +1453,7 @@ void glBindBuffer(GLenum target, GLuint buffer) return; } } - ((target == GL_ARRAY_BUFFER) ? + ((target == GL_ARRAY_BUFFER) ? c->arrays.array_buffer : c->arrays.element_array_buffer) = bo; } @@ -1463,7 +1472,7 @@ void glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usa ogles_error(c, GL_INVALID_ENUM); return; } - buffer_t const* bo = ((target == GL_ARRAY_BUFFER) ? + buffer_t const* bo = ((target == GL_ARRAY_BUFFER) ? c->arrays.array_buffer : c->arrays.element_array_buffer); if (bo == 0) { @@ -1493,7 +1502,7 @@ void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvo ogles_error(c, GL_INVALID_VALUE); return; } - buffer_t const* bo = ((target == GL_ARRAY_BUFFER) ? + buffer_t const* bo = ((target == GL_ARRAY_BUFFER) ? c->arrays.array_buffer : c->arrays.element_array_buffer); if (bo == 0) { @@ -1541,7 +1550,7 @@ void glDeleteBuffers(GLsizei n, const GLuint* buffers) } } } - } + } c->bufferObjectManager->deleteBuffers(n, buffers); c->bufferObjectManager->recycleTokens(n, buffers); } diff --git a/opengl/libagl/copybit.cpp b/opengl/libagl/copybit.cpp new file mode 100644 index 0000000000000..427e42aaf292c --- /dev/null +++ b/opengl/libagl/copybit.cpp @@ -0,0 +1,370 @@ +/* +** +** Copyright 2009, 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. +*/ + +#include +#include + +#include "context.h" +#include "fp.h" +#include "state.h" +#include "matrix.h" +#include "vertex.h" +#include "light.h" +#include "primitives.h" +#include "texture.h" +#include "BufferObjectManager.h" + +#include "TextureObjectManager.h" +#include +#include +#include "gralloc_priv.h" + +// ---------------------------------------------------------------------------- + +namespace android { + +static void textureToCopyBitImage(const GGLSurface* surface, int fd, copybit_image_t* img) { + img->w = surface->stride; + img->h = surface->height; + img->format = surface->format; + img->offset = 0; + img->base = surface->data; + img->fd = fd; +} + +struct clipRectRegion : public copybit_region_t { + clipRectRegion(ogles_context_t* c) { + next = iterate; + int x = c->viewport.scissor.x; + int y = c->viewport.scissor.y; + r.l = x; + r.t = y; + r.r = x + c->viewport.scissor.w; + r.b = y + c->viewport.scissor.h; + firstTime = true; + } +private: + static int iterate(copybit_region_t const * self, copybit_rect_t* rect) { + clipRectRegion* myself = (clipRectRegion*) self; + if (myself->firstTime) { + myself->firstTime = false; + *rect = myself->r; + return 1; + } + return 0; + } + mutable copybit_rect_t r; + mutable bool firstTime; +}; + +static bool supportedCopybitsFormat(int format) { + switch (format) { + case COPYBIT_FORMAT_RGBA_8888: + case COPYBIT_FORMAT_RGB_565: + case COPYBIT_FORMAT_BGRA_8888: + case COPYBIT_FORMAT_RGBA_5551: + case COPYBIT_FORMAT_RGBA_4444: + case COPYBIT_FORMAT_YCbCr_422_SP: + case COPYBIT_FORMAT_YCbCr_420_SP: + return true; + default: + return false; + } +} + +static bool hasAlpha(int format) { + switch (format) { + case COPYBIT_FORMAT_RGBA_8888: + case COPYBIT_FORMAT_BGRA_8888: + case COPYBIT_FORMAT_RGBA_5551: + case COPYBIT_FORMAT_RGBA_4444: + return true; + default: + return false; + } +} + +static inline int fixedToByte(GGLfixed val) { + return (val - (val >> 8)) >> 8; +} + +/** + * Performs a quick check of the rendering state. If this function returns + * false we cannot use the copybit driver. + */ + +static bool checkContext(ogles_context_t* c) { + + // By convenction copybitQuickCheckContext() has already returned true. + // avoid checking the same information again. + + if (c->copybits.blitEngine == NULL + || (c->rasterizer.state.enables + & (GGL_ENABLE_DEPTH_TEST|GGL_ENABLE_FOG)) != 0) { + return false; + } + + // Note: The drawSurfaceFd is only set for destination + // surfaces types that are supported by the hardware and + // do not have an alpha channel. So we don't have to re-check that here. + + static const int tmu = 0; + texture_unit_t& u(c->textures.tmu[tmu]); + EGLTextureObject* textureObject = u.texture; + + if (!supportedCopybitsFormat(textureObject->surface.format)) { + return false; + } + return true; +} + + +static bool copybit(GLint x, GLint y, + GLint w, GLint h, + EGLTextureObject* textureObject, + const GLint* crop_rect, + int transform, + ogles_context_t* c) +{ + // We assume checkContext has already been called and has already + // returned true. + + const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s; + + y = cbSurface.height - (y + h); + + const GLint Ucr = crop_rect[0]; + const GLint Vcr = crop_rect[1]; + const GLint Wcr = crop_rect[2]; + const GLint Hcr = crop_rect[3]; + + int32_t dsdx = (Wcr << 16) / w; // dsdx = ((Wcr/w)/Wt)*Wt + int32_t dtdy = ((-Hcr) << 16) / h; // dtdy = -((Hcr/h)/Ht)*Ht + + if (dsdx < c->copybits.minScale || dsdx > c->copybits.maxScale + || dtdy < c->copybits.minScale || dtdy > c->copybits.maxScale) { + // The requested scale is out of the range the hardware + // can support. + return false; + } + + int32_t texelArea = gglMulx(dtdy, dsdx); + if (texelArea < FIXED_ONE && textureObject->mag_filter != GL_LINEAR) { + // Non-linear filtering on a texture enlargement. + return false; + } + + if (texelArea > FIXED_ONE && textureObject->min_filter != GL_LINEAR) { + // Non-linear filtering on an texture shrink. + return false; + } + + const uint32_t enables = c->rasterizer.state.enables; + int planeAlpha = 255; + static const int tmu = 0; + texture_t& tev(c->rasterizer.state.texture[tmu]); + bool srcTextureHasAlpha = hasAlpha(textureObject->surface.format); + switch (tev.env) { + + case GGL_REPLACE: + if (!srcTextureHasAlpha) { + planeAlpha = fixedToByte(c->currentColorClamped.a); + } + break; + + case GGL_MODULATE: + if (! (c->currentColorClamped.r == FIXED_ONE + && c->currentColorClamped.g == FIXED_ONE + && c->currentColorClamped.b == FIXED_ONE)) { + return false; + } + planeAlpha = fixedToByte(c->currentColorClamped.a); + break; + + default: + // Incompatible texture environment. + return false; + } + + bool blending = false; + + if ((enables & GGL_ENABLE_BLENDING) + && !(c->rasterizer.state.blend.src == GL_ONE + && c->rasterizer.state.blend.dst == GL_ZERO)) { + // Blending is OK if it is + // the exact kind of blending that the copybits hardware supports. + // Note: The hardware only supports + // GL_SRC_ALPHA / GL_ONE_MINUS_SRC_ALPHA, + // But the surface flinger uses GL_ONE / GL_ONE_MINUS_SRC_ALPHA. + // We substitute GL_SRC_ALPHA / GL_ONE_MINUS_SRC_ALPHA in that case, + // because the performance is worth it, even if the results are + // not correct. + if (!((c->rasterizer.state.blend.src == GL_SRC_ALPHA + || c->rasterizer.state.blend.src == GL_ONE) + && c->rasterizer.state.blend.dst == GL_ONE_MINUS_SRC_ALPHA + && c->rasterizer.state.blend.alpha_separate == 0)) { + // Incompatible blend mode. + return false; + } + blending = true; + } else { + // No blending is OK if we are not using alpha. + if (srcTextureHasAlpha || planeAlpha != 255) { + // Incompatible alpha + return false; + } + } + + if (srcTextureHasAlpha && planeAlpha != 255) { + // Can't do two types of alpha at once. + return false; + } + + // LOGW("calling copybits"); + + copybit_device_t* copybit = c->copybits.blitEngine; + copybit_image_t dst; + textureToCopyBitImage(&cbSurface, c->copybits.drawSurfaceFd, &dst); + copybit_rect_t drect = {x, y, x+w, y+h}; + + copybit_image_t src; + textureToCopyBitImage(&textureObject->surface, textureObject->copybits_fd, + &src); + copybit_rect_t srect = { Ucr, Vcr + Hcr, Ucr + Wcr, Vcr }; + + copybit->set_parameter(copybit, COPYBIT_TRANSFORM, transform); + copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, planeAlpha); + + copybit->set_parameter(copybit, COPYBIT_DITHER, + (enables & GGL_ENABLE_DITHER) ? COPYBIT_ENABLE : COPYBIT_DISABLE); + + clipRectRegion it(c); + copybit->stretch(copybit, &dst, &src, &drect, &srect, &it); + return true; +} + +/* + * Try to draw a triangle fan with copybit, return false if we fail. + */ +bool drawTrangleFanWithCopybit_impl(ogles_context_t* c, GLint first, GLsizei count) { + if (! checkContext(c)) { + return false; + } + + c->arrays.compileElements(c, c->vc.vBuffer, 0, 4); + // Is the result a screen aligned rectangle? + int sx[4]; + int sy[4]; + for (int i = 0; i < 4; i++) { + GLfixed x = c->vc.vBuffer[i].window.x; + GLfixed y = c->vc.vBuffer[i].window.y; + if (x < 0 || y < 0 || (x & 0xf) != 0 || (y & 0xf) != 0) { + return false; + } + sx[i] = x >> 4; + sy[i] = y >> 4; + } + + /* + * This is the pattern we're looking for: + * (2)--(3) + * |\ | + * | \ | + * | \ | + * | \| + * (1)--(0) + * + */ + int dx[4]; + int dy[4]; + for (int i = 0; i < 4; i++) { + int i1 = (i + 1) & 3; + dx[i] = sx[i] - sx[i1]; + dy[i] = sy[i] - sy[i1]; + } + if (dx[1] | dx[3] | dy[0] | dy[2]) { + return false; + } + if (dx[0] != -dx[2] || dy[1] != -dy[3]) { + return false; + } + + int x = sx[1]; + int y = sy[1]; + int w = dx[0]; + int h = dy[3]; + + // We expect the texture coordinates to always be the unit square: + + static const GLfixed kExpectedUV[8] = { + 0, 0, + 0, FIXED_ONE, + FIXED_ONE, FIXED_ONE, + FIXED_ONE, 0 + }; + { + const GLfixed* pExpected = &kExpectedUV[0]; + for (int i = 0; i < 4; i++) { + GLfixed u = c->vc.vBuffer[i].texture[0].x; + GLfixed v = c->vc.vBuffer[i].texture[0].y; + if (u != *pExpected++ || v != *pExpected++) { + return false; + } + } + } + + static const int tmu = 0; + texture_unit_t& u(c->textures.tmu[tmu]); + EGLTextureObject* textureObject = u.texture; + + GLint tWidth = textureObject->surface.width; + GLint tHeight = textureObject->surface.height; + GLint crop_rect[4] = {0, tHeight, tWidth, -tHeight}; + + const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s; + y = cbSurface.height - (y + h); + + return copybit(x, y, w, h, textureObject, crop_rect, + COPYBIT_TRANSFORM_ROT_90, c); +} + +/* + * Try to drawTexiOESWithCopybit, return false if we fail. + */ + +bool drawTexiOESWithCopybit_impl(GLint x, GLint y, GLint z, + GLint w, GLint h, ogles_context_t* c) +{ + // quickly process empty rects + if ((w|h) <= 0) { + return true; + } + + if (! checkContext(c)) { + return false; + } + + static const int tmu = 0; + texture_unit_t& u(c->textures.tmu[tmu]); + EGLTextureObject* textureObject = u.texture; + + return copybit(x, y, w, h, textureObject, textureObject->crop_rect, + 0, c); +} + +} // namespace android + diff --git a/opengl/libagl/copybit.h b/opengl/libagl/copybit.h new file mode 100644 index 0000000000000..1888aee1929ed --- /dev/null +++ b/opengl/libagl/copybit.h @@ -0,0 +1,75 @@ +/* +** +** Copyright 2009, 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. +*/ + +#ifndef ANDROID_OPENGLES_COPYBIT_H +#define ANDROID_OPENGLES_COPYBIT_H + +#include + +#include + +#include "TextureObjectManager.h" +namespace android { +#ifdef LIBAGL_USE_GRALLOC_COPYBITS + +bool drawTexiOESWithCopybit_impl(GLint x, GLint y, GLint z, + GLint w, GLint h, ogles_context_t* c); +bool drawTrangleFanWithCopybit_impl(ogles_context_t* c, GLint first, + GLsizei count); + +inline bool copybitQuickCheckContext(ogles_context_t* c) { + return c->copybits.drawSurfaceFd >= 0 + && c->rasterizer.state.enabled_tmu == 1 + && c->textures.tmu[0].texture->copybits_fd >= 0; +} + +/* + * Tries to draw a drawTexiOES using copybit hardware. + * Returns true if successful. + */ +inline bool drawTexiOESWithCopybit(GLint x, GLint y, GLint z, + GLint w, GLint h, ogles_context_t* c) { + if (!copybitQuickCheckContext(c)) { + return false; + } + + return drawTexiOESWithCopybit_impl(x, y, z, w, h, c); +} + +/* + * Tries to draw a triangle fan using copybit hardware. + * Returns true if successful. + */ +inline bool drawTrangleFanWithCopybit(ogles_context_t* c, GLint first, + GLsizei count) { + /* + * We are looking for the glDrawArrays call made by SurfaceFlinger. + */ + + if (!(copybitQuickCheckContext(c) && first == 0 && count == 4)) { + return false; + } + + return drawTrangleFanWithCopybit_impl(c, first, count); +} + + +#endif // LIBAGL_USE_GRALLOC_COPYBITS + +} // namespace android + +#endif // ANDROID_OPENGLES_COPYBIT_H diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp index 3b4c0419f0db7..5c91c92bb1dbe 100644 --- a/opengl/libagl/egl.cpp +++ b/opengl/libagl/egl.cpp @@ -1,22 +1,20 @@ -/* +/* ** ** Copyright 2007 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 +** 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 +** 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 +** 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. */ -#define LOG_TAG "EGL" - #include #include #include @@ -35,6 +33,7 @@ #include #include +#include #include #include @@ -46,6 +45,10 @@ #include "texture.h" #include "matrix.h" +#ifdef LIBAGL_USE_GRALLOC_COPYBITS +#include "gralloc_priv.h" +#endif // LIBAGL_USE_GRALLOC_COPYBITS + #undef NELEM #define NELEM(x) (sizeof(x)/sizeof(*(x))) @@ -89,9 +92,9 @@ static GLint getError() { struct egl_display_t { egl_display_t() : type(0), initialized(0) { } - + static egl_display_t& get_display(EGLDisplay dpy); - + static EGLBoolean is_valid(EGLDisplay dpy) { return ((uintptr_t(dpy)-1U) >= NUM_DISPLAYS) ? EGL_FALSE : EGL_TRUE; } @@ -140,7 +143,7 @@ struct egl_surface_t egl_surface_t(EGLDisplay dpy, EGLConfig config, int32_t depthFormat); virtual ~egl_surface_t(); virtual bool isValid() const = 0; - + virtual EGLBoolean bindDrawSurface(ogles_context_t* gl) = 0; virtual EGLBoolean bindReadSurface(ogles_context_t* gl) = 0; virtual EGLint getWidth() const = 0; @@ -188,39 +191,48 @@ EGLint egl_surface_t::getSwapBehavior() const { // ---------------------------------------------------------------------------- -struct egl_window_surface_t : public egl_surface_t +struct egl_window_surface_v2_t : public egl_surface_t { - egl_window_surface_t( + egl_window_surface_v2_t( EGLDisplay dpy, EGLConfig config, int32_t depthFormat, - egl_native_window_t* window); + android_native_window_t* window); - ~egl_window_surface_t(); + ~egl_window_surface_v2_t(); - virtual bool isValid() const { return nativeWindow->magic == 0x600913; } + virtual bool isValid() const { return nativeWindow->common.magic == ANDROID_NATIVE_WINDOW_MAGIC; } virtual EGLBoolean swapBuffers(); virtual EGLBoolean bindDrawSurface(ogles_context_t* gl); virtual EGLBoolean bindReadSurface(ogles_context_t* gl); - virtual EGLint getWidth() const { return nativeWindow->width; } - virtual EGLint getHeight() const { return nativeWindow->height; } + virtual EGLint getWidth() const { return buffer->width; } + virtual EGLint getHeight() const { return buffer->height; } virtual void* getBits() const; virtual EGLint getHorizontalResolution() const; virtual EGLint getVerticalResolution() const; virtual EGLint getRefreshRate() const; virtual EGLint getSwapBehavior() const; private: - egl_native_window_t* nativeWindow; + android_native_window_t* nativeWindow; + android_native_buffer_t* buffer; + int width; + int height; }; -egl_window_surface_t::egl_window_surface_t(EGLDisplay dpy, +egl_window_surface_v2_t::egl_window_surface_v2_t(EGLDisplay dpy, EGLConfig config, int32_t depthFormat, - egl_native_window_t* window) - : egl_surface_t(dpy, config, depthFormat), nativeWindow(window) + android_native_window_t* window) + : egl_surface_t(dpy, config, depthFormat), nativeWindow(window), buffer(0) { + nativeWindow->common.incRef(&nativeWindow->common); + + nativeWindow->dequeueBuffer(nativeWindow, &buffer); + + width = buffer->width; + height = buffer->height; if (depthFormat) { - depth.width = window->width; - depth.height = window->height; + depth.width = width; + depth.height = height; depth.stride = depth.width; // use the width here depth.data = (GGLubyte*)malloc(depth.stride*depth.height*2); if (depth.data == 0) { @@ -228,23 +240,56 @@ egl_window_surface_t::egl_window_surface_t(EGLDisplay dpy, return; } } - nativeWindow->incRef(nativeWindow); -} -egl_window_surface_t::~egl_window_surface_t() { - nativeWindow->decRef(nativeWindow); + + // TODO: lockBuffer should rather be executed when the very first + // direct rendering occurs. + buffer->common.incRef(&buffer->common); + nativeWindow->lockBuffer(nativeWindow, buffer); + + // FIXME: we need to gralloc lock the buffer + // FIXME: we need to handle the copy-back if needed, but + // for now we're a "non preserving" implementation. } -EGLBoolean egl_window_surface_t::swapBuffers() +egl_window_surface_v2_t::~egl_window_surface_v2_t() { + if (buffer) { + buffer->common.decRef(&buffer->common); + } + nativeWindow->common.decRef(&nativeWindow->common); +} + +EGLBoolean egl_window_surface_v2_t::swapBuffers() { - uint32_t flags = nativeWindow->swapBuffers(nativeWindow); - if (flags & EGL_NATIVES_FLAG_SIZE_CHANGED) { + // TODO: this is roughly the code needed for preserving the back buffer + // efficiently. dirty is the area that has been modified. + //Region newDirty(dirty); + //newDirty.andSelf(Rect(nativeWindow->width, nativeWindow->height)); + //mDirty = newDirty; + //const Region copyback(mDirty.subtract(newDirty)); + //mDisplaySurface->copyFrontToBack(copyback); + + + nativeWindow->queueBuffer(nativeWindow, buffer); + buffer->common.decRef(&buffer->common); buffer = 0; + + nativeWindow->dequeueBuffer(nativeWindow, &buffer); + buffer->common.incRef(&buffer->common); + + // TODO: lockBuffer should rather be executed when the very first + // direct rendering occurs. + nativeWindow->lockBuffer(nativeWindow, buffer); + + + if ((width != buffer->width) || (height != buffer->height)) { // TODO: we probably should reset the swap rect here // if the window size has changed + width = buffer->width; + height = buffer->height; if (depth.data) { free(depth.data); - depth.width = nativeWindow->width; - depth.height = nativeWindow->height; - depth.stride = nativeWindow->stride; + depth.width = width; + depth.height = height; + depth.stride = buffer->stride; depth.data = (GGLubyte*)malloc(depth.stride*depth.height*2); if (depth.data == 0) { setError(EGL_BAD_ALLOC, EGL_NO_SURFACE); @@ -255,49 +300,81 @@ EGLBoolean egl_window_surface_t::swapBuffers() return EGL_TRUE; } -EGLBoolean egl_window_surface_t::bindDrawSurface(ogles_context_t* gl) +#ifdef LIBAGL_USE_GRALLOC_COPYBITS + +static bool supportedCopybitsDestinationFormat(int format) { + // Hardware supported and no destination alpha + switch (format) { + case HAL_PIXEL_FORMAT_RGB_565: + case HAL_PIXEL_FORMAT_YCbCr_422_SP: + case HAL_PIXEL_FORMAT_YCbCr_420_SP: + return true; + default: + return false; + } +} +#endif + +EGLBoolean egl_window_surface_v2_t::bindDrawSurface(ogles_context_t* gl) { GGLSurface buffer; buffer.version = sizeof(GGLSurface); - buffer.width = nativeWindow->width; - buffer.height = nativeWindow->height; - buffer.stride = nativeWindow->stride; - buffer.data = (GGLubyte*)nativeWindow->base + nativeWindow->offset; - buffer.format = nativeWindow->format; + buffer.width = this->buffer->width; + buffer.height = this->buffer->height; + buffer.stride = this->buffer->stride; + buffer.data = (GGLubyte*)this->buffer->bits; + buffer.format = this->buffer->format; gl->rasterizer.procs.colorBuffer(gl, &buffer); if (depth.data != gl->rasterizer.state.buffers.depth.data) gl->rasterizer.procs.depthBuffer(gl, &depth); +#ifdef LIBAGL_USE_GRALLOC_COPYBITS + gl->copybits.drawSurfaceFd = -1; + if (supportedCopybitsDestinationFormat(buffer.format)) { + buffer_handle_t handle; + this->buffer->getHandle(this->buffer, &handle); + if (handle != NULL) { + private_handle_t* hand = private_handle_t::dynamicCast(handle); + if (hand != NULL) { + if (hand->usesPhysicallyContiguousMemory()) { + gl->copybits.drawSurfaceFd = hand->fd; + } + } + } + } +#endif // LIBAGL_USE_GRALLOC_COPYBITS return EGL_TRUE; } -EGLBoolean egl_window_surface_t::bindReadSurface(ogles_context_t* gl) +EGLBoolean egl_window_surface_v2_t::bindReadSurface(ogles_context_t* gl) { GGLSurface buffer; buffer.version = sizeof(GGLSurface); - buffer.width = nativeWindow->width; - buffer.height = nativeWindow->height; - buffer.stride = nativeWindow->stride; - buffer.data = (GGLubyte*)nativeWindow->base + nativeWindow->offset; - buffer.format = nativeWindow->format; + buffer.width = this->buffer->width; + buffer.height = this->buffer->height; + buffer.stride = this->buffer->stride; + buffer.data = (GGLubyte*)this->buffer->bits; + buffer.format = this->buffer->format; gl->rasterizer.procs.readBuffer(gl, &buffer); return EGL_TRUE; } -void* egl_window_surface_t::getBits() const { - return (GGLubyte*)nativeWindow->base + nativeWindow->offset; +void* egl_window_surface_v2_t::getBits() const { + return (GGLubyte*)buffer->bits; } -EGLint egl_window_surface_t::getHorizontalResolution() const { +EGLint egl_window_surface_v2_t::getHorizontalResolution() const { return (nativeWindow->xdpi * EGL_DISPLAY_SCALING) * (1.0f / 25.4f); } -EGLint egl_window_surface_t::getVerticalResolution() const { +EGLint egl_window_surface_v2_t::getVerticalResolution() const { return (nativeWindow->ydpi * EGL_DISPLAY_SCALING) * (1.0f / 25.4f); } -EGLint egl_window_surface_t::getRefreshRate() const { - return (nativeWindow->fps * EGL_DISPLAY_SCALING); +EGLint egl_window_surface_v2_t::getRefreshRate() const { + return (60 * EGL_DISPLAY_SCALING); // FIXME } -EGLint egl_window_surface_t::getSwapBehavior() const { - uint32_t flags = nativeWindow->flags; - if (flags & EGL_NATIVES_FLAG_DESTROY_BACKBUFFER) - return EGL_BUFFER_DESTROYED; - return EGL_BUFFER_PRESERVED; +EGLint egl_window_surface_v2_t::getSwapBehavior() const { + //uint32_t flags = nativeWindow->flags; + //if (flags & SURFACE_FLAG_PRESERVE_CONTENT) + // return EGL_BUFFER_PRESERVED; + // This is now a feature of EGL, currently we don't preserve + // the content of the buffers. + return EGL_BUFFER_DESTROYED; } // ---------------------------------------------------------------------------- @@ -311,7 +388,7 @@ struct egl_pixmap_surface_t : public egl_surface_t virtual ~egl_pixmap_surface_t() { } - virtual bool isValid() const { return nativePixmap.version == sizeof(egl_native_pixmap_t); } + virtual bool isValid() const { return nativePixmap.version == sizeof(egl_native_pixmap_t); } virtual EGLBoolean bindDrawSurface(ogles_context_t* gl); virtual EGLBoolean bindReadSurface(ogles_context_t* gl); virtual EGLint getWidth() const { return nativePixmap.width; } @@ -347,7 +424,7 @@ EGLBoolean egl_pixmap_surface_t::bindDrawSurface(ogles_context_t* gl) buffer.stride = nativePixmap.stride; buffer.data = nativePixmap.data; buffer.format = nativePixmap.format; - + gl->rasterizer.procs.colorBuffer(gl, &buffer); if (depth.data != gl->rasterizer.state.buffers.depth.data) gl->rasterizer.procs.depthBuffer(gl, &depth); @@ -376,7 +453,7 @@ struct egl_pbuffer_surface_t : public egl_surface_t virtual ~egl_pbuffer_surface_t(); - virtual bool isValid() const { return pbuffer.data != 0; } + virtual bool isValid() const { return pbuffer.data != 0; } virtual EGLBoolean bindDrawSurface(ogles_context_t* gl); virtual EGLBoolean bindReadSurface(ogles_context_t* gl); virtual EGLint getWidth() const { return pbuffer.width; } @@ -407,7 +484,7 @@ egl_pbuffer_surface_t::egl_pbuffer_surface_t(EGLDisplay dpy, pbuffer.stride = w; pbuffer.data = (GGLubyte*)malloc(size); pbuffer.format = f; - + if (depthFormat) { depth.width = pbuffer.width; depth.height = pbuffer.height; @@ -468,7 +545,11 @@ struct config_management_t { static char const * const gVendorString = "Google Inc."; static char const * const gVersionString = "1.2 Android Driver"; static char const * const gClientApiString = "OpenGL ES"; -static char const * const gExtensionsString = ""; +static char const * const gExtensionsString = + "KHR_image_base " + // "KHR_image_pixmap " + "EGL_ANDROID_image_native_buffer " + ; // ---------------------------------------------------------------------------- @@ -478,25 +559,45 @@ struct extention_map_t { }; static const extention_map_t gExtentionMap[] = { - { "glDrawTexsOES", (void(*)())&glDrawTexsOES }, - { "glDrawTexiOES", (void(*)())&glDrawTexiOES }, - { "glDrawTexfOES", (void(*)())&glDrawTexfOES }, - { "glDrawTexxOES", (void(*)())&glDrawTexxOES }, - { "glDrawTexsvOES", (void(*)())&glDrawTexsvOES }, - { "glDrawTexivOES", (void(*)())&glDrawTexivOES }, - { "glDrawTexfvOES", (void(*)())&glDrawTexfvOES }, - { "glDrawTexxvOES", (void(*)())&glDrawTexxvOES }, - { "glQueryMatrixxOES", (void(*)())&glQueryMatrixxOES }, - { "glClipPlanef", (void(*)())&glClipPlanef }, - { "glClipPlanex", (void(*)())&glClipPlanex }, - { "glBindBuffer", (void(*)())&glBindBuffer }, - { "glBufferData", (void(*)())&glBufferData }, - { "glBufferSubData", (void(*)())&glBufferSubData }, - { "glDeleteBuffers", (void(*)())&glDeleteBuffers }, - { "glGenBuffers", (void(*)())&glGenBuffers }, + { "glDrawTexsOES", + (__eglMustCastToProperFunctionPointerType)&glDrawTexsOES }, + { "glDrawTexiOES", + (__eglMustCastToProperFunctionPointerType)&glDrawTexiOES }, + { "glDrawTexfOES", + (__eglMustCastToProperFunctionPointerType)&glDrawTexfOES }, + { "glDrawTexxOES", + (__eglMustCastToProperFunctionPointerType)&glDrawTexxOES }, + { "glDrawTexsvOES", + (__eglMustCastToProperFunctionPointerType)&glDrawTexsvOES }, + { "glDrawTexivOES", + (__eglMustCastToProperFunctionPointerType)&glDrawTexivOES }, + { "glDrawTexfvOES", + (__eglMustCastToProperFunctionPointerType)&glDrawTexfvOES }, + { "glDrawTexxvOES", + (__eglMustCastToProperFunctionPointerType)&glDrawTexxvOES }, + { "glQueryMatrixxOES", + (__eglMustCastToProperFunctionPointerType)&glQueryMatrixxOES }, + { "glEGLImageTargetTexture2DOES", + (__eglMustCastToProperFunctionPointerType)&glEGLImageTargetTexture2DOES }, + { "glEGLImageTargetRenderbufferStorageOES", + (__eglMustCastToProperFunctionPointerType)&glEGLImageTargetRenderbufferStorageOES }, + { "glClipPlanef", + (__eglMustCastToProperFunctionPointerType)&glClipPlanef }, + { "glClipPlanex", + (__eglMustCastToProperFunctionPointerType)&glClipPlanex }, + { "glBindBuffer", + (__eglMustCastToProperFunctionPointerType)&glBindBuffer }, + { "glBufferData", + (__eglMustCastToProperFunctionPointerType)&glBufferData }, + { "glBufferSubData", + (__eglMustCastToProperFunctionPointerType)&glBufferSubData }, + { "glDeleteBuffers", + (__eglMustCastToProperFunctionPointerType)&glDeleteBuffers }, + { "glGenBuffers", + (__eglMustCastToProperFunctionPointerType)&glGenBuffers }, }; -/* +/* * In the lists below, attributes names MUST be sorted. * Additionally, all configs must be sorted according to * the EGL specification. @@ -507,7 +608,7 @@ static config_pair_t const config_base_attribute_list[] = { { EGL_CONFIG_CAVEAT, EGL_SLOW_CONFIG }, { EGL_LEVEL, 0 }, { EGL_MAX_PBUFFER_HEIGHT, GGL_MAX_VIEWPORT_DIMS }, - { EGL_MAX_PBUFFER_PIXELS, + { EGL_MAX_PBUFFER_PIXELS, GGL_MAX_VIEWPORT_DIMS*GGL_MAX_VIEWPORT_DIMS }, { EGL_MAX_PBUFFER_WIDTH, GGL_MAX_VIEWPORT_DIMS }, { EGL_NATIVE_RENDERABLE, EGL_TRUE }, @@ -644,9 +745,9 @@ static int binarySearch(T const sortedArray[], int first, int last, EGLint key) { while (first <= last) { int mid = (first + last) / 2; - if (key > sortedArray[mid].key) { + if (key > sortedArray[mid].key) { first = mid + 1; - } else if (key < sortedArray[mid].key) { + } else if (key < sortedArray[mid].key) { last = mid - 1; } else { return mid; @@ -658,13 +759,13 @@ static int binarySearch(T const sortedArray[], int first, int last, EGLint key) static int isAttributeMatching(int i, EGLint attr, EGLint val) { // look for the attribute in all of our configs - config_pair_t const* configFound = gConfigs[i].array; + config_pair_t const* configFound = gConfigs[i].array; int index = binarySearch( gConfigs[i].array, 0, gConfigs[i].size-1, attr); if (index < 0) { - configFound = config_base_attribute_list; + configFound = config_base_attribute_list; index = binarySearch( config_base_attribute_list, 0, NELEM(config_base_attribute_list)-1, @@ -778,28 +879,28 @@ static EGLSurface createWindowSurface(EGLDisplay dpy, EGLConfig config, int32_t depthFormat; int32_t pixelFormat; switch(configID) { - case 0: - pixelFormat = GGL_PIXEL_FORMAT_RGB_565; + case 0: + pixelFormat = GGL_PIXEL_FORMAT_RGB_565; depthFormat = 0; break; case 1: - pixelFormat = GGL_PIXEL_FORMAT_RGB_565; + pixelFormat = GGL_PIXEL_FORMAT_RGB_565; depthFormat = GGL_PIXEL_FORMAT_Z_16; break; case 2: - pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; + pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; depthFormat = 0; break; case 3: - pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; + pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; depthFormat = GGL_PIXEL_FORMAT_Z_16; break; case 4: - pixelFormat = GGL_PIXEL_FORMAT_A_8; + pixelFormat = GGL_PIXEL_FORMAT_A_8; depthFormat = 0; break; case 5: - pixelFormat = GGL_PIXEL_FORMAT_A_8; + pixelFormat = GGL_PIXEL_FORMAT_A_8; depthFormat = GGL_PIXEL_FORMAT_Z_16; break; default: @@ -812,9 +913,9 @@ static EGLSurface createWindowSurface(EGLDisplay dpy, EGLConfig config, //if (EGLint(info.format) != pixelFormat) // return setError(EGL_BAD_MATCH, EGL_NO_SURFACE); - egl_surface_t* surface = - new egl_window_surface_t(dpy, config, depthFormat, - static_cast(window)); + egl_surface_t* surface; + surface = new egl_window_surface_v2_t(dpy, config, depthFormat, + static_cast(window)); if (!surface->isValid()) { // there was a problem in the ctor, the error @@ -847,28 +948,28 @@ static EGLSurface createPixmapSurface(EGLDisplay dpy, EGLConfig config, int32_t depthFormat; int32_t pixelFormat; switch(configID) { - case 0: - pixelFormat = GGL_PIXEL_FORMAT_RGB_565; + case 0: + pixelFormat = GGL_PIXEL_FORMAT_RGB_565; depthFormat = 0; break; case 1: - pixelFormat = GGL_PIXEL_FORMAT_RGB_565; + pixelFormat = GGL_PIXEL_FORMAT_RGB_565; depthFormat = GGL_PIXEL_FORMAT_Z_16; break; case 2: - pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; + pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; depthFormat = 0; break; case 3: - pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; + pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; depthFormat = GGL_PIXEL_FORMAT_Z_16; break; case 4: - pixelFormat = GGL_PIXEL_FORMAT_A_8; + pixelFormat = GGL_PIXEL_FORMAT_A_8; depthFormat = 0; break; case 5: - pixelFormat = GGL_PIXEL_FORMAT_A_8; + pixelFormat = GGL_PIXEL_FORMAT_A_8; depthFormat = GGL_PIXEL_FORMAT_Z_16; break; default: @@ -900,10 +1001,10 @@ static EGLSurface createPbufferSurface(EGLDisplay dpy, EGLConfig config, EGLint surfaceType; if (getConfigAttrib(dpy, config, EGL_SURFACE_TYPE, &surfaceType) == EGL_FALSE) return EGL_FALSE; - + if (!(surfaceType & EGL_PBUFFER_BIT)) return setError(EGL_BAD_MATCH, EGL_NO_SURFACE); - + EGLint configID; if (getConfigAttrib(dpy, config, EGL_CONFIG_ID, &configID) == EGL_FALSE) return EGL_FALSE; @@ -911,28 +1012,28 @@ static EGLSurface createPbufferSurface(EGLDisplay dpy, EGLConfig config, int32_t depthFormat; int32_t pixelFormat; switch(configID) { - case 0: - pixelFormat = GGL_PIXEL_FORMAT_RGB_565; + case 0: + pixelFormat = GGL_PIXEL_FORMAT_RGB_565; depthFormat = 0; break; case 1: - pixelFormat = GGL_PIXEL_FORMAT_RGB_565; + pixelFormat = GGL_PIXEL_FORMAT_RGB_565; depthFormat = GGL_PIXEL_FORMAT_Z_16; break; case 2: - pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; + pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; depthFormat = 0; break; case 3: - pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; + pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; depthFormat = GGL_PIXEL_FORMAT_Z_16; break; case 4: - pixelFormat = GGL_PIXEL_FORMAT_A_8; + pixelFormat = GGL_PIXEL_FORMAT_A_8; depthFormat = 0; break; case 5: - pixelFormat = GGL_PIXEL_FORMAT_A_8; + pixelFormat = GGL_PIXEL_FORMAT_A_8; depthFormat = GGL_PIXEL_FORMAT_Z_16; break; default: @@ -985,7 +1086,7 @@ EGLDisplay eglGetDisplay(NativeDisplayType display) egl_display_t& d = egl_display_t::get_display(dpy); d.type = display; return dpy; - } + } return EGL_NO_DISPLAY; } @@ -993,10 +1094,10 @@ EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) { if (egl_display_t::is_valid(dpy) == EGL_FALSE) return setError(EGL_BAD_DISPLAY, EGL_FALSE); - + EGLBoolean res = EGL_TRUE; egl_display_t& d = egl_display_t::get_display(dpy); - + if (android_atomic_inc(&d.initialized) == 0) { // initialize stuff here if needed //pthread_mutex_lock(&gInitMutex); @@ -1064,7 +1165,7 @@ EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list, *num_config = 0; return EGL_TRUE; } - + int numAttributes = 0; int numConfigs = NELEM(gConfigs); uint32_t possibleMatch = (1<getSwapBehavior(); + *value = surface->getSwapBehavior(); break; default: ret = setError(EGL_BAD_ATTRIBUTE, EGL_FALSE); @@ -1278,7 +1379,7 @@ EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw, } EGLContext current_ctx = EGL_NO_CONTEXT; - + if ((read == EGL_NO_SURFACE && draw == EGL_NO_SURFACE) && (ctx != EGL_NO_CONTEXT)) return setError(EGL_BAD_MATCH, EGL_FALSE); @@ -1299,6 +1400,8 @@ EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw, } } + // TODO: call connect / disconnect on the surface + ogles_context_t* gl = (ogles_context_t*)ctx; if (makeCurrent(gl) == 0) { if (ctx) { @@ -1407,7 +1510,7 @@ EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface draw) { if (egl_display_t::is_valid(dpy) == EGL_FALSE) return setError(EGL_BAD_DISPLAY, EGL_FALSE); - + egl_surface_t* d = static_cast(draw); if (d->dpy != dpy) return setError(EGL_BAD_DISPLAY, EGL_FALSE); @@ -1540,7 +1643,7 @@ EGLSurface eglCreatePbufferFromClientBuffer( } // ---------------------------------------------------------------------------- -// Android extensions +// EGL_EGLEXT_VERSION 3 // ---------------------------------------------------------------------------- void (*eglGetProcAddress (const char *procname))() @@ -1553,3 +1656,81 @@ void (*eglGetProcAddress (const char *procname))() } return NULL; } + +EGLBoolean eglLockSurfaceKHR(EGLDisplay dpy, EGLSurface surface, + const EGLint *attrib_list) +{ + EGLBoolean result = EGL_FALSE; + return result; +} + +EGLBoolean eglUnlockSurfaceKHR(EGLDisplay dpy, EGLSurface surface) +{ + EGLBoolean result = EGL_FALSE; + return result; +} + +EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, + EGLClientBuffer buffer, const EGLint *attrib_list) +{ + if (egl_display_t::is_valid(dpy) == EGL_FALSE) { + return setError(EGL_BAD_DISPLAY, EGL_NO_IMAGE_KHR); + } + if (ctx != EGL_NO_CONTEXT) { + return setError(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR); + } + if (target != EGL_NATIVE_BUFFER_ANDROID) { + return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); + } + + android_native_buffer_t* native_buffer = (android_native_buffer_t*)buffer; + + if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) + return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); + + if (native_buffer->common.version != sizeof(android_native_buffer_t)) + return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); + + hw_module_t const* pModule; + if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule)) + return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); + buffer_handle_t bufferHandle; + gralloc_module_t const* module = + reinterpret_cast(pModule); + if (native_buffer->getHandle(native_buffer, &bufferHandle) < 0) + return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); + if (module->map(module, bufferHandle, &native_buffer->bits) < 0) + return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); + + native_buffer->common.incRef(&native_buffer->common); + return (EGLImageKHR)native_buffer; +} + +EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img) +{ + if (egl_display_t::is_valid(dpy) == EGL_FALSE) { + return setError(EGL_BAD_DISPLAY, EGL_FALSE); + } + + android_native_buffer_t* native_buffer = (android_native_buffer_t*)img; + + if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) + return setError(EGL_BAD_PARAMETER, EGL_FALSE); + + if (native_buffer->common.version != sizeof(android_native_buffer_t)) + return setError(EGL_BAD_PARAMETER, EGL_FALSE); + + hw_module_t const* pModule; + if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule) == 0) { + buffer_handle_t bufferHandle; + gralloc_module_t const* module = + reinterpret_cast(pModule); + if (native_buffer->getHandle(native_buffer, &bufferHandle) == 0) { + module->unmap(module, bufferHandle); + } + } + + native_buffer->common.decRef(&native_buffer->common); + + return EGL_TRUE; +} diff --git a/opengl/libagl/state.cpp b/opengl/libagl/state.cpp index 5cbabea1f8a8e..a00f779d6d35a 100644 --- a/opengl/libagl/state.cpp +++ b/opengl/libagl/state.cpp @@ -2,16 +2,16 @@ ** ** Copyright 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 +** 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 +** 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 +** 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. */ @@ -28,12 +28,16 @@ #include "BufferObjectManager.h" #include "TextureObjectManager.h" +#ifdef LIBAGL_USE_GRALLOC_COPYBITS +#include +#endif // LIBAGL_USE_GRALLOC_COPYBITS + namespace android { // ---------------------------------------------------------------------------- static char const * const gVendorString = "Android"; -static char const * const gRendererString = "Android PixelFlinger 1.0"; +static char const * const gRendererString = "Android PixelFlinger 1.1"; static char const * const gVersionString = "OpenGL ES-CM 1.0"; static char const * const gExtensionsString = "GL_OES_byte_coordinates " // OK @@ -46,9 +50,9 @@ static char const * const gExtensionsString = "GL_OES_query_matrix " // OK // "GL_OES_point_size_array " // TODO // "GL_OES_point_sprite " // TODO + "GL_OES_EGL_image " // OK "GL_ARB_texture_compression " // OK "GL_ARB_texture_non_power_of_two " // OK - "GL_ANDROID_direct_texture " // OK "GL_ANDROID_user_clip_plane " // OK "GL_ANDROID_vertex_buffer_object " // OK "GL_ANDROID_generate_mipmap " // OK @@ -62,13 +66,13 @@ static char const * const gExtensionsString = ogles_context_t *ogles_init(size_t extra) { void* const base = malloc(extra + sizeof(ogles_context_t) + 32); - if (!base) return 0; + if (!base) return 0; ogles_context_t *c = (ogles_context_t *)((ptrdiff_t(base) + extra + 31) & ~0x1FL); memset(c, 0, sizeof(ogles_context_t)); ggl_init_context(&(c->rasterizer)); - + // XXX: this should be passed as an argument sp smgr(new EGLSurfaceManager()); c->surfaceManager = smgr.get(); @@ -87,13 +91,42 @@ ogles_context_t *ogles_init(size_t extra) c->rasterizer.base = base; c->point.size = TRI_ONE; c->line.width = TRI_ONE; - + // in OpenGL, writing to the depth buffer is enabled by default. c->rasterizer.procs.depthMask(c, 1); - + // OpenGL enables dithering by default c->rasterizer.procs.enable(c, GL_DITHER); + c->copybits.blitEngine = NULL; + c->copybits.minScale = 0; + c->copybits.maxScale = 0; + c->copybits.drawSurfaceFd = -1; + +#ifdef LIBAGL_USE_GRALLOC_COPYBITS + hw_module_t const* module; + if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) { + struct copybit_device_t* copyBits; + if (copybit_open(module, ©Bits) == 0) { + c->copybits.blitEngine = copyBits; + { + int minLim = copyBits->get(copyBits, + COPYBIT_MINIFICATION_LIMIT); + if (minLim != -EINVAL && minLim > 0) { + c->copybits.minScale = (1 << 16) / minLim; + } + } + { + int magLim = copyBits->get(copyBits, + COPYBIT_MAGNIFICATION_LIMIT); + if (magLim != -EINVAL && magLim > 0) { + c->copybits.maxScale = min(32*1024-1, magLim) << 16; + } + } + } + } +#endif // LIBAGL_USE_GRALLOC_COPYBITS + return c; } @@ -107,7 +140,12 @@ void ogles_uninit(ogles_context_t* c) c->surfaceManager->decStrong(c); c->bufferObjectManager->decStrong(c); ggl_uninit_context(&(c->rasterizer)); - free(c->rasterizer.base); + free(c->rasterizer.base); +#ifdef LIBAGL_USE_GRALLOC_COPYBITS + if (c->copybits.blitEngine != NULL) { + copybit_close((struct copybit_device_t*) c->copybits.blitEngine); + } +#endif // LIBAGL_USE_GRALLOC_COPYBITS } void _ogles_error(ogles_context_t* c, GLenum error) @@ -188,7 +226,7 @@ static void enable_disable(ogles_context_t* c, GLenum cap, int enabled) // these need to fall through into the rasterizer c->rasterizer.procs.enableDisable(c, cap, enabled); break; - + case GL_MULTISAMPLE: case GL_SAMPLE_ALPHA_TO_COVERAGE: case GL_SAMPLE_ALPHA_TO_ONE: @@ -281,7 +319,7 @@ void glHint(GLenum target, GLenum mode) case GL_LINE_SMOOTH_HINT: break; case GL_POINT_SMOOTH_HINT: - c->rasterizer.procs.enableDisable(c, + c->rasterizer.procs.enableDisable(c, GGL_POINT_SMOOTH_NICE, mode==GL_NICEST); break; case GL_PERSPECTIVE_CORRECTION_HINT: @@ -323,7 +361,7 @@ GLenum glGetError() c->error = 0; return ret; } - + if (c->rasterizer.error) { const GLenum ret(c->rasterizer.error); c->rasterizer.error = 0; @@ -362,25 +400,25 @@ void glGetIntegerv(GLenum pname, GLint *params) int index = c->rasterizer.state.buffers.color.format; GGLFormat const * formats = gglGetPixelFormatTable(); params[0] = formats[index].ah - formats[index].al; - break; + break; } case GL_RED_BITS: { int index = c->rasterizer.state.buffers.color.format; GGLFormat const * formats = gglGetPixelFormatTable(); params[0] = formats[index].rh - formats[index].rl; - break; + break; } case GL_GREEN_BITS: { int index = c->rasterizer.state.buffers.color.format; GGLFormat const * formats = gglGetPixelFormatTable(); params[0] = formats[index].gh - formats[index].gl; - break; + break; } case GL_BLUE_BITS: { int index = c->rasterizer.state.buffers.color.format; GGLFormat const * formats = gglGetPixelFormatTable(); params[0] = formats[index].bh - formats[index].bl; - break; + break; } case GL_COMPRESSED_TEXTURE_FORMATS: params[ 0] = GL_PALETTE4_RGB8_OES; diff --git a/opengl/libagl/texture.cpp b/opengl/libagl/texture.cpp index b6f534b7ea506..9dca1338c2fb1 100644 --- a/opengl/libagl/texture.cpp +++ b/opengl/libagl/texture.cpp @@ -2,16 +2,16 @@ ** ** Copyright 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 +** 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 +** 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 +** 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. */ @@ -23,6 +23,13 @@ #include "texture.h" #include "TextureObjectManager.h" +#include + +#ifdef LIBAGL_USE_GRALLOC_COPYBITS +#include "copybit.h" +#include "gralloc_priv.h" +#endif // LIBAGL_USE_GRALLOC_COPYBITS + namespace android { // ---------------------------------------------------------------------------- @@ -48,7 +55,7 @@ void ogles_init_texture(ogles_context_t* c) // each context has a default named (0) texture (not shared) c->textures.defaultTexture = new EGLTextureObject(); c->textures.defaultTexture->incStrong(c); - + // bind the default texture to each texture unit for (int i=0; itextures.defaultTexture); @@ -255,7 +262,7 @@ sp getAndBindActiveTextureObject(ogles_context_t* c) u.texture->decStrong(c); if (name == 0) { - // 0 is our local texture object, not shared with anyone. + // 0 is our local texture object, not shared with anyone. // But it affects all bound TMUs immediately. // (we need to invalidate all units bound to this texture object) tex = c->textures.defaultTexture; @@ -273,7 +280,7 @@ sp getAndBindActiveTextureObject(ogles_context_t* c) u.texture = tex.get(); u.texture->incStrong(c); u.name = name; - invalidate_texture(c, active); + invalidate_texture(c, active); return tex; } @@ -282,7 +289,7 @@ void bindTextureTmu( { if (tex.get() == c->textures.tmu[tmu].texture) return; - + // free the reference to the previously bound object texture_unit_t& u(c->textures.tmu[tmu]); if (u.texture) @@ -310,7 +317,7 @@ int createTextureSurface(ogles_context_t* c, if (formatIdx == 0) { // we don't know what to do with this return GL_INVALID_OPERATION; } - + // figure out the size we need as well as the stride const GGLFormat& pixelFormat(c->rasterizer.formats[formatIdx]); const int32_t align = c->textures.unpackAlignment-1; @@ -530,8 +537,8 @@ static void texParameterx( ogles_error(c, GL_INVALID_ENUM); return; } - - EGLTextureObject* textureObject = c->textures.tmu[c->textures.active].texture; + + EGLTextureObject* textureObject = c->textures.tmu[c->textures.active].texture; switch (pname) { case GL_TEXTURE_WRAP_S: if ((param == GL_REPEAT) || @@ -581,13 +588,10 @@ invalid_enum: } -static void drawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h, + +static void drawTexxOESImp(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h, ogles_context_t* c) { - // quickly reject empty rects - if ((w|h) <= 0) - return; - const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s; y = gglIntToFixed(cbSurface.height) - (y + h); w >>= FIXED_BITS; @@ -610,7 +614,7 @@ static void drawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h, GGL_TEXTURE_2D, GGL_TEXTURE_WRAP_T, GGL_CLAMP); u.dirty = 0xFF; // XXX: should be more subtle - EGLTextureObject* textureObject = u.texture; + EGLTextureObject* textureObject = u.texture; const GLint Ucr = textureObject->crop_rect[0] << 16; const GLint Vcr = textureObject->crop_rect[1] << 16; const GLint Wcr = textureObject->crop_rect[2] << 16; @@ -641,13 +645,30 @@ static void drawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h, c->rasterizer.procs.disable(c, GGL_W_LERP); c->rasterizer.procs.disable(c, GGL_AA); c->rasterizer.procs.shadeModel(c, GL_FLAT); - c->rasterizer.procs.recti(c, + c->rasterizer.procs.recti(c, gglFixedToIntRound(x), gglFixedToIntRound(y), gglFixedToIntRound(x)+w, gglFixedToIntRound(y)+h); } +static void drawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h, + ogles_context_t* c) +{ +#ifdef LIBAGL_USE_GRALLOC_COPYBITS + if (drawTexiOESWithCopybit(gglFixedToIntRound(x), + gglFixedToIntRound(y), gglFixedToIntRound(z), + gglFixedToIntRound(w), gglFixedToIntRound(h), c)) { + return; + } +#else + // quickly reject empty rects + if ((w|h) <= 0) + return; +#endif + drawTexxOESImp(x, y, z, w, h, c); +} + static void drawTexiOES(GLint x, GLint y, GLint z, GLint w, GLint h, ogles_context_t* c) { // All coordinates are integer, so if we have only one @@ -656,14 +677,21 @@ static void drawTexiOES(GLint x, GLint y, GLint z, GLint w, GLint h, ogles_conte // which is a lot faster. if (ggl_likely(c->rasterizer.state.enabled_tmu == 1)) { +#ifdef LIBAGL_USE_GRALLOC_COPYBITS + if (drawTexiOESWithCopybit(x, y, z, w, h, c)) { + return; + } +#endif const int tmu = 0; texture_unit_t& u(c->textures.tmu[tmu]); - EGLTextureObject* textureObject = u.texture; + EGLTextureObject* textureObject = u.texture; const GLint Wcr = textureObject->crop_rect[2]; const GLint Hcr = textureObject->crop_rect[3]; if ((w == Wcr) && (h == -Hcr)) { +#ifndef LIBAGL_USE_GRALLOC_COPYBITS if ((w|h) <= 0) return; // quickly reject empty rects +#endif if (u.dirty) { c->rasterizer.procs.activeTexture(c, tmu); @@ -679,14 +707,14 @@ static void drawTexiOES(GLint x, GLint y, GLint z, GLint w, GLint h, ogles_conte GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); u.dirty = 0xFF; // XXX: should be more subtle c->rasterizer.procs.activeTexture(c, c->textures.active); - + const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s; y = cbSurface.height - (y + h); const GLint Ucr = textureObject->crop_rect[0]; const GLint Vcr = textureObject->crop_rect[1]; const GLint s0 = Ucr - x; const GLint t0 = (Vcr + Hcr) - y; - + const GLuint tw = textureObject->surface.width; const GLuint th = textureObject->surface.height; if ((uint32_t(s0+x+w) > tw) || (uint32_t(t0+y+h) > th)) { @@ -694,7 +722,7 @@ static void drawTexiOES(GLint x, GLint y, GLint z, GLint w, GLint h, ogles_conte // in this case, so we just use the slow case, which // at least won't crash goto slow_case; - } + } c->rasterizer.procs.texCoord2i(c, s0, t0); const uint32_t enables = c->rasterizer.state.enables; @@ -711,7 +739,7 @@ static void drawTexiOES(GLint x, GLint y, GLint z, GLint w, GLint h, ogles_conte } slow_case: - drawTexxOES( + drawTexxOESImp( gglIntToFixed(x), gglIntToFixed(y), gglIntToFixed(z), gglIntToFixed(w), gglIntToFixed(h), c); @@ -749,7 +777,7 @@ void glBindTexture(GLenum target, GLuint texture) } // Bind or create a texture - sp tex; + sp tex; if (texture == 0) { // 0 is our local texture object tex = c->textures.defaultTexture; @@ -837,7 +865,7 @@ void glPixelStorei(GLenum pname, GLint param) if ((pname != GL_PACK_ALIGNMENT) && (pname != GL_UNPACK_ALIGNMENT)) { ogles_error(c, GL_INVALID_ENUM); return; - } + } if ((param<=0 || param>8) || (param & (param-1))) { ogles_error(c, GL_INVALID_VALUE); return; @@ -945,7 +973,7 @@ void glCompressedTexImage2D( } // "uncompress" the texture since pixelflinger doesn't support - // any compressed texture format natively. + // any compressed texture format natively. GLenum format; GLenum type; switch (internalformat) { @@ -1009,7 +1037,7 @@ void glTexImage2D( GLenum format, GLenum type, const GLvoid *pixels) { ogles_context_t* c = ogles_context_t::get(); - if (target != GL_TEXTURE_2D && target != GL_DIRECT_TEXTURE_2D_QUALCOMM) { + if (target != GL_TEXTURE_2D) { ogles_error(c, GL_INVALID_ENUM); return; } @@ -1017,7 +1045,7 @@ void glTexImage2D( ogles_error(c, GL_INVALID_VALUE); return; } - if (format != internalformat) { + if (format != (GLenum)internalformat) { ogles_error(c, GL_INVALID_OPERATION); return; } @@ -1027,16 +1055,10 @@ void glTexImage2D( int32_t size = 0; GGLSurface* surface = 0; - if (target != GL_DIRECT_TEXTURE_2D_QUALCOMM) { - int error = createTextureSurface(c, &surface, &size, - level, format, type, width, height); - if (error) { - ogles_error(c, error); - return; - } - } else if (pixels == 0 || level != 0) { - // pixel can't be null for direct texture - ogles_error(c, GL_INVALID_OPERATION); + int error = createTextureSurface(c, &surface, &size, + level, format, type, width, height); + if (error) { + ogles_error(c, error); return; } @@ -1057,18 +1079,12 @@ void glTexImage2D( userSurface.compressedFormat = 0; userSurface.data = (GLubyte*)pixels; - if (target != GL_DIRECT_TEXTURE_2D_QUALCOMM) { - int err = copyPixels(c, *surface, 0, 0, userSurface, 0, 0, width, height); - if (err) { - ogles_error(c, err); - return; - } - generateMipmap(c, level); - } else { - // bind it to the texture unit - sp tex = getAndBindActiveTextureObject(c); - tex->setSurface(&userSurface); + int err = copyPixels(c, *surface, 0, 0, userSurface, 0, 0, width, height); + if (err) { + ogles_error(c, err); + return; } + generateMipmap(c, level); } } @@ -1143,7 +1159,7 @@ void glTexSubImage2D( int err = copyPixels(c, surface, xoffset, yoffset, - userSurface, 0, 0, width, height); + userSurface, 0, 0, width, height); if (err) { ogles_error(c, err); return; @@ -1196,7 +1212,7 @@ void glCopyTexImage2D( case GL_LUMINANCE_ALPHA: case GL_LUMINANCE: type = GL_UNSIGNED_BYTE; - break; + break; } // figure out the format to use for the new texture @@ -1206,7 +1222,7 @@ void glCopyTexImage2D( case GGL_PIXEL_FORMAT_RGBA_5551: case GGL_PIXEL_FORMAT_RGBA_4444: format = internalformat; - break; + break; case GGL_PIXEL_FORMAT_RGBX_8888: case GGL_PIXEL_FORMAT_RGB_888: case GGL_PIXEL_FORMAT_RGB_565: @@ -1215,7 +1231,7 @@ void glCopyTexImage2D( case GL_LUMINANCE: case GL_RGB: format = internalformat; - break; + break; } break; } @@ -1235,7 +1251,7 @@ void glCopyTexImage2D( ogles_error(c, error); return; } - + // The bottom row is stored first in textures GGLSurface txSurface(*surface); txSurface.stride = -txSurface.stride; @@ -1245,7 +1261,7 @@ void glCopyTexImage2D( int err = copyPixels(c, txSurface, 0, 0, - cbSurface, x, y, cbSurface.width, cbSurface.height); + cbSurface, x, y, cbSurface.width, cbSurface.height); if (err) { ogles_error(c, err); } @@ -1295,7 +1311,7 @@ void glCopyTexSubImage2D( int err = copyPixels(c, surface, xoffset, yoffset, - cbSurface, x, y, width, height); + cbSurface, x, y, width, height); if (err) { ogles_error(c, err); return; @@ -1365,7 +1381,7 @@ void glReadPixels( return; } - ggl->colorBuffer(ggl, &userSurface); // destination is user buffer + ggl->colorBuffer(ggl, &userSurface); // destination is user buffer ggl->bindTexture(ggl, &readSurface); // source is read-buffer ggl->texCoord2i(ggl, x, readSurface.height - (y + height)); ggl->recti(ggl, 0, 0, width, height); @@ -1419,3 +1435,73 @@ void glDrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h) { ogles_context_t* c = ogles_context_t::get(); drawTexxOES(x, y, z, w, h, c); } + +// ---------------------------------------------------------------------------- +#if 0 +#pragma mark - +#pragma mark EGL Image Extension +#endif + +void glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image) +{ + ogles_context_t* c = ogles_context_t::get(); + if (target != GL_TEXTURE_2D) { + ogles_error(c, GL_INVALID_ENUM); + return; + } + + android_native_buffer_t* native_buffer = (android_native_buffer_t*)image; + if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) { + ogles_error(c, GL_INVALID_VALUE); + return; + } + if (native_buffer->common.version != sizeof(android_native_buffer_t)) { + ogles_error(c, GL_INVALID_VALUE); + return; + } + + if (native_buffer->bits == NULL) { + // this buffer cannot be used with this implementation + ogles_error(c, GL_INVALID_VALUE); + return; + } + + GGLSurface sur; + sur.version = sizeof(GGLSurface); + sur.width = native_buffer->width; + sur.height= native_buffer->height; + sur.stride= native_buffer->stride; + sur.format= native_buffer->format; + sur.data = (GGLubyte*)native_buffer->bits; + + // bind it to the texture unit + sp tex = getAndBindActiveTextureObject(c); + tex->setSurface(&sur); + + /* + * Here an implementation can retrieve the buffer_handle_t of this buffer + * which gives it access to an arbitrary-defined kernel resource + * (or anything else for that matter). + * There needs to be an intimate knowledge between GLES and buffer_handle_t, + * so make sure to validate the handle before using it. + * Typically, buffer_handle_t comes from the gralloc HAL which is provided + * by the implementor of GLES. + * + */ +#ifdef LIBAGL_USE_GRALLOC_COPYBITS + tex->copybits_fd = -1; + buffer_handle_t handle; + if (native_buffer->getHandle(native_buffer, &handle) == 0) { + private_handle_t* hand; + if ((hand = private_handle_t::dynamicCast(handle)) != NULL) { + if (hand->usesPhysicallyContiguousMemory()) { + tex->copybits_fd = hand->fd; + } + } + } +#endif // LIBAGL_USE_GRALLOC_COPYBITS +} + +void glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image) +{ +} diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk index 2ecc7768cac25..da00cc537b82a 100644 --- a/opengl/libs/Android.mk +++ b/opengl/libs/Android.mk @@ -7,8 +7,7 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ - EGL/egl.cpp \ - EGL/gpu.cpp \ + EGL/egl.cpp \ # LOCAL_SHARED_LIBRARIES += libcutils libutils libui @@ -23,6 +22,9 @@ else LOCAL_CFLAGS += -I$(LOCAL_PATH)/../../../../bionic/libc/private endif +LOCAL_CFLAGS += -DLOG_TAG=\"libEGL\" +LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES + include $(BUILD_SHARED_LIBRARY) @@ -35,7 +37,6 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ GLES_CM/gl.cpp.arm \ - GLES_CM/gl_logger.cpp \ # LOCAL_SHARED_LIBRARIES += libcutils libutils libui libEGL @@ -50,4 +51,7 @@ else LOCAL_CFLAGS += -I$(LOCAL_PATH)/../../../../bionic/libc/private endif +LOCAL_CFLAGS += -DLOG_TAG=\"libGLESv1\" +LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES + include $(BUILD_SHARED_LIBRARY) diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp index 0b4bcce9eae52..c58fff8790b38 100644 --- a/opengl/libs/EGL/egl.cpp +++ b/opengl/libs/EGL/egl.cpp @@ -14,8 +14,6 @@ ** limitations under the License. */ -#define LOG_TAG "GLLogger" - #include #include #include @@ -38,6 +36,8 @@ #include #include +#include +#include #include "hooks.h" #include "egl_impl.h" @@ -55,7 +55,14 @@ namespace android { static char const * const gVendorString = "Android"; static char const * const gVersionString = "1.31 Android META-EGL"; static char const * const gClientApiString = "OpenGL ES"; -static char const * const gExtensionString = ""; +static char const * const gExtensionString = + "EGL_KHR_image " + "KHR_image_base " + "KHR_image_pixmap " + "EGL_ANDROID_image_native_buffer " + ; + +// ---------------------------------------------------------------------------- template struct egl_object_t @@ -69,9 +76,9 @@ private: struct egl_display_t : public egl_object_t<'_dpy'> { - EGLDisplay dpys[2]; - EGLConfig* configs[2]; - EGLint numConfigs[2]; + EGLDisplay dpys[IMPL_NUM_DRIVERS_IMPLEMENTATIONS]; + EGLConfig* configs[IMPL_NUM_DRIVERS_IMPLEMENTATIONS]; + EGLint numConfigs[IMPL_NUM_DRIVERS_IMPLEMENTATIONS]; EGLint numTotalConfigs; char const* extensionsString; volatile int32_t refs; @@ -81,27 +88,21 @@ struct egl_display_t : public egl_object_t<'_dpy'> char const * clientApi; char const * extensions; }; - strings_t queryString[2]; + strings_t queryString[IMPL_NUM_DRIVERS_IMPLEMENTATIONS]; }; struct egl_surface_t : public egl_object_t<'_srf'> { egl_surface_t(EGLDisplay dpy, EGLSurface surface, - NativeWindowType window, int impl, egl_connection_t const* cnx) - : dpy(dpy), surface(surface), window(window), impl(impl), cnx(cnx) + int impl, egl_connection_t const* cnx) + : dpy(dpy), surface(surface), impl(impl), cnx(cnx) { // NOTE: window must be incRef'ed and connected already } ~egl_surface_t() { - if (window) { - if (window->disconnect) - window->disconnect(window); - window->decRef(window); - } } EGLDisplay dpy; EGLSurface surface; - NativeWindowType window; int impl; egl_connection_t const* cnx; }; @@ -121,6 +122,18 @@ struct egl_context_t : public egl_object_t<'_ctx'> egl_connection_t const* cnx; }; +struct egl_image_t : public egl_object_t<'_img'> +{ + egl_image_t(EGLDisplay dpy, EGLContext context) + : dpy(dpy), context(context) + { + memset(images, 0, sizeof(images)); + } + EGLDisplay dpy; + EGLConfig context; + EGLImageKHR images[IMPL_NUM_DRIVERS_IMPLEMENTATIONS]; +}; + struct tls_t { tls_t() : error(EGL_SUCCESS), ctx(0) { } @@ -156,7 +169,7 @@ static char const * const egl_names[] = { // ---------------------------------------------------------------------------- -egl_connection_t gEGLImpl[2]; +egl_connection_t gEGLImpl[IMPL_NUM_DRIVERS_IMPLEMENTATIONS]; static egl_display_t gDisplay[NUM_DISPLAYS]; static pthread_mutex_t gThreadLocalStorageKeyMutex = PTHREAD_MUTEX_INITIALIZER; static pthread_key_t gEGLThreadLocalStorageKey = -1; @@ -261,14 +274,8 @@ EGLContext getContext() { return tls->ctx; } - /*****************************************************************************/ -class ISurfaceComposer; -const sp& getSurfaceFlinger(); -request_gpu_t* gpu_acquire(void* user); -int gpu_release(void*, request_gpu_t* gpu); - static __attribute__((noinline)) void *load_driver(const char* driver, gl_hooks_t* hooks) { @@ -278,42 +285,59 @@ void *load_driver(const char* driver, gl_hooks_t* hooks) driver, dlerror()); if (dso) { - void** curr; + // first find the symbol for eglGetProcAddress + + typedef __eglMustCastToProperFunctionPointerType (*getProcAddressType)( + const char*); + + getProcAddressType getProcAddress = + (getProcAddressType)dlsym(dso, "eglGetProcAddress"); + + LOGE_IF(!getProcAddress, + "can't find eglGetProcAddress() in %s", driver); + + __eglMustCastToProperFunctionPointerType* curr; char const * const * api; - gl_hooks_t::gl_t* gl = &hooks->gl; - curr = (void**)gl; - api = gl_names; - while (*api) { - void* f = dlsym(dso, *api); - //LOGD("<%s> @ 0x%p", *api, f); - if (f == NULL) { - //LOGW("<%s> not found in %s", *api, driver); - f = (void*)gl_unimplemented; - } - *curr++ = f; - api++; - } + gl_hooks_t::egl_t* egl = &hooks->egl; - curr = (void**)egl; + curr = (__eglMustCastToProperFunctionPointerType*)egl; api = egl_names; while (*api) { - void* f = dlsym(dso, *api); + char const * name = *api; + __eglMustCastToProperFunctionPointerType f = + (__eglMustCastToProperFunctionPointerType)dlsym(dso, name); if (f == NULL) { - //LOGW("<%s> not found in %s", *api, driver); - f = (void*)0; + // couldn't find the entry-point, use eglGetProcAddress() + f = getProcAddress(name); + if (f == NULL) { + f = (__eglMustCastToProperFunctionPointerType)0; + } } *curr++ = f; api++; } - - // hook this driver up with surfaceflinger if needed - register_gpu_t register_gpu = - (register_gpu_t)dlsym(dso, "oem_register_gpu"); - - if (register_gpu != NULL) { - if (getSurfaceFlinger() != 0) { - register_gpu(dso, gpu_acquire, gpu_release); + + gl_hooks_t::gl_t* gl = &hooks->gl; + curr = (__eglMustCastToProperFunctionPointerType*)gl; + api = gl_names; + while (*api) { + char const * name = *api; + // if the function starts with '__' it's a special case that + // uses a wrapper. skip the '__' when looking into the real lib. + if (name[0] == '_' && name[1] == '_') { + name += 2; } + __eglMustCastToProperFunctionPointerType f = + (__eglMustCastToProperFunctionPointerType)dlsym(dso, name); + if (f == NULL) { + // couldn't find the entry-point, use eglGetProcAddress() + f = getProcAddress(name); + if (f == NULL) { + f = (__eglMustCastToProperFunctionPointerType)gl_unimplemented; + } + } + *curr++ = f; + api++; } } return dso; @@ -365,6 +389,14 @@ struct extention_map_t { }; static const extention_map_t gExtentionMap[] = { + { "eglLockSurfaceKHR", + (__eglMustCastToProperFunctionPointerType)&eglLockSurfaceKHR }, + { "eglUnlockSurfaceKHR", + (__eglMustCastToProperFunctionPointerType)&eglUnlockSurfaceKHR }, + { "eglCreateImageKHR", + (__eglMustCastToProperFunctionPointerType)&eglCreateImageKHR }, + { "eglDestroyImageKHR", + (__eglMustCastToProperFunctionPointerType)&eglDestroyImageKHR }, }; static extention_map_t gGLExtentionMap[MAX_NUMBER_OF_GL_EXTENSIONS]; @@ -382,6 +414,12 @@ static void(*findProcAddress(const char* name, // ---------------------------------------------------------------------------- +/* + * To "loose" the GPU, use something like + * gEGLImpl[IMPL_HARDWARE].hooks = &gHooks[IMPL_CONTEXT_LOST]; + * + */ + static int gl_context_lost() { setGlThreadSpecific(&gHooks[IMPL_CONTEXT_LOST]); return 0; @@ -429,18 +467,24 @@ egl_display_t* get_display(EGLDisplay dpy) return (index >= NUM_DISPLAYS) ? NULL : &gDisplay[index]; } -static inline -egl_surface_t* get_surface(EGLSurface surface) -{ - egl_surface_t* s = (egl_surface_t *)surface; - return s; +template +static inline NATIVE* egl_to_native_cast(EGL arg) { + return reinterpret_cast(arg); } static inline -egl_context_t* get_context(EGLContext context) -{ - egl_context_t* c = (egl_context_t *)context; - return c; +egl_surface_t* get_surface(EGLSurface surface) { + return egl_to_native_cast(surface); +} + +static inline +egl_context_t* get_context(EGLContext context) { + return egl_to_native_cast(context); +} + +static inline +egl_image_t* get_image(EGLImageKHR image) { + return egl_to_native_cast(image); } static egl_connection_t* validate_display_config( @@ -451,7 +495,7 @@ static egl_connection_t* validate_display_config( if (!dp) return setError(EGL_BAD_DISPLAY, (egl_connection_t*)NULL); impl = uintptr_t(config)>>24; - if (uint32_t(impl) >= 2) { + if (uint32_t(impl) >= IMPL_NUM_DRIVERS_IMPLEMENTATIONS) { return setError(EGL_BAD_CONFIG, (egl_connection_t*)NULL); } index = uintptr_t(config) & 0xFFFFFF; @@ -491,13 +535,26 @@ static EGLBoolean validate_display_surface(EGLDisplay dpy, EGLSurface surface) return EGL_TRUE; } -// ---------------------------------------------------------------------------- -}; // namespace android -// ---------------------------------------------------------------------------- -using namespace android; +EGLImageKHR egl_get_image_for_current_context(EGLImageKHR image) +{ + EGLContext context = getContext(); + if (context == EGL_NO_CONTEXT || image == EGL_NO_IMAGE_KHR) + return EGL_NO_IMAGE_KHR; + + egl_context_t const * const c = get_context(context); + if (!c->isValid()) + return EGL_NO_IMAGE_KHR; -EGLDisplay eglGetDisplay(NativeDisplayType display) + egl_image_t const * const i = get_image(image); + if (!i->isValid()) + return EGL_NO_IMAGE_KHR; + + return i->images[c->impl]; +} + + +EGLDisplay egl_init_displays(NativeDisplayType display) { if (sEarlyInitState) { return EGL_NO_DISPLAY; @@ -510,7 +567,7 @@ EGLDisplay eglGetDisplay(NativeDisplayType display) EGLDisplay dpy = EGLDisplay(uintptr_t(display) + 1LU); egl_display_t* d = &gDisplay[index]; - + // dynamically load all our EGL implementations for that display // and call into the real eglGetGisplay() egl_connection_t* cnx = &gEGLImpl[IMPL_SOFTWARE]; @@ -530,7 +587,7 @@ EGLDisplay eglGetDisplay(NativeDisplayType display) property_get("debug.egl.hw", value, "1"); if (atoi(value) != 0) { cnx->hooks = &gHooks[IMPL_HARDWARE]; - cnx->dso = load_driver("libhgl.so", cnx->hooks); + cnx->dso = load_driver("libhgl2.so", cnx->hooks); } else { LOGD("3D hardware acceleration is disabled"); } @@ -573,6 +630,18 @@ EGLDisplay eglGetDisplay(NativeDisplayType display) return dpy; } + +// ---------------------------------------------------------------------------- +}; // namespace android +// ---------------------------------------------------------------------------- + +using namespace android; + +EGLDisplay eglGetDisplay(NativeDisplayType display) +{ + return egl_init_displays(display); +} + // ---------------------------------------------------------------------------- // Initialization // ---------------------------------------------------------------------------- @@ -594,7 +663,7 @@ EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) // build our own extension string first, based on the extension we know // and the extension supported by our client implementation dp->extensionsString = strdup(gExtensionString); - for (int i=0 ; i<2 ; i++) { + for (int i=0 ; imajor = -1; cnx->minor = -1; @@ -624,7 +693,7 @@ EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) } EGLBoolean res = EGL_FALSE; - for (int i=0 ; i<2 ; i++) { + for (int i=0 ; idso && cnx->major>=0 && cnx->minor>=0) { EGLint n; @@ -663,7 +732,7 @@ EGLBoolean eglTerminate(EGLDisplay dpy) return EGL_TRUE; EGLBoolean res = EGL_FALSE; - for (int i=0 ; i<2 ; i++) { + for (int i=0 ; idso) { cnx->hooks->egl.eglTerminate(dp->dpys[i]); @@ -706,7 +775,7 @@ EGLBoolean eglGetConfigs( EGLDisplay dpy, return EGL_TRUE; } GLint n = 0; - for (int j=0 ; j<2 ; j++) { + for (int j=0 ; jnumConfigs[j] && config_size ; i++) { *configs++ = MAKE_CONFIG(j, i); config_size--; @@ -794,7 +863,7 @@ EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list, return res; } - for (int i=0 ; i<2 ; i++) { + for (int i=0 ; idso) { if (cnx->hooks->egl.eglChooseConfig( @@ -854,26 +923,12 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config, int i=0, index=0; egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index); if (cnx) { - // window must be connected upon calling underlying - // eglCreateWindowSurface - if (window) { - window->incRef(window); - if (window->connect) - window->connect(window); - } - EGLSurface surface = cnx->hooks->egl.eglCreateWindowSurface( dp->dpys[i], dp->configs[i][index], window, attrib_list); if (surface != EGL_NO_SURFACE) { - egl_surface_t* s = new egl_surface_t(dpy, surface, window, i, cnx); + egl_surface_t* s = new egl_surface_t(dpy, surface, i, cnx); return s; } - - // something went wrong, disconnect and free window - // (will disconnect() automatically) - if (window) { - window->decRef(window); - } } return EGL_NO_SURFACE; } @@ -889,7 +944,7 @@ EGLSurface eglCreatePixmapSurface( EGLDisplay dpy, EGLConfig config, EGLSurface surface = cnx->hooks->egl.eglCreatePixmapSurface( dp->dpys[i], dp->configs[i][index], pixmap, attrib_list); if (surface != EGL_NO_SURFACE) { - egl_surface_t* s = new egl_surface_t(dpy, surface, NULL, i, cnx); + egl_surface_t* s = new egl_surface_t(dpy, surface, i, cnx); return s; } } @@ -906,7 +961,7 @@ EGLSurface eglCreatePbufferSurface( EGLDisplay dpy, EGLConfig config, EGLSurface surface = cnx->hooks->egl.eglCreatePbufferSurface( dp->dpys[i], dp->configs[i][index], attrib_list); if (surface != EGL_NO_SURFACE) { - egl_surface_t* s = new egl_surface_t(dpy, surface, NULL, i, cnx); + egl_surface_t* s = new egl_surface_t(dpy, surface, i, cnx); return s; } } @@ -1107,7 +1162,7 @@ EGLBoolean eglWaitNative(EGLint engine) EGLint eglGetError(void) { EGLint result = EGL_SUCCESS; - for (int i=0 ; i<2 ; i++) { + for (int i=0 ; idso) @@ -1120,8 +1175,15 @@ EGLint eglGetError(void) return result; } -void (*eglGetProcAddress(const char *procname))() +__eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname) { + // eglGetProcAddress() could be the very first function called + // in which case we must make sure we've initialized ourselves, this + // happens the first time egl_get_display() is called. + + if (egl_init_displays(EGL_DEFAULT_DISPLAY) == EGL_NO_DISPLAY) + return NULL; + __eglMustCastToProperFunctionPointerType addr; addr = findProcAddress(procname, gExtentionMap, NELEM(gExtentionMap)); if (addr) return addr; @@ -1133,7 +1195,7 @@ void (*eglGetProcAddress(const char *procname))() addr = 0; int slot = -1; - for (int i=0 ; i<2 ; i++) { + for (int i=0 ; idso) { if (cnx->hooks->egl.eglGetProcAddress) { @@ -1266,7 +1328,7 @@ EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval) if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE); EGLBoolean res = EGL_TRUE; - for (int i=0 ; i<2 ; i++) { + for (int i=0 ; idso) { if (cnx->hooks->egl.eglSwapInterval) { @@ -1309,7 +1371,7 @@ EGLBoolean eglBindAPI(EGLenum api) { // bind this API on all EGLs EGLBoolean res = EGL_TRUE; - for (int i=0 ; i<2 ; i++) { + for (int i=0 ; idso) { if (cnx->hooks->egl.eglBindAPI) { @@ -1324,7 +1386,7 @@ EGLBoolean eglBindAPI(EGLenum api) EGLenum eglQueryAPI(void) { - for (int i=0 ; i<2 ; i++) { + for (int i=0 ; idso) { if (cnx->hooks->egl.eglQueryAPI) { @@ -1340,7 +1402,7 @@ EGLenum eglQueryAPI(void) EGLBoolean eglReleaseThread(void) { - for (int i=0 ; i<2 ; i++) { + for (int i=0 ; idso) { if (cnx->hooks->egl.eglReleaseThread) { @@ -1366,3 +1428,124 @@ EGLSurface eglCreatePbufferFromClientBuffer( } return setError(EGL_BAD_CONFIG, EGL_NO_SURFACE); } + +// ---------------------------------------------------------------------------- +// EGL_EGLEXT_VERSION 3 +// ---------------------------------------------------------------------------- + +EGLBoolean eglLockSurfaceKHR(EGLDisplay dpy, EGLSurface surface, + const EGLint *attrib_list) +{ + EGLBoolean result = EGL_FALSE; + if (!validate_display_surface(dpy, surface)) + return result; + + egl_display_t const * const dp = get_display(dpy); + egl_surface_t const * const s = get_surface(surface); + + if (s->cnx->hooks->egl.eglLockSurfaceKHR) { + result = s->cnx->hooks->egl.eglLockSurfaceKHR( + dp->dpys[s->impl], s->surface, attrib_list); + } + return result; +} + +EGLBoolean eglUnlockSurfaceKHR(EGLDisplay dpy, EGLSurface surface) +{ + EGLBoolean result = EGL_FALSE; + if (!validate_display_surface(dpy, surface)) + return result; + + egl_display_t const * const dp = get_display(dpy); + egl_surface_t const * const s = get_surface(surface); + + if (s->cnx->hooks->egl.eglUnlockSurfaceKHR) { + result = s->cnx->hooks->egl.eglUnlockSurfaceKHR( + dp->dpys[s->impl], s->surface); + } + return result; +} + +EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, + EGLClientBuffer buffer, const EGLint *attrib_list) +{ + if (ctx != EGL_NO_CONTEXT) { + if (!validate_display_context(dpy, ctx)) + return EGL_NO_IMAGE_KHR; + egl_display_t const * const dp = get_display(dpy); + egl_context_t * const c = get_context(ctx); + // since we have an EGLContext, we know which implementation to use + EGLImageKHR image = c->cnx->hooks->egl.eglCreateImageKHR( + dp->dpys[c->impl], c->context, target, buffer, attrib_list); + if (image == EGL_NO_IMAGE_KHR) + return image; + + egl_image_t* result = new egl_image_t(dpy, ctx); + result->images[c->impl] = image; + return (EGLImageKHR)result; + } else { + // EGL_NO_CONTEXT is a valid parameter + egl_display_t const * const dp = get_display(dpy); + 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 + + EGLImageKHR implImages[IMPL_NUM_DRIVERS_IMPLEMENTATIONS]; + bool success = false; + for (int i=0 ; idso) { + if (cnx->hooks->egl.eglCreateImageKHR) { + implImages[i] = cnx->hooks->egl.eglCreateImageKHR( + dp->dpys[i], ctx, target, buffer, attrib_list); + if (implImages[i] != EGL_NO_IMAGE_KHR) { + success = true; + } + } + } + } + if (!success) + return EGL_NO_IMAGE_KHR; + + egl_image_t* result = new egl_image_t(dpy, ctx); + memcpy(result->images, implImages, sizeof(implImages)); + return (EGLImageKHR)result; + } +} + +EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img) +{ + egl_display_t const * const dp = get_display(dpy); + if (dp == 0) { + return setError(EGL_BAD_DISPLAY, EGL_FALSE); + } + + egl_image_t* image = get_image(img); + if (!image->isValid()) { + return setError(EGL_BAD_PARAMETER, EGL_FALSE); + } + + bool success = false; + for (int i=0 ; iimages[i] != EGL_NO_IMAGE_KHR) { + if (cnx->dso) { + if (cnx->hooks->egl.eglCreateImageKHR) { + if (cnx->hooks->egl.eglDestroyImageKHR( + dp->dpys[i], image->images[i])) { + success = true; + } + } + } + } + } + if (!success) + return EGL_FALSE; + + delete image; + + return EGL_FALSE; +} diff --git a/opengl/libs/GLES_CM/gl.cpp b/opengl/libs/GLES_CM/gl.cpp index 865cf44362f0a..a1753435042e8 100644 --- a/opengl/libs/GLES_CM/gl.cpp +++ b/opengl/libs/GLES_CM/gl.cpp @@ -14,8 +14,6 @@ ** limitations under the License. */ -#define LOG_TAG "GLES_CM" - #include #include #include @@ -29,6 +27,7 @@ #include #include "hooks.h" +#include "egl_impl.h" using namespace android; @@ -57,13 +56,6 @@ void glVertexPointerBounds(GLint size, GLenum type, // Actual GL entry-points // ---------------------------------------------------------------------------- -#if GL_LOGGER -# include "gl_logger.h" -# define GL_LOGGER_IMPL(_x) _x -#else -# define GL_LOGGER_IMPL(_x) -#endif - #undef API_ENTRY #undef CALL_GL_API #undef CALL_GL_API_RETURN @@ -96,16 +88,15 @@ void glVertexPointerBounds(GLint size, GLenum type, #define CALL_GL_API(_api, ...) \ gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \ - GL_LOGGER_IMPL( log_##_api(__VA_ARGS__); ) \ _c->_api(__VA_ARGS__) #define CALL_GL_API_RETURN(_api, ...) \ gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \ - GL_LOGGER_IMPL( log_##_api(__VA_ARGS__); ) \ return _c->_api(__VA_ARGS__) #endif + extern "C" { #include "gl_api.in" } @@ -114,3 +105,27 @@ extern "C" { #undef CALL_GL_API #undef CALL_GL_API_RETURN + +/* + * These GL calls are special because they need to EGL to retrieve some + * informations before they can execute. + */ + +extern "C" void __glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image); +extern "C" void __glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image); + + +void glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image) +{ + GLeglImageOES implImage = + (GLeglImageOES)egl_get_image_for_current_context((EGLImageKHR)image); + __glEGLImageTargetTexture2DOES(target, implImage); +} + +void glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image) +{ + GLeglImageOES implImage = + (GLeglImageOES)egl_get_image_for_current_context((EGLImageKHR)image); + __glEGLImageTargetRenderbufferStorageOES(target, image); +} + diff --git a/opengl/libs/GLES_CM/gl_api.in b/opengl/libs/GLES_CM/gl_api.in index 9234ef27387fb..f36b8c025ca46 100644 --- a/opengl/libs/GLES_CM/gl_api.in +++ b/opengl/libs/GLES_CM/gl_api.in @@ -1,144 +1,33 @@ -void API_ENTRY(glActiveTexture)(GLenum texture) { - CALL_GL_API(glActiveTexture, texture); +void API_ENTRY(glColor4f)(GLfloat arg0, GLfloat arg1, GLfloat arg2, GLfloat arg3) { + CALL_GL_API(glColor4f, arg0, arg1, arg2, arg3); } -void API_ENTRY(glAlphaFunc)(GLenum func, GLclampf ref) { - CALL_GL_API(glAlphaFunc, func, ref); +void API_ENTRY(glColor4x)(GLfixed arg0, GLfixed arg1, GLfixed arg2, GLfixed arg3) { + CALL_GL_API(glColor4x, arg0, arg1, arg2, arg3); } -void API_ENTRY(glAlphaFuncx)(GLenum func, GLclampx ref) { - CALL_GL_API(glAlphaFuncx, func, ref); +void API_ENTRY(glNormal3f)(GLfloat arg0, GLfloat arg1, GLfloat arg2) { + CALL_GL_API(glNormal3f, arg0, arg1, arg2); } -void API_ENTRY(glBindTexture)(GLenum target, GLuint texture) { - CALL_GL_API(glBindTexture, target, texture); +void API_ENTRY(glNormal3x)(GLfixed arg0, GLfixed arg1, GLfixed arg2) { + CALL_GL_API(glNormal3x, arg0, arg1, arg2); } -void API_ENTRY(glBlendFunc)(GLenum sfactor, GLenum dfactor) { - CALL_GL_API(glBlendFunc, sfactor, dfactor); +void API_ENTRY(glCullFace)(GLenum arg0) { + CALL_GL_API(glCullFace, arg0); } -void API_ENTRY(glClear)(GLbitfield mask) { - CALL_GL_API(glClear, mask); +void API_ENTRY(glFrontFace)(GLenum arg0) { + CALL_GL_API(glFrontFace, arg0); } -void API_ENTRY(glClearColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { - CALL_GL_API(glClearColor, red, green, blue, alpha); +void API_ENTRY(glDisable)(GLenum arg0) { + CALL_GL_API(glDisable, arg0); } -void API_ENTRY(glClearColorx)(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha) { - CALL_GL_API(glClearColorx, red, green, blue, alpha); -} - -void API_ENTRY(glClearDepthf)(GLclampf depth) { - CALL_GL_API(glClearDepthf, depth); -} - -void API_ENTRY(glClearDepthx)(GLclampx depth) { - CALL_GL_API(glClearDepthx, depth); -} - -void API_ENTRY(glClearStencil)(GLint s) { - CALL_GL_API(glClearStencil, s); -} - -void API_ENTRY(glClientActiveTexture)(GLenum texture) { - CALL_GL_API(glClientActiveTexture, texture); -} - -void API_ENTRY(glColor4f)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { - CALL_GL_API(glColor4f, red, green, blue, alpha); -} - -void API_ENTRY(glColor4x)(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha) { - CALL_GL_API(glColor4x, red, green, blue, alpha); -} - -void API_ENTRY(glColorMask)(GLboolean r, GLboolean g, GLboolean b, GLboolean a) { - CALL_GL_API(glColorMask, r, g, b, a); -} - -void API_ENTRY(glColorPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) -{ - CALL_GL_API(glColorPointer, size, type, stride, ptr); -} - -void API_ENTRY(glCompressedTexImage2D)(GLenum target, GLint level, GLenum internalformat, - GLsizei width, GLsizei height, GLint border, - GLsizei imageSize, const GLvoid *data) { - CALL_GL_API(glCompressedTexImage2D, target, level, internalformat, - width, height, border, imageSize, data); -} - -void API_ENTRY(glCompressedTexSubImage2D)( GLenum target, GLint level, GLint xoffset, - GLint yoffset, GLsizei width, GLsizei height, - GLenum format, GLsizei imageSize, - const GLvoid *data) { - CALL_GL_API(glCompressedTexSubImage2D, target, level, xoffset, yoffset, - width, height, format, imageSize, data); -} - -void API_ENTRY(glCopyTexImage2D)( GLenum target, GLint level, GLenum internalformat, - GLint x, GLint y, GLsizei width, GLsizei height, - GLint border) { - CALL_GL_API(glCopyTexImage2D, target, level, internalformat, x, y, - width, height, border); -} - -void API_ENTRY(glCopyTexSubImage2D)( GLenum target, GLint level, GLint xoffset, - GLint yoffset, GLint x, GLint y, GLsizei width, - GLsizei height) { - CALL_GL_API(glCopyTexSubImage2D, target, level, xoffset, yoffset, x, y, - width, height); -} - -void API_ENTRY(glCullFace)(GLenum mode) { - CALL_GL_API(glCullFace, mode); -} - -void API_ENTRY(glDeleteTextures)(GLsizei n, const GLuint *textures) { - CALL_GL_API(glDeleteTextures, n, textures); -} - -void API_ENTRY(glDepthFunc)(GLenum func) { - CALL_GL_API(glDepthFunc, func); -} - -void API_ENTRY(glDepthMask)(GLboolean flag) { - CALL_GL_API(glDepthMask, flag); -} - -void API_ENTRY(glDepthRangef)(GLclampf zNear, GLclampf zFar) { - CALL_GL_API(glDepthRangef, zNear, zFar); -} - -void API_ENTRY(glDepthRangex)(GLclampx zNear, GLclampx zFar) { - CALL_GL_API(glDepthRangex, zNear, zFar); -} - -void API_ENTRY(glDisable)(GLenum cap) { - CALL_GL_API(glDisable, cap); -} - -void API_ENTRY(glDisableClientState)(GLenum array) { - CALL_GL_API(glDisableClientState, array); -} - -void API_ENTRY(glDrawArrays)(GLenum mode, GLint first, GLsizei count) { - CALL_GL_API(glDrawArrays, mode, first, count); -} - -void API_ENTRY(glDrawElements)(GLenum mode, GLsizei count, - GLenum type, const GLvoid *indices) { - CALL_GL_API(glDrawElements, mode, count, type, indices); -} - -void API_ENTRY(glEnable)(GLenum cap) { - CALL_GL_API(glEnable, cap); -} - -void API_ENTRY(glEnableClientState)(GLenum array) { - CALL_GL_API(glEnableClientState, array); +void API_ENTRY(glEnable)(GLenum arg0) { + CALL_GL_API(glEnable, arg0); } void API_ENTRY(glFinish)(void) { @@ -149,192 +38,256 @@ void API_ENTRY(glFlush)(void) { CALL_GL_API(glFlush); } -void API_ENTRY(glFogf)(GLenum pname, GLfloat param) { - CALL_GL_API(glFogf, pname, param); -} - -void API_ENTRY(glFogfv)(GLenum pname, const GLfloat *params) { - CALL_GL_API(glFogfv, pname, params); -} - -void API_ENTRY(glFogx)(GLenum pname, GLfixed param) { - CALL_GL_API(glFogx, pname, param); -} - -void API_ENTRY(glFogxv)(GLenum pname, const GLfixed *params) { - CALL_GL_API(glFogxv, pname, params); -} - -void API_ENTRY(glFrontFace)(GLenum mode) { - CALL_GL_API(glFrontFace, mode); -} - -void API_ENTRY(glFrustumf)(GLfloat left, GLfloat right, - GLfloat bottom, GLfloat top, - GLfloat zNear, GLfloat zFar) { - CALL_GL_API(glFrustumf, left, right, bottom, top, zNear, zFar); -} - -void API_ENTRY(glFrustumx)(GLfixed left, GLfixed right, - GLfixed bottom, GLfixed top, - GLfixed zNear, GLfixed zFar) { - CALL_GL_API(glFrustumx, left, right, bottom, top, zNear, zFar); -} - -void API_ENTRY(glGenTextures)(GLsizei n, GLuint *textures) { - CALL_GL_API(glGenTextures, n, textures); -} - GLenum API_ENTRY(glGetError)(void) { CALL_GL_API_RETURN(glGetError); } -void API_ENTRY(glGetIntegerv)(GLenum pname, GLint *params) { - CALL_GL_API(glGetIntegerv, pname, params); +const GLubyte* API_ENTRY(glGetString)(GLenum arg0) { + CALL_GL_API_RETURN(glGetString, arg0); } -const GLubyte * API_ENTRY(glGetString)(GLenum name) { - CALL_GL_API_RETURN(glGetString, name); +void API_ENTRY(glGetIntegerv)(GLenum arg0, GLint * arg1) { + CALL_GL_API(glGetIntegerv, arg0, arg1); } -void API_ENTRY(glHint)(GLenum target, GLenum mode) { - CALL_GL_API(glHint, target, mode); +void API_ENTRY(glColorMask)(GLboolean arg0, GLboolean arg1, GLboolean arg2, GLboolean arg3) { + CALL_GL_API(glColorMask, arg0, arg1, arg2, arg3); } -void API_ENTRY(glLightModelf)(GLenum pname, GLfloat param) { - CALL_GL_API(glLightModelf, pname, param); +void API_ENTRY(glDepthMask)(GLboolean arg0) { + CALL_GL_API(glDepthMask, arg0); } -void API_ENTRY(glLightModelfv)(GLenum pname, const GLfloat *params) { - CALL_GL_API(glLightModelfv, pname, params); +void API_ENTRY(glStencilMask)(GLuint arg0) { + CALL_GL_API(glStencilMask, arg0); } -void API_ENTRY(glLightModelx)(GLenum pname, GLfixed param) { - CALL_GL_API(glLightModelx, pname, param); +void API_ENTRY(glDepthFunc)(GLenum arg0) { + CALL_GL_API(glDepthFunc, arg0); } -void API_ENTRY(glLightModelxv)(GLenum pname, const GLfixed *params) { - CALL_GL_API(glLightModelxv, pname, params); +void API_ENTRY(glDepthRangef)(GLclampf arg0, GLclampf arg1) { + CALL_GL_API(glDepthRangef, arg0, arg1); } -void API_ENTRY(glLightf)(GLenum light, GLenum pname, GLfloat param) { - CALL_GL_API(glLightf, light, pname, param); +void API_ENTRY(glDepthRangex)(GLclampx arg0, GLclampx arg1) { + CALL_GL_API(glDepthRangex, arg0, arg1); } -void API_ENTRY(glLightfv)(GLenum light, GLenum pname, const GLfloat *params) { - CALL_GL_API(glLightfv, light, pname, params); +void API_ENTRY(glPolygonOffset)(GLfloat arg0, GLfloat arg1) { + CALL_GL_API(glPolygonOffset, arg0, arg1); } -void API_ENTRY(glLightx)(GLenum light, GLenum pname, GLfixed param) { - CALL_GL_API(glLightx, light, pname, param); +void API_ENTRY(glPolygonOffsetx)(GLfixed arg0, GLfixed arg1) { + CALL_GL_API(glPolygonOffsetx, arg0, arg1); } -void API_ENTRY(glLightxv)(GLenum light, GLenum pname, const GLfixed *params) { - CALL_GL_API(glLightxv, light, pname, params); +void API_ENTRY(glLogicOp)(GLenum arg0) { + CALL_GL_API(glLogicOp, arg0); } -void API_ENTRY(glLineWidth)(GLfloat width) { - CALL_GL_API(glLineWidth, width); +void API_ENTRY(glAlphaFuncx)(GLenum arg0, GLclampx arg1) { + CALL_GL_API(glAlphaFuncx, arg0, arg1); } -void API_ENTRY(glLineWidthx)(GLfixed width) { - CALL_GL_API(glLineWidthx, width); +void API_ENTRY(glAlphaFunc)(GLenum arg0, GLclampf arg1) { + CALL_GL_API(glAlphaFunc, arg0, arg1); +} + +void API_ENTRY(glBlendFunc)(GLenum arg0, GLenum arg1) { + CALL_GL_API(glBlendFunc, arg0, arg1); +} + +void API_ENTRY(glClear)(GLbitfield arg0) { + CALL_GL_API(glClear, arg0); +} + +void API_ENTRY(glClearColor)(GLclampf arg0, GLclampf arg1, GLclampf arg2, GLclampf arg3) { + CALL_GL_API(glClearColor, arg0, arg1, arg2, arg3); +} + +void API_ENTRY(glClearColorx)(GLclampx arg0, GLclampx arg1, GLclampx arg2, GLclampx arg3) { + CALL_GL_API(glClearColorx, arg0, arg1, arg2, arg3); +} + +void API_ENTRY(glClearDepthf)(GLclampf arg0) { + CALL_GL_API(glClearDepthf, arg0); +} + +void API_ENTRY(glClearDepthx)(GLclampx arg0) { + CALL_GL_API(glClearDepthx, arg0); +} + +void API_ENTRY(glClearStencil)(GLint arg0) { + CALL_GL_API(glClearStencil, arg0); +} + +void API_ENTRY(glPointSize)(GLfloat arg0) { + CALL_GL_API(glPointSize, arg0); +} + +void API_ENTRY(glPointSizex)(GLfixed arg0) { + CALL_GL_API(glPointSizex, arg0); +} + +void API_ENTRY(glSampleCoverage)(GLclampf arg0, GLboolean arg1) { + CALL_GL_API(glSampleCoverage, arg0, arg1); +} + +void API_ENTRY(glSampleCoveragex)(GLclampx arg0, GLboolean arg1) { + CALL_GL_API(glSampleCoveragex, arg0, arg1); +} + +void API_ENTRY(glStencilFunc)(GLenum arg0, GLint arg1, GLuint arg2) { + CALL_GL_API(glStencilFunc, arg0, arg1, arg2); +} + +void API_ENTRY(glStencilOp)(GLenum arg0, GLenum arg1, GLenum arg2) { + CALL_GL_API(glStencilOp, arg0, arg1, arg2); +} + +void API_ENTRY(glScissor)(GLint arg0, GLint arg1, GLsizei arg2, GLsizei arg3) { + CALL_GL_API(glScissor, arg0, arg1, arg2, arg3); +} + +void API_ENTRY(glHint)(GLenum arg0, GLenum arg1) { + CALL_GL_API(glHint, arg0, arg1); +} + +void API_ENTRY(glLineWidth)(GLfloat arg0) { + CALL_GL_API(glLineWidth, arg0); +} + +void API_ENTRY(glLineWidthx)(GLfixed arg0) { + CALL_GL_API(glLineWidthx, arg0); +} + +void API_ENTRY(glShadeModel)(GLenum arg0) { + CALL_GL_API(glShadeModel, arg0); +} + +void API_ENTRY(glLightModelf)(GLenum arg0, GLfloat arg1) { + CALL_GL_API(glLightModelf, arg0, arg1); +} + +void API_ENTRY(glLightModelfv)(GLenum arg0, const GLfloat * arg1) { + CALL_GL_API(glLightModelfv, arg0, arg1); +} + +void API_ENTRY(glLightModelx)(GLenum arg0, GLfixed arg1) { + CALL_GL_API(glLightModelx, arg0, arg1); +} + +void API_ENTRY(glLightModelxv)(GLenum arg0, const GLfixed * arg1) { + CALL_GL_API(glLightModelxv, arg0, arg1); +} + +void API_ENTRY(glLightf)(GLenum arg0, GLenum arg1, GLfloat arg2) { + CALL_GL_API(glLightf, arg0, arg1, arg2); +} + +void API_ENTRY(glLightfv)(GLenum arg0, GLenum arg1, const GLfloat * arg2) { + CALL_GL_API(glLightfv, arg0, arg1, arg2); +} + +void API_ENTRY(glLightx)(GLenum arg0, GLenum arg1, GLfixed arg2) { + CALL_GL_API(glLightx, arg0, arg1, arg2); +} + +void API_ENTRY(glLightxv)(GLenum arg0, GLenum arg1, const GLfixed * arg2) { + CALL_GL_API(glLightxv, arg0, arg1, arg2); +} + +void API_ENTRY(glMaterialf)(GLenum arg0, GLenum arg1, GLfloat arg2) { + CALL_GL_API(glMaterialf, arg0, arg1, arg2); +} + +void API_ENTRY(glMaterialfv)(GLenum arg0, GLenum arg1, const GLfloat * arg2) { + CALL_GL_API(glMaterialfv, arg0, arg1, arg2); +} + +void API_ENTRY(glMaterialx)(GLenum arg0, GLenum arg1, GLfixed arg2) { + CALL_GL_API(glMaterialx, arg0, arg1, arg2); +} + +void API_ENTRY(glMaterialxv)(GLenum arg0, GLenum arg1, const GLfixed * arg2) { + CALL_GL_API(glMaterialxv, arg0, arg1, arg2); +} + +void API_ENTRY(glFogf)(GLenum arg0, GLfloat arg1) { + CALL_GL_API(glFogf, arg0, arg1); +} + +void API_ENTRY(glFogfv)(GLenum arg0, const GLfloat * arg1) { + CALL_GL_API(glFogfv, arg0, arg1); +} + +void API_ENTRY(glFogx)(GLenum arg0, GLfixed arg1) { + CALL_GL_API(glFogx, arg0, arg1); +} + +void API_ENTRY(glFogxv)(GLenum arg0, const GLfixed * arg1) { + CALL_GL_API(glFogxv, arg0, arg1); +} + +void API_ENTRY(glVertexPointer)(GLint arg0, GLenum arg1, GLsizei arg2, const GLvoid * arg3) { + CALL_GL_API(glVertexPointer, arg0, arg1, arg2, arg3); +} + +void API_ENTRY(glColorPointer)(GLint arg0, GLenum arg1, GLsizei arg2, const GLvoid * arg3) { + CALL_GL_API(glColorPointer, arg0, arg1, arg2, arg3); +} + +void API_ENTRY(glNormalPointer)(GLenum arg0, GLsizei arg1, const GLvoid * arg2) { + CALL_GL_API(glNormalPointer, arg0, arg1, arg2); +} + +void API_ENTRY(glTexCoordPointer)(GLint arg0, GLenum arg1, GLsizei arg2, const GLvoid * arg3) { + CALL_GL_API(glTexCoordPointer, arg0, arg1, arg2, arg3); +} + +void API_ENTRY(glEnableClientState)(GLenum arg0) { + CALL_GL_API(glEnableClientState, arg0); +} + +void API_ENTRY(glDisableClientState)(GLenum arg0) { + CALL_GL_API(glDisableClientState, arg0); +} + +void API_ENTRY(glClientActiveTexture)(GLenum arg0) { + CALL_GL_API(glClientActiveTexture, arg0); +} + +void API_ENTRY(glDrawArrays)(GLenum arg0, GLint arg1, GLsizei arg2) { + CALL_GL_API(glDrawArrays, arg0, arg1, arg2); +} + +void API_ENTRY(glDrawElements)(GLenum arg0, GLsizei arg1, GLenum arg2, const GLvoid * arg3) { + CALL_GL_API(glDrawElements, arg0, arg1, arg2, arg3); } void API_ENTRY(glLoadIdentity)(void) { CALL_GL_API(glLoadIdentity); } -void API_ENTRY(glLoadMatrixf)(const GLfloat *m) { - CALL_GL_API(glLoadMatrixf, m); +void API_ENTRY(glLoadMatrixf)(const GLfloat* arg0) { + CALL_GL_API(glLoadMatrixf, arg0); } -void API_ENTRY(glLoadMatrixx)(const GLfixed *m) { - CALL_GL_API(glLoadMatrixx, m); +void API_ENTRY(glLoadMatrixx)(const GLfixed* arg0) { + CALL_GL_API(glLoadMatrixx, arg0); } -void API_ENTRY(glLogicOp)(GLenum opcode) { - CALL_GL_API(glLogicOp, opcode); +void API_ENTRY(glMatrixMode)(GLenum arg0) { + CALL_GL_API(glMatrixMode, arg0); } -void API_ENTRY(glMaterialf)(GLenum face, GLenum pname, GLfloat param) { - CALL_GL_API(glMaterialf, face, pname, param); +void API_ENTRY(glMultMatrixf)(const GLfloat* arg0) { + CALL_GL_API(glMultMatrixf, arg0); } -void API_ENTRY(glMaterialfv)(GLenum face, GLenum pname, const GLfloat *params) { - CALL_GL_API(glMaterialfv, face, pname, params); -} - -void API_ENTRY(glMaterialx)(GLenum face, GLenum pname, GLfixed param) { - CALL_GL_API(glMaterialx, face, pname, param); -} - -void API_ENTRY(glMaterialxv)(GLenum face, GLenum pname, const GLfixed *params) { - CALL_GL_API(glMaterialxv, face, pname, params); -} - -void API_ENTRY(glMatrixMode)(GLenum mode) { - CALL_GL_API(glMatrixMode, mode); -} - -void API_ENTRY(glMultMatrixf)(const GLfloat *m) { - CALL_GL_API(glMultMatrixf, m); -} - -void API_ENTRY(glMultMatrixx)(const GLfixed *m) { - CALL_GL_API(glMultMatrixx, m); -} - -void API_ENTRY(glMultiTexCoord4f)(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) { - CALL_GL_API(glMultiTexCoord4f, target, s, t, r, q); -} - -void API_ENTRY(glMultiTexCoord4x)(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q) { - CALL_GL_API(glMultiTexCoord4x, target, s, t, r, q); -} - -void API_ENTRY(glNormal3f)(GLfloat nx, GLfloat ny, GLfloat nz) { - CALL_GL_API(glNormal3f, nx, ny, nz); -} - -void API_ENTRY(glNormal3x)(GLfixed nx, GLfixed ny, GLfixed nz) { - CALL_GL_API(glNormal3x, nx, ny, nz); -} - -void API_ENTRY(glNormalPointer)(GLenum type, GLsizei stride, const GLvoid *pointer) { - CALL_GL_API(glNormalPointer, type, stride, pointer); -} - -void API_ENTRY(glOrthof)( GLfloat left, GLfloat right, - GLfloat bottom, GLfloat top, - GLfloat zNear, GLfloat zFar) { - CALL_GL_API(glOrthof, left, right, bottom, top, zNear, zFar); -} - -void API_ENTRY(glOrthox)( GLfixed left, GLfixed right, - GLfixed bottom, GLfixed top, - GLfixed zNear, GLfixed zFar) { - CALL_GL_API(glOrthox, left, right, bottom, top, zNear, zFar); -} - -void API_ENTRY(glPixelStorei)(GLenum pname, GLint param) { - CALL_GL_API(glPixelStorei, pname, param); -} - -void API_ENTRY(glPointSize)(GLfloat size) { - CALL_GL_API(glPointSize, size); -} - -void API_ENTRY(glPointSizex)(GLfixed size) { - CALL_GL_API(glPointSizex, size); -} - -void API_ENTRY(glPolygonOffset)(GLfloat factor, GLfloat units) { - CALL_GL_API(glPolygonOffset, factor, units); -} - -void API_ENTRY(glPolygonOffsetx)(GLfixed factor, GLfixed units) { - CALL_GL_API(glPolygonOffsetx, factor, units); +void API_ENTRY(glMultMatrixx)(const GLfixed* arg0) { + CALL_GL_API(glMultMatrixx, arg0); } void API_ENTRY(glPopMatrix)(void) { @@ -345,262 +298,463 @@ void API_ENTRY(glPushMatrix)(void) { CALL_GL_API(glPushMatrix); } -void API_ENTRY(glReadPixels)( GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, GLvoid *pixels) { - CALL_GL_API(glReadPixels, x, y, width, height, format, type, pixels); +void API_ENTRY(glFrustumf)(GLfloat arg0, GLfloat arg1, GLfloat arg2, GLfloat arg3, GLfloat arg4, GLfloat arg5) { + CALL_GL_API(glFrustumf, arg0, arg1, arg2, arg3, arg4, arg5); } -void API_ENTRY(glRotatef)(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) { - CALL_GL_API(glRotatef, angle, x, y, z); +void API_ENTRY(glFrustumx)(GLfixed arg0, GLfixed arg1, GLfixed arg2, GLfixed arg3, GLfixed arg4, GLfixed arg5) { + CALL_GL_API(glFrustumx, arg0, arg1, arg2, arg3, arg4, arg5); } -void API_ENTRY(glRotatex)(GLfixed angle, GLfixed x, GLfixed y, GLfixed z) { - CALL_GL_API(glRotatex, angle, x, y, z); +void API_ENTRY(glOrthof)(GLfloat arg0, GLfloat arg1, GLfloat arg2, GLfloat arg3, GLfloat arg4, GLfloat arg5) { + CALL_GL_API(glOrthof, arg0, arg1, arg2, arg3, arg4, arg5); } -void API_ENTRY(glSampleCoverage)(GLclampf value, GLboolean invert) { - CALL_GL_API(glSampleCoverage, value, invert); +void API_ENTRY(glOrthox)(GLfixed arg0, GLfixed arg1, GLfixed arg2, GLfixed arg3, GLfixed arg4, GLfixed arg5) { + CALL_GL_API(glOrthox, arg0, arg1, arg2, arg3, arg4, arg5); } -void API_ENTRY(glSampleCoveragex)(GLclampx value, GLboolean invert) { - CALL_GL_API(glSampleCoveragex, value, invert); +void API_ENTRY(glRotatef)(GLfloat arg0, GLfloat arg1, GLfloat arg2, GLfloat arg3) { + CALL_GL_API(glRotatef, arg0, arg1, arg2, arg3); } -void API_ENTRY(glScalef)(GLfloat x, GLfloat y, GLfloat z) { - CALL_GL_API(glScalef, x, y, z); +void API_ENTRY(glRotatex)(GLfixed arg0, GLfixed arg1, GLfixed arg2, GLfixed arg3) { + CALL_GL_API(glRotatex, arg0, arg1, arg2, arg3); } -void API_ENTRY(glScalex)(GLfixed x, GLfixed y, GLfixed z) { - CALL_GL_API(glScalex, x, y, z); +void API_ENTRY(glScalef)(GLfloat arg0, GLfloat arg1, GLfloat arg2) { + CALL_GL_API(glScalef, arg0, arg1, arg2); } -void API_ENTRY(glScissor)(GLint x, GLint y, GLsizei width, GLsizei height) { - CALL_GL_API(glScissor, x, y, width, height); +void API_ENTRY(glScalex)(GLfixed arg0, GLfixed arg1, GLfixed arg2) { + CALL_GL_API(glScalex, arg0, arg1, arg2); } -void API_ENTRY(glShadeModel)(GLenum mode) { - CALL_GL_API(glShadeModel, mode); +void API_ENTRY(glTranslatef)(GLfloat arg0, GLfloat arg1, GLfloat arg2) { + CALL_GL_API(glTranslatef, arg0, arg1, arg2); } -void API_ENTRY(glStencilFunc)(GLenum func, GLint ref, GLuint mask) { - CALL_GL_API(glStencilFunc, func, ref, mask); +void API_ENTRY(glTranslatex)(GLfixed arg0, GLfixed arg1, GLfixed arg2) { + CALL_GL_API(glTranslatex, arg0, arg1, arg2); } -void API_ENTRY(glStencilMask)(GLuint mask) { - CALL_GL_API(glStencilMask, mask); +void API_ENTRY(glViewport)(GLint arg0, GLint arg1, GLsizei arg2, GLsizei arg3) { + CALL_GL_API(glViewport, arg0, arg1, arg2, arg3); } -void API_ENTRY(glStencilOp)(GLenum fail, GLenum zfail, GLenum zpass) { - CALL_GL_API(glStencilOp, fail, zfail, zpass); +void API_ENTRY(glActiveTexture)(GLenum arg0) { + CALL_GL_API(glActiveTexture, arg0); } -void API_ENTRY(glTexCoordPointer)( GLint size, GLenum type, - GLsizei stride, const GLvoid *pointer) { - CALL_GL_API(glTexCoordPointer, size, type, stride, pointer); +void API_ENTRY(glBindTexture)(GLenum arg0, GLuint arg1) { + CALL_GL_API(glBindTexture, arg0, arg1); } -void API_ENTRY(glTexEnvf)(GLenum target, GLenum pname, GLfloat param) { - CALL_GL_API(glTexEnvf, target, pname, param); +void API_ENTRY(glGenTextures)(GLsizei arg0, GLuint* arg1) { + CALL_GL_API(glGenTextures, arg0, arg1); } -void API_ENTRY(glTexEnvfv)(GLenum target, GLenum pname, const GLfloat *params) { - CALL_GL_API(glTexEnvfv, target, pname, params); +void API_ENTRY(glDeleteTextures)(GLsizei arg0, const GLuint * arg1) { + CALL_GL_API(glDeleteTextures, arg0, arg1); } -void API_ENTRY(glTexEnvx)(GLenum target, GLenum pname, GLfixed param) { - CALL_GL_API(glTexEnvx, target, pname, param); +void API_ENTRY(glMultiTexCoord4f)(GLenum arg0, GLfloat arg1, GLfloat arg2, GLfloat arg3, GLfloat arg4) { + CALL_GL_API(glMultiTexCoord4f, arg0, arg1, arg2, arg3, arg4); } -void API_ENTRY(glTexEnvxv)(GLenum target, GLenum pname, const GLfixed *params) { - CALL_GL_API(glTexEnvxv, target, pname, params); +void API_ENTRY(glMultiTexCoord4x)(GLenum arg0, GLfixed arg1, GLfixed arg2, GLfixed arg3, GLfixed arg4) { + CALL_GL_API(glMultiTexCoord4x, arg0, arg1, arg2, arg3, arg4); } -void API_ENTRY(glTexImage2D)( GLenum target, GLint level, GLint internalformat, - GLsizei width, GLsizei height, GLint border, GLenum format, - GLenum type, const GLvoid *pixels) { - CALL_GL_API(glTexImage2D, target, level, internalformat, width, height, - border, format, type, pixels); +void API_ENTRY(glPixelStorei)(GLenum arg0, GLint arg1) { + CALL_GL_API(glPixelStorei, arg0, arg1); } -void API_ENTRY(glTexParameterf)(GLenum target, GLenum pname, GLfloat param) { - CALL_GL_API(glTexParameterf, target, pname, param); +void API_ENTRY(glTexEnvf)(GLenum arg0, GLenum arg1, GLfloat arg2) { + CALL_GL_API(glTexEnvf, arg0, arg1, arg2); } -void API_ENTRY(glTexParameterx)(GLenum target, GLenum pname, GLfixed param) { - CALL_GL_API(glTexParameterx, target, pname, param); +void API_ENTRY(glTexEnvfv)(GLenum arg0, GLenum arg1, const GLfloat* arg2) { + CALL_GL_API(glTexEnvfv, arg0, arg1, arg2); } -void API_ENTRY(glTexSubImage2D)( GLenum target, GLint level, GLint xoffset, - GLint yoffset, GLsizei width, GLsizei height, - GLenum format, GLenum type, const GLvoid *pixels) { - CALL_GL_API(glTexSubImage2D, target, level, xoffset, yoffset, - width, height, format, type, pixels); +void API_ENTRY(glTexEnvx)(GLenum arg0, GLenum arg1, GLfixed arg2) { + CALL_GL_API(glTexEnvx, arg0, arg1, arg2); } -void API_ENTRY(glTranslatef)(GLfloat x, GLfloat y, GLfloat z) { - CALL_GL_API(glTranslatef, x, y, z); +void API_ENTRY(glTexEnvxv)(GLenum arg0, GLenum arg1, const GLfixed* arg2) { + CALL_GL_API(glTexEnvxv, arg0, arg1, arg2); } -void API_ENTRY(glTranslatex)(GLfixed x, GLfixed y, GLfixed z) { - CALL_GL_API(glTranslatex, x, y, z); +void API_ENTRY(glTexParameterf)(GLenum arg0, GLenum arg1, GLfloat arg2) { + CALL_GL_API(glTexParameterf, arg0, arg1, arg2); } -void API_ENTRY(glVertexPointer)( GLint size, GLenum type, - GLsizei stride, const GLvoid *pointer) { - CALL_GL_API(glVertexPointer, size, type, stride, pointer); +void API_ENTRY(glTexParameterx)(GLenum arg0, GLenum arg1, GLfixed arg2) { + CALL_GL_API(glTexParameterx, arg0, arg1, arg2); } -void API_ENTRY(glViewport)(GLint x, GLint y, GLsizei width, GLsizei height) { - CALL_GL_API(glViewport, x, y, width, height); +void API_ENTRY(glCompressedTexImage2D)(GLenum arg0, GLint arg1, GLenum arg2, GLsizei arg3, GLsizei arg4, GLint arg5, GLsizei arg6, const GLvoid* arg7) { + CALL_GL_API(glCompressedTexImage2D, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); } -// ES 1.1 -void API_ENTRY(glClipPlanef)(GLenum plane, const GLfloat *equation) { - CALL_GL_API(glClipPlanef, plane, equation); -} -void API_ENTRY(glClipPlanex)(GLenum plane, const GLfixed *equation) { - CALL_GL_API(glClipPlanex, plane, equation); -} -void API_ENTRY(glBindBuffer)(GLenum target, GLuint buffer) { - CALL_GL_API(glBindBuffer, target, buffer); -} -void API_ENTRY(glBufferData)(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) { - CALL_GL_API(glBufferData, target, size, data, usage); -} -void API_ENTRY(glBufferSubData)(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) { - CALL_GL_API(glBufferSubData, target, offset, size, data); -} -void API_ENTRY(glDeleteBuffers)(GLsizei n, const GLuint* buffers) { - CALL_GL_API(glDeleteBuffers, n, buffers); -} -void API_ENTRY(glGenBuffers)(GLsizei n, GLuint* buffers) { - CALL_GL_API(glGenBuffers, n, buffers); -} -void API_ENTRY(glGetBooleanv)(GLenum pname, GLboolean *params) { - CALL_GL_API(glGetBooleanv, pname, params); -} -void API_ENTRY(glGetFixedv)(GLenum pname, GLfixed *params) { - CALL_GL_API(glGetFixedv, pname, params); -} -void API_ENTRY(glGetFloatv)(GLenum pname, GLfloat *params) { - CALL_GL_API(glGetFloatv, pname, params); -} -void API_ENTRY(glGetPointerv)(GLenum pname, void **params) { - CALL_GL_API(glGetPointerv, pname, params); -} -void API_ENTRY(glGetBufferParameteriv)(GLenum target, GLenum pname, GLint *params) { - CALL_GL_API(glGetBufferParameteriv, target, pname, params); -} -void API_ENTRY(glGetClipPlanef)(GLenum pname, GLfloat eqn[4]) { - CALL_GL_API(glGetClipPlanef, pname, eqn); -} -void API_ENTRY(glGetClipPlanex)(GLenum pname, GLfixed eqn[4]) { - CALL_GL_API(glGetClipPlanex, pname, eqn); -} -void API_ENTRY(glGetLightxv)(GLenum light, GLenum pname, GLfixed *params) { - CALL_GL_API(glGetLightxv, light, pname, params); -} -void API_ENTRY(glGetLightfv)(GLenum light, GLenum pname, GLfloat *params) { - CALL_GL_API(glGetLightfv, light, pname, params); -} -void API_ENTRY(glGetMaterialxv)(GLenum face, GLenum pname, GLfixed *params) { - CALL_GL_API(glGetMaterialxv, face, pname, params); -} -void API_ENTRY(glGetMaterialfv)(GLenum face, GLenum pname, GLfloat *params) { - CALL_GL_API(glGetMaterialfv, face, pname, params); -} -void API_ENTRY(glGetTexEnvfv)(GLenum env, GLenum pname, GLfloat *params) { - CALL_GL_API(glGetTexEnvfv, env, pname, params); -} -void API_ENTRY(glGetTexEnviv)(GLenum env, GLenum pname, GLint *params) { - CALL_GL_API(glGetTexEnviv, env, pname, params); -} -void API_ENTRY(glGetTexEnvxv)(GLenum env, GLenum pname, GLfixed *params) { - CALL_GL_API(glGetTexEnvxv, env, pname, params); -} -void API_ENTRY(glGetTexParameterfv)(GLenum target, GLenum pname, GLfloat *params) { - CALL_GL_API(glGetTexParameterfv, target, pname, params); -} -void API_ENTRY(glGetTexParameteriv)(GLenum target, GLenum pname, GLint *params) { - CALL_GL_API(glGetTexParameteriv, target, pname, params); -} -void API_ENTRY(glGetTexParameterxv)(GLenum target, GLenum pname, GLfixed *params) { - CALL_GL_API(glGetTexParameterxv, target, pname, params); -} -GLboolean API_ENTRY(glIsBuffer)(GLuint buffer) { - CALL_GL_API_RETURN(glIsBuffer, buffer); -} -GLboolean API_ENTRY(glIsEnabled)(GLenum cap) { - CALL_GL_API_RETURN(glIsEnabled, cap); -} -GLboolean API_ENTRY(glIsTexture)(GLuint texture) { - CALL_GL_API_RETURN(glIsTexture, texture); -} -void API_ENTRY(glPointParameterf)(GLenum pname, GLfloat param) { - CALL_GL_API(glPointParameterf, pname, param); -} -void API_ENTRY(glPointParameterfv)(GLenum pname, const GLfloat *params) { - CALL_GL_API(glPointParameterfv, pname, params); -} -void API_ENTRY(glPointParameterx)(GLenum pname, GLfixed param) { - CALL_GL_API(glPointParameterx, pname, param); -} -void API_ENTRY(glPointParameterxv)(GLenum pname, const GLfixed *params) { - CALL_GL_API(glPointParameterxv, pname, params); -} -void API_ENTRY(glColor4ub)(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) { - CALL_GL_API(glColor4ub, red, green, blue, alpha); -} -void API_ENTRY(glTexEnvi)(GLenum target, GLenum pname, GLint param) { - CALL_GL_API(glTexEnvi, target, pname, param); -} -void API_ENTRY(glTexEnviv)(GLenum target, GLenum pname, const GLint *params) { - CALL_GL_API(glTexEnviv, target, pname, params); +void API_ENTRY(glCompressedTexSubImage2D)(GLenum arg0, GLint arg1, GLint arg2, GLint arg3, GLsizei arg4, GLsizei arg5, GLenum arg6, GLsizei arg7, const GLvoid* arg8) { + CALL_GL_API(glCompressedTexSubImage2D, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); } -void API_ENTRY(glTexParameterfv)(GLenum target, GLenum pname, const GLfloat *params) { - CALL_GL_API(glTexParameterfv, target, pname, params); +void API_ENTRY(glCopyTexImage2D)(GLenum arg0, GLint arg1, GLenum arg2, GLint arg3, GLint arg4, GLsizei arg5, GLsizei arg6, GLint arg7) { + CALL_GL_API(glCopyTexImage2D, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); } -void API_ENTRY(glTexParameteriv)(GLenum target, GLenum pname, const GLint *params) { - CALL_GL_API(glTexParameteriv, target, pname, params); +void API_ENTRY(glCopyTexSubImage2D)(GLenum arg0, GLint arg1, GLint arg2, GLint arg3, GLint arg4, GLint arg5, GLsizei arg6, GLsizei arg7) { + CALL_GL_API(glCopyTexSubImage2D, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); } -void API_ENTRY(glTexParameteri)(GLenum target, GLenum pname, GLint param) { - CALL_GL_API(glTexParameteri, target, pname, param); -} -void API_ENTRY(glTexParameterxv)(GLenum target, GLenum pname, const GLfixed *params) { - CALL_GL_API(glTexParameterxv, target, pname, params); -} -void API_ENTRY(glPointSizePointerOES)(GLenum type, GLsizei stride, const GLvoid *pointer) { - CALL_GL_API(glPointSizePointerOES, type, stride, pointer); +void API_ENTRY(glTexImage2D)(GLenum arg0, GLint arg1, GLint arg2, GLsizei arg3, GLsizei arg4, GLint arg5, GLenum arg6, GLenum arg7, const GLvoid* arg8) { + CALL_GL_API(glTexImage2D, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); } -// Extensions -void API_ENTRY(glDrawTexsOES)(GLshort x , GLshort y, GLshort z, GLshort w, GLshort h) { - CALL_GL_API(glDrawTexsOES, x, y, z, w, h); +void API_ENTRY(glTexSubImage2D)(GLenum arg0, GLint arg1, GLint arg2, GLint arg3, GLsizei arg4, GLsizei arg5, GLenum arg6, GLenum arg7, const GLvoid* arg8) { + CALL_GL_API(glTexSubImage2D, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); } -void API_ENTRY(glDrawTexiOES)(GLint x, GLint y, GLint z, GLint w, GLint h) { - CALL_GL_API(glDrawTexiOES, x, y, z, w, h); + +void API_ENTRY(glReadPixels)(GLint arg0, GLint arg1, GLsizei arg2, GLsizei arg3, GLenum arg4, GLenum arg5, GLvoid * arg6) { + CALL_GL_API(glReadPixels, arg0, arg1, arg2, arg3, arg4, arg5, arg6); } -void API_ENTRY(glDrawTexfOES)(GLfloat x, GLfloat y, GLfloat z, GLfloat w, GLfloat h) { - CALL_GL_API(glDrawTexfOES, x, y, z, w, h); + +void API_ENTRY(glClipPlanef)(GLenum arg0, const GLfloat* arg1) { + CALL_GL_API(glClipPlanef, arg0, arg1); } -void API_ENTRY(glDrawTexxOES)(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h) { - CALL_GL_API(glDrawTexxOES, x, y, z, w, h); + +void API_ENTRY(glClipPlanex)(GLenum arg0, const GLfixed* arg1) { + CALL_GL_API(glClipPlanex, arg0, arg1); } -void API_ENTRY(glDrawTexsvOES)(const GLshort* coords) { - CALL_GL_API(glDrawTexsvOES, coords); + +void API_ENTRY(glBindBuffer)(GLenum arg0, GLuint arg1) { + CALL_GL_API(glBindBuffer, arg0, arg1); } -void API_ENTRY(glDrawTexivOES)(const GLint* coords) { - CALL_GL_API(glDrawTexivOES, coords); + +void API_ENTRY(glBufferData)(GLenum arg0, GLsizeiptr arg1, const GLvoid* arg2, GLenum arg3) { + CALL_GL_API(glBufferData, arg0, arg1, arg2, arg3); } -void API_ENTRY(glDrawTexfvOES)(const GLfloat* coords) { - CALL_GL_API(glDrawTexfvOES, coords); + +void API_ENTRY(glBufferSubData)(GLenum arg0, GLintptr arg1, GLsizeiptr arg2, const GLvoid* arg3) { + CALL_GL_API(glBufferSubData, arg0, arg1, arg2, arg3); } -void API_ENTRY(glDrawTexxvOES)(const GLfixed* coords) { - CALL_GL_API(glDrawTexxvOES, coords); + +void API_ENTRY(glDeleteBuffers)(GLsizei arg0, const GLuint* arg1) { + CALL_GL_API(glDeleteBuffers, arg0, arg1); } -GLbitfield API_ENTRY(glQueryMatrixxOES)(GLfixed* mantissa, GLint* exponent) { - CALL_GL_API_RETURN(glQueryMatrixxOES, mantissa, exponent); + +void API_ENTRY(glGenBuffers)(GLsizei arg0, GLuint* arg1) { + CALL_GL_API(glGenBuffers, arg0, arg1); } + +void API_ENTRY(glGetBooleanv)(GLenum arg0, GLboolean * arg1) { + CALL_GL_API(glGetBooleanv, arg0, arg1); +} + +void API_ENTRY(glGetFixedv)(GLenum arg0, GLfixed * arg1) { + CALL_GL_API(glGetFixedv, arg0, arg1); +} + +void API_ENTRY(glGetFloatv)(GLenum arg0, GLfloat * arg1) { + CALL_GL_API(glGetFloatv, arg0, arg1); +} + +void API_ENTRY(glGetPointerv)(GLenum arg0, void ** arg1) { + CALL_GL_API(glGetPointerv, arg0, arg1); +} + +void API_ENTRY(glGetBufferParameteriv)(GLenum arg0, GLenum arg1, GLint * arg2) { + CALL_GL_API(glGetBufferParameteriv, arg0, arg1, arg2); +} + +void API_ENTRY(glGetClipPlanef)(GLenum arg0, GLfloat arg1[4]) { + CALL_GL_API(glGetClipPlanef, arg0, arg1); +} + +void API_ENTRY(glGetClipPlanex)(GLenum arg0, GLfixed arg1[4]) { + CALL_GL_API(glGetClipPlanex, arg0, arg1); +} + +void API_ENTRY(glGetLightxv)(GLenum arg0, GLenum arg1, GLfixed * arg2) { + CALL_GL_API(glGetLightxv, arg0, arg1, arg2); +} + +void API_ENTRY(glGetLightfv)(GLenum arg0, GLenum arg1, GLfloat * arg2) { + CALL_GL_API(glGetLightfv, arg0, arg1, arg2); +} + +void API_ENTRY(glGetMaterialxv)(GLenum arg0, GLenum arg1, GLfixed * arg2) { + CALL_GL_API(glGetMaterialxv, arg0, arg1, arg2); +} + +void API_ENTRY(glGetMaterialfv)(GLenum arg0, GLenum arg1, GLfloat * arg2) { + CALL_GL_API(glGetMaterialfv, arg0, arg1, arg2); +} + +void API_ENTRY(glGetTexEnvfv)(GLenum arg0, GLenum arg1, GLfloat * arg2) { + CALL_GL_API(glGetTexEnvfv, arg0, arg1, arg2); +} + +void API_ENTRY(glGetTexEnviv)(GLenum arg0, GLenum arg1, GLint * arg2) { + CALL_GL_API(glGetTexEnviv, arg0, arg1, arg2); +} + +void API_ENTRY(glGetTexEnvxv)(GLenum arg0, GLenum arg1, GLfixed * arg2) { + CALL_GL_API(glGetTexEnvxv, arg0, arg1, arg2); +} + +void API_ENTRY(glGetTexParameterfv)(GLenum arg0, GLenum arg1, GLfloat * arg2) { + CALL_GL_API(glGetTexParameterfv, arg0, arg1, arg2); +} + +void API_ENTRY(glGetTexParameteriv)(GLenum arg0, GLenum arg1, GLint * arg2) { + CALL_GL_API(glGetTexParameteriv, arg0, arg1, arg2); +} + +void API_ENTRY(glGetTexParameterxv)(GLenum arg0, GLenum arg1, GLfixed * arg2) { + CALL_GL_API(glGetTexParameterxv, arg0, arg1, arg2); +} + +GLboolean API_ENTRY(glIsBuffer)(GLuint arg0) { + CALL_GL_API_RETURN(glIsBuffer, arg0); +} + +GLboolean API_ENTRY(glIsEnabled)(GLenum arg0) { + CALL_GL_API_RETURN(glIsEnabled, arg0); +} + +GLboolean API_ENTRY(glIsTexture)(GLuint arg0) { + CALL_GL_API_RETURN(glIsTexture, arg0); +} + +void API_ENTRY(glPointParameterf)(GLenum arg0, GLfloat arg1) { + CALL_GL_API(glPointParameterf, arg0, arg1); +} + +void API_ENTRY(glPointParameterfv)(GLenum arg0, const GLfloat * arg1) { + CALL_GL_API(glPointParameterfv, arg0, arg1); +} + +void API_ENTRY(glPointParameterx)(GLenum arg0, GLfixed arg1) { + CALL_GL_API(glPointParameterx, arg0, arg1); +} + +void API_ENTRY(glPointParameterxv)(GLenum arg0, const GLfixed * arg1) { + CALL_GL_API(glPointParameterxv, arg0, arg1); +} + +void API_ENTRY(glColor4ub)(GLubyte arg0, GLubyte arg1, GLubyte arg2, GLubyte arg3) { + CALL_GL_API(glColor4ub, arg0, arg1, arg2, arg3); +} + +void API_ENTRY(glTexEnvi)(GLenum arg0, GLenum arg1, GLint arg2) { + CALL_GL_API(glTexEnvi, arg0, arg1, arg2); +} + +void API_ENTRY(glTexEnviv)(GLenum arg0, GLenum arg1, const GLint * arg2) { + CALL_GL_API(glTexEnviv, arg0, arg1, arg2); +} + +void API_ENTRY(glTexParameterfv)(GLenum arg0, GLenum arg1, const GLfloat * arg2) { + CALL_GL_API(glTexParameterfv, arg0, arg1, arg2); +} + +void API_ENTRY(glTexParameteriv)(GLenum arg0, GLenum arg1, const GLint * arg2) { + CALL_GL_API(glTexParameteriv, arg0, arg1, arg2); +} + +void API_ENTRY(glTexParameteri)(GLenum arg0, GLenum arg1, GLint arg2) { + CALL_GL_API(glTexParameteri, arg0, arg1, arg2); +} + +void API_ENTRY(glTexParameterxv)(GLenum arg0, GLenum arg1, const GLfixed * arg2) { + CALL_GL_API(glTexParameterxv, arg0, arg1, arg2); +} + +void API_ENTRY(glPointSizePointerOES)(GLenum arg0, GLsizei arg1, const GLvoid* arg2) { + CALL_GL_API(glPointSizePointerOES, arg0, arg1, arg2); +} + +void API_ENTRY(glDrawTexsOES)(GLshort arg0, GLshort arg1, GLshort arg2, GLshort arg3, GLshort arg4) { + CALL_GL_API(glDrawTexsOES, arg0, arg1, arg2, arg3, arg4); +} + +void API_ENTRY(glDrawTexiOES)(GLint arg0, GLint arg1, GLint arg2, GLint arg3, GLint arg4) { + CALL_GL_API(glDrawTexiOES, arg0, arg1, arg2, arg3, arg4); +} + +void API_ENTRY(glDrawTexfOES)(GLfloat arg0, GLfloat arg1, GLfloat arg2, GLfloat arg3, GLfloat arg4) { + CALL_GL_API(glDrawTexfOES, arg0, arg1, arg2, arg3, arg4); +} + +void API_ENTRY(glDrawTexxOES)(GLfixed arg0, GLfixed arg1, GLfixed arg2, GLfixed arg3, GLfixed arg4) { + CALL_GL_API(glDrawTexxOES, arg0, arg1, arg2, arg3, arg4); +} + +void API_ENTRY(glDrawTexsvOES)(const GLshort* arg0) { + CALL_GL_API(glDrawTexsvOES, arg0); +} + +void API_ENTRY(glDrawTexivOES)(const GLint* arg0) { + CALL_GL_API(glDrawTexivOES, arg0); +} + +void API_ENTRY(glDrawTexfvOES)(const GLfloat* arg0) { + CALL_GL_API(glDrawTexfvOES, arg0); +} + +void API_ENTRY(glDrawTexxvOES)(const GLfixed* arg0) { + CALL_GL_API(glDrawTexxvOES, arg0); +} + +GLbitfield API_ENTRY(glQueryMatrixxOES)(GLfixed* arg0, GLint* arg1) { + CALL_GL_API_RETURN(glQueryMatrixxOES, arg0, arg1); +} + +void API_ENTRY(__glEGLImageTargetTexture2DOES)(GLenum arg0, GLeglImageOES arg1) { + CALL_GL_API(__glEGLImageTargetTexture2DOES, arg0, arg1); +} + +void API_ENTRY(__glEGLImageTargetRenderbufferStorageOES)(GLenum arg0, GLeglImageOES arg1) { + CALL_GL_API(__glEGLImageTargetRenderbufferStorageOES, arg0, arg1); +} + +void API_ENTRY(glBlendEquationSeparateOES)(GLenum arg0, GLenum arg1) { + CALL_GL_API(glBlendEquationSeparateOES, arg0, arg1); +} + +void API_ENTRY(glBlendFuncSeparateOES)(GLenum arg0, GLenum arg1, GLenum arg2, GLenum arg3) { + CALL_GL_API(glBlendFuncSeparateOES, arg0, arg1, arg2, arg3); +} + +void API_ENTRY(glBlendEquationOES)(GLenum arg0) { + CALL_GL_API(glBlendEquationOES, arg0); +} + +GLboolean API_ENTRY(glIsRenderbufferOES)(GLuint arg0) { + CALL_GL_API_RETURN(glIsRenderbufferOES, arg0); +} + +void API_ENTRY(glBindRenderbufferOES)(GLenum arg0, GLuint arg1) { + CALL_GL_API(glBindRenderbufferOES, arg0, arg1); +} + +void API_ENTRY(glDeleteRenderbuffersOES)(GLsizei arg0, const GLuint* arg1) { + CALL_GL_API(glDeleteRenderbuffersOES, arg0, arg1); +} + +void API_ENTRY(glGenRenderbuffersOES)(GLsizei arg0, GLuint* arg1) { + CALL_GL_API(glGenRenderbuffersOES, arg0, arg1); +} + +void API_ENTRY(glRenderbufferStorageOES)(GLenum arg0, GLenum arg1, GLsizei arg2, GLsizei arg3) { + CALL_GL_API(glRenderbufferStorageOES, arg0, arg1, arg2, arg3); +} + +void API_ENTRY(glGetRenderbufferParameterivOES)(GLenum arg0, GLenum arg1, GLint* arg2) { + CALL_GL_API(glGetRenderbufferParameterivOES, arg0, arg1, arg2); +} + +GLboolean API_ENTRY(glIsFramebufferOES)(GLuint arg0) { + CALL_GL_API_RETURN(glIsFramebufferOES, arg0); +} + +void API_ENTRY(glBindFramebufferOES)(GLenum arg0, GLuint arg1) { + CALL_GL_API(glBindFramebufferOES, arg0, arg1); +} + +void API_ENTRY(glDeleteFramebuffersOES)(GLsizei arg0, const GLuint* arg1) { + CALL_GL_API(glDeleteFramebuffersOES, arg0, arg1); +} + +void API_ENTRY(glGenFramebuffersOES)(GLsizei arg0, GLuint* arg1) { + CALL_GL_API(glGenFramebuffersOES, arg0, arg1); +} + +GLenum API_ENTRY(glCheckFramebufferStatusOES)(GLenum arg0) { + CALL_GL_API_RETURN(glCheckFramebufferStatusOES, arg0); +} + +void API_ENTRY(glFramebufferRenderbufferOES)(GLenum arg0, GLenum arg1, GLenum arg2, GLuint arg3) { + CALL_GL_API(glFramebufferRenderbufferOES, arg0, arg1, arg2, arg3); +} + +void API_ENTRY(glFramebufferTexture2DOES)(GLenum arg0, GLenum arg1, GLenum arg2, GLuint arg3, GLint arg4) { + CALL_GL_API(glFramebufferTexture2DOES, arg0, arg1, arg2, arg3, arg4); +} + +void API_ENTRY(glGetFramebufferAttachmentParameterivOES)(GLenum arg0, GLenum arg1, GLenum arg2, GLint* arg3) { + CALL_GL_API(glGetFramebufferAttachmentParameterivOES, arg0, arg1, arg2, arg3); +} + +void API_ENTRY(glGenerateMipmapOES)(GLenum arg0) { + CALL_GL_API(glGenerateMipmapOES, arg0); +} + +void* API_ENTRY(glMapBufferOES)(GLenum arg0, GLenum arg1) { + CALL_GL_API_RETURN(glMapBufferOES, arg0, arg1); +} + +GLboolean API_ENTRY(glUnmapBufferOES)(GLenum arg0) { + CALL_GL_API_RETURN(glUnmapBufferOES, arg0); +} + +void API_ENTRY(glGetBufferPointervOES)(GLenum arg0, GLenum arg1, void** arg2) { + CALL_GL_API(glGetBufferPointervOES, arg0, arg1, arg2); +} + +void API_ENTRY(glCurrentPaletteMatrixOES)(GLuint arg0) { + CALL_GL_API(glCurrentPaletteMatrixOES, arg0); +} + +void API_ENTRY(glLoadPaletteFromModelViewMatrixOES)(void) { + CALL_GL_API(glLoadPaletteFromModelViewMatrixOES); +} + +void API_ENTRY(glMatrixIndexPointerOES)(GLint arg0, GLenum arg1, GLsizei arg2, const GLvoid * arg3) { + CALL_GL_API(glMatrixIndexPointerOES, arg0, arg1, arg2, arg3); +} + +void API_ENTRY(glWeightPointerOES)(GLint arg0, GLenum arg1, GLsizei arg2, const GLvoid * arg3) { + CALL_GL_API(glWeightPointerOES, arg0, arg1, arg2, arg3); +} + +void API_ENTRY(glTexGenfOES)(GLenum arg0, GLenum arg1, GLfloat arg2) { + CALL_GL_API(glTexGenfOES, arg0, arg1, arg2); +} + +void API_ENTRY(glTexGenfvOES)(GLenum arg0, GLenum arg1, const GLfloat * arg2) { + CALL_GL_API(glTexGenfvOES, arg0, arg1, arg2); +} + +void API_ENTRY(glTexGeniOES)(GLenum arg0, GLenum arg1, GLint arg2) { + CALL_GL_API(glTexGeniOES, arg0, arg1, arg2); +} + +void API_ENTRY(glTexGenivOES)(GLenum arg0, GLenum arg1, const GLint * arg2) { + CALL_GL_API(glTexGenivOES, arg0, arg1, arg2); +} + +void API_ENTRY(glTexGenxOES)(GLenum arg0, GLenum arg1, GLfixed arg2) { + CALL_GL_API(glTexGenxOES, arg0, arg1, arg2); +} + +void API_ENTRY(glTexGenxvOES)(GLenum arg0, GLenum arg1, const GLfixed * arg2) { + CALL_GL_API(glTexGenxvOES, arg0, arg1, arg2); +} + +void API_ENTRY(glGetTexGenfvOES)(GLenum arg0, GLenum arg1, GLfloat * arg2) { + CALL_GL_API(glGetTexGenfvOES, arg0, arg1, arg2); +} + +void API_ENTRY(glGetTexGenivOES)(GLenum arg0, GLenum arg1, GLint * arg2) { + CALL_GL_API(glGetTexGenivOES, arg0, arg1, arg2); +} + +void API_ENTRY(glGetTexGenxvOES)(GLenum arg0, GLenum arg1, GLfixed * arg2) { + CALL_GL_API(glGetTexGenxvOES, arg0, arg1, arg2); +} + diff --git a/opengl/libs/egl_entries.in b/opengl/libs/egl_entries.in index 33b4c654d207f..3b4551b639646 100644 --- a/opengl/libs/egl_entries.in +++ b/opengl/libs/egl_entries.in @@ -43,3 +43,10 @@ EGL_ENTRY(EGLSurface, eglCreatePbufferFromClientBuffer, EGLDisplay, EGLenum, EGL /* EGL 1.3 */ /* EGL 1.4 */ + +/* EGL_EGLEXT_VERSION 3 */ + +EGL_ENTRY(EGLBoolean, eglLockSurfaceKHR, EGLDisplay, EGLSurface, const EGLint *) +EGL_ENTRY(EGLBoolean, eglUnlockSurfaceKHR, EGLDisplay, EGLSurface) +EGL_ENTRY(EGLImageKHR, eglCreateImageKHR, EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, const EGLint *) +EGL_ENTRY(EGLBoolean, eglDestroyImageKHR, EGLDisplay, EGLImageKHR) diff --git a/opengl/libs/egl_impl.h b/opengl/libs/egl_impl.h index 62ce3fce17009..4e0c7bfeba691 100644 --- a/opengl/libs/egl_impl.h +++ b/opengl/libs/egl_impl.h @@ -20,6 +20,7 @@ #include #include +#include // ---------------------------------------------------------------------------- namespace android { @@ -36,6 +37,8 @@ struct egl_connection_t int unavailable; }; +EGLImageKHR egl_get_image_for_current_context(EGLImageKHR image); + // ---------------------------------------------------------------------------- }; // namespace android // ---------------------------------------------------------------------------- diff --git a/opengl/libs/gl_entries.in b/opengl/libs/gl_entries.in index b97e8fe3c479d..4e8f8284f8444 100644 --- a/opengl/libs/gl_entries.in +++ b/opengl/libs/gl_entries.in @@ -15,30 +15,30 @@ GL_ENTRY(void, glColorMask, GLboolean, GLboolean, GLboolean, GLboolean) GL_ENTRY(void, glDepthMask, GLboolean) GL_ENTRY(void, glStencilMask, GLuint) GL_ENTRY(void, glDepthFunc, GLenum) -GL_ENTRY(void, glDepthRangef, GLclampf zNear, GLclampf zFar) -GL_ENTRY(void, glDepthRangex, GLclampx zNear, GLclampx zFar) -GL_ENTRY(void, glPolygonOffset, GLfloat factor, GLfloat units) -GL_ENTRY(void, glPolygonOffsetx, GLfixed factor, GLfixed units) -GL_ENTRY(void, glLogicOp, GLenum opcode) -GL_ENTRY(void, glAlphaFuncx, GLenum func, GLclampx ref) -GL_ENTRY(void, glAlphaFunc, GLenum func, GLclampf ref) -GL_ENTRY(void, glBlendFunc, GLenum sfactor, GLenum dfactor) -GL_ENTRY(void, glClear, GLbitfield mask) -GL_ENTRY(void, glClearColor, GLclampf r, GLclampf g, GLclampf b, GLclampf a) -GL_ENTRY(void, glClearColorx, GLclampx r, GLclampx g, GLclampx b, GLclampx a) -GL_ENTRY(void, glClearDepthf, GLclampf depth) -GL_ENTRY(void, glClearDepthx, GLclampx depth) -GL_ENTRY(void, glClearStencil, GLint s) +GL_ENTRY(void, glDepthRangef, GLclampf, GLclampf) +GL_ENTRY(void, glDepthRangex, GLclampx, GLclampx) +GL_ENTRY(void, glPolygonOffset, GLfloat, GLfloat) +GL_ENTRY(void, glPolygonOffsetx, GLfixed, GLfixed) +GL_ENTRY(void, glLogicOp, GLenum) +GL_ENTRY(void, glAlphaFuncx, GLenum, GLclampx) +GL_ENTRY(void, glAlphaFunc, GLenum, GLclampf) +GL_ENTRY(void, glBlendFunc, GLenum, GLenum) +GL_ENTRY(void, glClear, GLbitfield) +GL_ENTRY(void, glClearColor, GLclampf, GLclampf, GLclampf, GLclampf) +GL_ENTRY(void, glClearColorx, GLclampx, GLclampx, GLclampx, GLclampx) +GL_ENTRY(void, glClearDepthf, GLclampf) +GL_ENTRY(void, glClearDepthx, GLclampx) +GL_ENTRY(void, glClearStencil, GLint) GL_ENTRY(void, glPointSize, GLfloat) GL_ENTRY(void, glPointSizex, GLfixed) -GL_ENTRY(void, glSampleCoverage, GLclampf value, GLboolean invert) -GL_ENTRY(void, glSampleCoveragex, GLclampx value, GLboolean invert) -GL_ENTRY(void, glStencilFunc, GLenum func, GLint ref, GLuint mask) -GL_ENTRY(void, glStencilOp, GLenum fail, GLenum zfail, GLenum zpass) -GL_ENTRY(void, glScissor, GLint x, GLint y, GLsizei width, GLsizei height) -GL_ENTRY(void, glHint, GLenum, GLenum mode) -GL_ENTRY(void, glLineWidth, GLfloat width) -GL_ENTRY(void, glLineWidthx, GLfixed width) +GL_ENTRY(void, glSampleCoverage, GLclampf, GLboolean) +GL_ENTRY(void, glSampleCoveragex, GLclampx, GLboolean) +GL_ENTRY(void, glStencilFunc, GLenum, GLint, GLuint) +GL_ENTRY(void, glStencilOp, GLenum, GLenum, GLenum) +GL_ENTRY(void, glScissor, GLint, GLint, GLsizei, GLsizei) +GL_ENTRY(void, glHint, GLenum, GLenum) +GL_ENTRY(void, glLineWidth, GLfloat) +GL_ENTRY(void, glLineWidthx, GLfixed) GL_ENTRY(void, glShadeModel, GLenum) GL_ENTRY(void, glLightModelf, GLenum, GLfloat) GL_ENTRY(void, glLightModelfv, GLenum, const GLfloat *) @@ -63,12 +63,12 @@ GL_ENTRY(void, glTexCoordPointer, GLint, GLenum, GLsizei, const GLvoid *) GL_ENTRY(void, glEnableClientState, GLenum) GL_ENTRY(void, glDisableClientState, GLenum) GL_ENTRY(void, glClientActiveTexture, GLenum) -GL_ENTRY(void, glDrawArrays, GLenum, GLint first, GLsizei) +GL_ENTRY(void, glDrawArrays, GLenum, GLint, GLsizei) GL_ENTRY(void, glDrawElements, GLenum, GLsizei, GLenum, const GLvoid *) GL_ENTRY(void, glLoadIdentity, void) GL_ENTRY(void, glLoadMatrixf, const GLfloat*) GL_ENTRY(void, glLoadMatrixx, const GLfixed*) -GL_ENTRY(void, glMatrixMode, GLenum mode) +GL_ENTRY(void, glMatrixMode, GLenum) GL_ENTRY(void, glMultMatrixf, const GLfloat*) GL_ENTRY(void, glMultMatrixx, const GLfixed*) GL_ENTRY(void, glPopMatrix, void) @@ -87,7 +87,7 @@ GL_ENTRY(void, glViewport, GLint, GLint, GLsizei, GLsizei) GL_ENTRY(void, glActiveTexture, GLenum) GL_ENTRY(void, glBindTexture, GLenum, GLuint) GL_ENTRY(void, glGenTextures, GLsizei, GLuint*) -GL_ENTRY(void, glDeleteTextures, GLsizei n, const GLuint *) +GL_ENTRY(void, glDeleteTextures, GLsizei, const GLuint *) GL_ENTRY(void, glMultiTexCoord4f, GLenum, GLfloat, GLfloat, GLfloat, GLfloat) GL_ENTRY(void, glMultiTexCoord4x, GLenum, GLfixed, GLfixed, GLfixed, GLfixed) GL_ENTRY(void, glPixelStorei, GLenum, GLint) @@ -106,8 +106,8 @@ GL_ENTRY(void, glTexSubImage2D, GLenum, GLint, GLint, GLint, GLsizei, GLsizei, G GL_ENTRY(void, glReadPixels, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLvoid *) // 1.1 additions -GL_ENTRY(void, glClipPlanef, GLenum plane, const GLfloat*) -GL_ENTRY(void, glClipPlanex, GLenum plane, const GLfixed*) +GL_ENTRY(void, glClipPlanef, GLenum, const GLfloat*) +GL_ENTRY(void, glClipPlanex, GLenum, const GLfixed*) GL_ENTRY(void, glBindBuffer, GLenum, GLuint) GL_ENTRY(void, glBufferData, GLenum, GLsizeiptr, const GLvoid*, GLenum) GL_ENTRY(void, glBufferSubData, GLenum, GLintptr, GLsizeiptr, const GLvoid*) @@ -144,7 +144,7 @@ GL_ENTRY(void, glTexParameterfv, GLenum, GLenum, const GLfloat *) GL_ENTRY(void, glTexParameteriv, GLenum, GLenum, const GLint *) GL_ENTRY(void, glTexParameteri, GLenum, GLenum, GLint) GL_ENTRY(void, glTexParameterxv, GLenum, GLenum, const GLfixed *) -GL_ENTRY(void, glPointSizePointerOES, GLenum type, GLsizei stride, const GLvoid*) +GL_ENTRY(void, glPointSizePointerOES, GLenum, GLsizei, const GLvoid*) // Extensions GL_ENTRY(void, glDrawTexsOES, GLshort, GLshort, GLshort, GLshort, GLshort) @@ -155,5 +155,40 @@ GL_ENTRY(void, glDrawTexsvOES, const GLshort*) GL_ENTRY(void, glDrawTexivOES, const GLint*) GL_ENTRY(void, glDrawTexfvOES, const GLfloat*) GL_ENTRY(void, glDrawTexxvOES, const GLfixed*) -GL_ENTRY(GLbitfield, glQueryMatrixxOES, GLfixed* mantissa, GLint* exponent) - +GL_ENTRY(GLbitfield, glQueryMatrixxOES, GLfixed*, GLint*) +GL_ENTRY(void, __glEGLImageTargetTexture2DOES, GLenum, GLeglImageOES) +GL_ENTRY(void, __glEGLImageTargetRenderbufferStorageOES, GLenum, GLeglImageOES) +GL_ENTRY(void, glBlendEquationSeparateOES, GLenum, GLenum) +GL_ENTRY(void, glBlendFuncSeparateOES, GLenum, GLenum, GLenum, GLenum) +GL_ENTRY(void, glBlendEquationOES, GLenum) +GL_ENTRY(GLboolean, glIsRenderbufferOES, GLuint) +GL_ENTRY(void, glBindRenderbufferOES, GLenum, GLuint) +GL_ENTRY(void, glDeleteRenderbuffersOES, GLsizei, const GLuint*) +GL_ENTRY(void, glGenRenderbuffersOES, GLsizei, GLuint*) +GL_ENTRY(void, glRenderbufferStorageOES, GLenum, GLenum, GLsizei, GLsizei) +GL_ENTRY(void, glGetRenderbufferParameterivOES, GLenum, GLenum, GLint*) +GL_ENTRY(GLboolean, glIsFramebufferOES, GLuint) +GL_ENTRY(void, glBindFramebufferOES, GLenum, GLuint) +GL_ENTRY(void, glDeleteFramebuffersOES, GLsizei, const GLuint*) +GL_ENTRY(void, glGenFramebuffersOES, GLsizei, GLuint*) +GL_ENTRY(GLenum, glCheckFramebufferStatusOES, GLenum) +GL_ENTRY(void, glFramebufferRenderbufferOES, GLenum, GLenum, GLenum, GLuint) +GL_ENTRY(void, glFramebufferTexture2DOES, GLenum, GLenum, GLenum, GLuint, GLint) +GL_ENTRY(void, glGetFramebufferAttachmentParameterivOES, GLenum, GLenum, GLenum, GLint*) +GL_ENTRY(void, glGenerateMipmapOES, GLenum) +GL_ENTRY(void*, glMapBufferOES, GLenum, GLenum) +GL_ENTRY(GLboolean, glUnmapBufferOES, GLenum) +GL_ENTRY(void, glGetBufferPointervOES, GLenum, GLenum, void**) +GL_ENTRY(void, glCurrentPaletteMatrixOES, GLuint) +GL_ENTRY(void, glLoadPaletteFromModelViewMatrixOES, void) +GL_ENTRY(void, glMatrixIndexPointerOES, GLint, GLenum, GLsizei, const GLvoid *) +GL_ENTRY(void, glWeightPointerOES, GLint, GLenum, GLsizei, const GLvoid *) +GL_ENTRY(void, glTexGenfOES, GLenum, GLenum, GLfloat) +GL_ENTRY(void, glTexGenfvOES, GLenum, GLenum, const GLfloat *) +GL_ENTRY(void, glTexGeniOES, GLenum, GLenum, GLint) +GL_ENTRY(void, glTexGenivOES, GLenum, GLenum, const GLint *) +GL_ENTRY(void, glTexGenxOES, GLenum, GLenum, GLfixed) +GL_ENTRY(void, glTexGenxvOES, GLenum, GLenum, const GLfixed *) +GL_ENTRY(void, glGetTexGenfvOES, GLenum, GLenum, GLfloat *) +GL_ENTRY(void, glGetTexGenivOES, GLenum, GLenum, GLint *) +GL_ENTRY(void, glGetTexGenxvOES, GLenum, GLenum, GLfixed *) diff --git a/opengl/libs/hooks.h b/opengl/libs/hooks.h index 63fb017675bf1..392724fe5e909 100644 --- a/opengl/libs/hooks.h +++ b/opengl/libs/hooks.h @@ -22,9 +22,10 @@ #include #include +#include #include +#include -#define GL_LOGGER 0 #if !defined(__arm__) #define USE_SLOW_BINDING 1 #else @@ -35,7 +36,7 @@ #define MAX_NUMBER_OF_GL_EXTENSIONS 32 -#if defined(HAVE_ANDROID_OS) && !USE_SLOW_BINDING && !GL_LOGGER && __OPTIMIZE__ +#if defined(HAVE_ANDROID_OS) && !USE_SLOW_BINDING && __OPTIMIZE__ #define USE_FAST_TLS_KEY 1 #else #define USE_FAST_TLS_KEY 0 @@ -55,7 +56,10 @@ const unsigned int NUM_DISPLAYS = 1; enum { IMPL_HARDWARE = 0, IMPL_SOFTWARE, - IMPL_CONTEXT_LOST, + + IMPL_NUM_DRIVERS_IMPLEMENTATIONS, + + IMPL_CONTEXT_LOST = IMPL_NUM_DRIVERS_IMPLEMENTATIONS, IMPL_NO_CONTEXT, IMPL_NUM_IMPLEMENTATIONS diff --git a/opengl/libs/tools/glapigen b/opengl/libs/tools/glapigen new file mode 100755 index 0000000000000..0333294b4e905 --- /dev/null +++ b/opengl/libs/tools/glapigen @@ -0,0 +1,51 @@ +#! /usr/bin/perl + +use strict; + +my $lineNum = 0; +while (my $line = <>) { + $lineNum += 1; + next if $line =~ /^\//; + next if $line =~ /^#/; + next if $line =~ /^\s*$/; + if ($line !~ /^GL_ENTRY\(([^,]+),\s*([^,]+),\s*([^)]+)\)/) { + printf STDERR "Cannot parse line number $lineNum:\n$line"; + next; + } + my $type = $1; + my $name = $2; + my $args = $3; + + printf("%s API_ENTRY(%s)(", $type, $name); + my @args = split ',', $args; + + my $len = scalar(@args); + for (my $num = 0; $num < $len; $num++) { + print ", " if $num > 0; + my $arg = $args[$num]; + if ($arg =~ /([^]]+)(\[[^]]\])/) { + my $argtype = $1; + my $array = $2; + printf("%s arg%d%s", $argtype, $num, $array); + } else { + if ($arg eq "void") { + printf("void"); + } else { + printf("%s arg%d", $arg, $num); + } + } + } + printf(") {\n"); + if ($type eq "void") { + printf(" CALL_GL_API(%s", $name); + } else { + printf(" CALL_GL_API_RETURN(%s", $name); + } + for (my $num = 0; $num < $len; $num++) { + if ($args[$num] ne "void") { + print ", "; + printf("arg%d", $num); + } + } + printf(");\n}\n\n"); +} diff --git a/opengl/tests/copybits/Android.mk b/opengl/tests/copybits/Android.mk new file mode 100644 index 0000000000000..d5ded42b5fb18 --- /dev/null +++ b/opengl/tests/copybits/Android.mk @@ -0,0 +1,18 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + copybits.cpp + +LOCAL_SHARED_LIBRARIES := \ + libcutils \ + libEGL \ + libGLESv1_CM \ + libui + +LOCAL_MODULE:= test-opengl-copybits + +LOCAL_MODULE_TAGS := tests + +include $(BUILD_EXECUTABLE) + diff --git a/opengl/tests/copybits/copybits.cpp b/opengl/tests/copybits/copybits.cpp new file mode 100644 index 0000000000000..ff17cc941d100 --- /dev/null +++ b/opengl/tests/copybits/copybits.cpp @@ -0,0 +1,752 @@ +// Test software OpenGL hardware accelleration using copybits. + +#define LOG_TAG "copybits_test" + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include + +#include + +#include +#include + +#define EGL_EGLEXT_PROTOTYPES +#define GL_GLEXT_PROTOTYPES + +#include +#include + +#include +#include + +extern "C" EGLNativeWindowType android_createDisplaySurface(void); + +using namespace android; + +EGLDisplay eglDisplay; +EGLSurface eglSurface; +EGLContext eglContext; +GLuint texture; + +hw_module_t const* gralloc_module; +alloc_device_t *sAllocDev; + +#define FIXED_ONE 0x10000 + +int init_gl_surface(); +void free_gl_surface(); +void init_scene(); + +int create_physical_texture(); +int readTimer(); + +// =========================================================================== +// Buffer and implementation of android_native_buffer_t +// =========================================================================== + +class NativeBuffer; + +class Buffer : public android_native_buffer_t, + public LightRefBase +{ +public: + + // creates w * h buffer + Buffer(uint32_t w, uint32_t h, PixelFormat format, int usage); + + // return status + status_t initCheck() const; + + + uint32_t getWidth() const { return mWidth; } + uint32_t getHeight() const { return mHeight; } + uint32_t getStride() const { return mStride; } + uint32_t getUsage() const { return mUsage; } + PixelFormat getPixelFormat() const { return mFormat; } + buffer_handle_t getHandle() const { return mBufferHandle; } + + android_native_buffer_t* getNativeBuffer() const; + + void setPixel(int x, int y, int r, int g, int b, int a); + +private: + friend class LightRefBase; + Buffer(const Buffer& rhs); + ~Buffer(); + Buffer& operator = (const Buffer& rhs); + const Buffer& operator = (const Buffer& rhs) const; + + status_t initSize(uint32_t w, uint32_t h); + + static void incRef(android_native_base_t* buffer); + static void decRef(android_native_base_t* buffer); + static int getHandlePriv(android_native_buffer_t const * buffer, + buffer_handle_t* handle); + + buffer_handle_t mBufferHandle; + ssize_t mInitCheck; + + uint32_t mWidth; + uint32_t mHeight; + uint32_t mStride; + uint32_t mVStride; + PixelFormat mFormat; + void* mData; + uint32_t mUsage; +}; + +Buffer::Buffer(uint32_t w, uint32_t h, PixelFormat format, int usage) + : mBufferHandle(0), mInitCheck(NO_INIT), + mWidth(0), mHeight(0), mStride(0), mVStride(0), mFormat(format), mData(0), + mUsage(usage) +{ + common.magic = ANDROID_NATIVE_BUFFER_MAGIC; + common.version = sizeof(android_native_buffer_t); + common.incRef = incRef; + common.decRef = decRef; + android_native_buffer_t::getHandle = getHandlePriv; + if (w>0 && h>0) { + mInitCheck = initSize(w, h); + } +} + +Buffer::~Buffer() +{ + if (mBufferHandle) { + + gralloc_module_t* mod = (gralloc_module_t*)sAllocDev->common.module; + mod->unmap(mod, mBufferHandle); + + sAllocDev->free(sAllocDev, mBufferHandle); + } +} + +void Buffer::incRef(android_native_base_t* buffer) { + Buffer* self = static_cast( + reinterpret_cast(buffer)); + self->incStrong(self); +} + +void Buffer::decRef(android_native_base_t* buffer) { + Buffer* self = static_cast( + reinterpret_cast(buffer)); + self->decStrong(self); +} + +int Buffer::getHandlePriv(android_native_buffer_t const * buffer, + buffer_handle_t* handle) { + Buffer const * self = static_cast(buffer); + *handle = self->getHandle(); + return 0; +} + +status_t Buffer::initCheck() const { + return mInitCheck; +} + +android_native_buffer_t* Buffer::getNativeBuffer() const +{ + Buffer* that = const_cast(this); + that->android_native_buffer_t::width = mWidth; + that->android_native_buffer_t::height = mHeight; + that->android_native_buffer_t::stride = mStride; + that->android_native_buffer_t::format = mFormat; + that->android_native_buffer_t::usage = mUsage; + that->android_native_buffer_t::bits = mData; + return static_cast(that); +} + +status_t Buffer::initSize(uint32_t w, uint32_t h) +{ + status_t err = NO_ERROR; + + int32_t stride; + err = sAllocDev->alloc(sAllocDev, w, h, mFormat, mUsage, &mBufferHandle, &stride); + + if (err == NO_ERROR) { + void* addr = 0; + gralloc_module_t* mod = (gralloc_module_t*)sAllocDev->common.module; + err = mod->map(mod, mBufferHandle, &addr); + if (err == NO_ERROR) { + mData = addr; + mWidth = w; + mHeight = h; + mStride = stride; + mVStride = 0; + } + } + + return err; +} + +void Buffer::setPixel(int x, int y, int r, int g, int b, int a) { + if (x < 0 || (unsigned int) x >= mWidth + || y < 0 || (unsigned int) y >= mHeight) { + // clipped + return; + } + int index = mStride * y + x; + switch (mFormat) { + case HAL_PIXEL_FORMAT_RGB_565: { + unsigned short val = (unsigned short) ( + ((0x1f & (r >> 3)) << 11) + | ((0x3f & (g >> 2)) << 5) + | (0x1f & (b >> 3))); + ((unsigned short*) mData)[index]= val; + } + break; + case HAL_PIXEL_FORMAT_RGBA_8888: { // ABGR + unsigned int val = (unsigned int) + (((a & 0xff) << 24) + | ((b & 0xff) << 16) + | ((g & 0xff) << 8) + | (r & 0xff)); + ((unsigned int*) mData)[index] = val; + } + break; + default: + // Unsupported pixel format + break; + } +} + + +static void gluLookAt(float eyeX, float eyeY, float eyeZ, + float centerX, float centerY, float centerZ, float upX, float upY, + float upZ) +{ + // See the OpenGL GLUT documentation for gluLookAt for a description + // of the algorithm. We implement it in a straightforward way: + + float fx = centerX - eyeX; + float fy = centerY - eyeY; + float fz = centerZ - eyeZ; + + // Normalize f + float rlf = 1.0f / sqrtf(fx*fx + fy*fy + fz*fz); + fx *= rlf; + fy *= rlf; + fz *= rlf; + + // Normalize up + float rlup = 1.0f / sqrtf(upX*upX + upY*upY + upZ*upZ); + upX *= rlup; + upY *= rlup; + upZ *= rlup; + + // compute s = f x up (x means "cross product") + + float sx = fy * upZ - fz * upY; + float sy = fz * upX - fx * upZ; + float sz = fx * upY - fy * upX; + + // compute u = s x f + float ux = sy * fz - sz * fy; + float uy = sz * fx - sx * fz; + float uz = sx * fy - sy * fx; + + float m[16] ; + m[0] = sx; + m[1] = ux; + m[2] = -fx; + m[3] = 0.0f; + + m[4] = sy; + m[5] = uy; + m[6] = -fy; + m[7] = 0.0f; + + m[8] = sz; + m[9] = uz; + m[10] = -fz; + m[11] = 0.0f; + + m[12] = 0.0f; + m[13] = 0.0f; + m[14] = 0.0f; + m[15] = 1.0f; + + glMultMatrixf(m); + glTranslatef(-eyeX, -eyeY, -eyeZ); +} + +int init_gralloc() { + int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &gralloc_module); + LOGE_IF(err, "FATAL: can't find the %s module", GRALLOC_HARDWARE_MODULE_ID); + + if (err == 0) { + gralloc_open(gralloc_module, &sAllocDev); + } + return err; +} + +int init_gl_surface(void) +{ + EGLint numConfigs = 1; + EGLConfig myConfig = {0}; + EGLint attrib[] = + { + EGL_DEPTH_SIZE, 16, + EGL_NONE + }; + + printf("init_gl_surface\n"); + if ( (eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY)) == EGL_NO_DISPLAY ) + { + printf("eglGetDisplay failed\n"); + return 0; + } + + if ( eglInitialize(eglDisplay, NULL, NULL) != EGL_TRUE ) + { + printf("eglInitialize failed\n"); + return 0; + } + + if ( eglChooseConfig(eglDisplay, attrib, &myConfig, 1, &numConfigs) != EGL_TRUE ) + { + printf("eglChooseConfig failed\n"); + return 0; + } + + if ( (eglSurface = eglCreateWindowSurface(eglDisplay, myConfig, + android_createDisplaySurface(), 0)) == EGL_NO_SURFACE ) + { + printf("eglCreateWindowSurface failed\n"); + return 0; + } + + if ( (eglContext = eglCreateContext(eglDisplay, myConfig, 0, 0)) == EGL_NO_CONTEXT ) + { + printf("eglCreateContext failed\n"); + return 0; + } + + if ( eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext) != EGL_TRUE ) + { + printf("eglMakeCurrent failed\n"); + return 0; + } + + return 1; +} + +void free_gl_surface(void) +{ + if (eglDisplay != EGL_NO_DISPLAY) + { + eglMakeCurrent( EGL_NO_DISPLAY, EGL_NO_SURFACE, + EGL_NO_SURFACE, EGL_NO_CONTEXT ); + eglDestroyContext( eglDisplay, eglContext ); + eglDestroySurface( eglDisplay, eglSurface ); + eglTerminate( eglDisplay ); + eglDisplay = EGL_NO_DISPLAY; + } +} + +void init_scene(void) +{ + glDisable(GL_DITHER); + glEnable(GL_CULL_FACE); + float ratio = 320.0f / 480.0f; + glViewport(0, 0, 320, 480); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustumf(-ratio, ratio, -1, 1, 1, 10); + + glMatrixMode(GL_MODELVIEW); + + glLoadIdentity(); + gluLookAt( + 0, 0, 3, // eye + 0, 0, 0, // center + 0, 1, 0); // up + + glEnable(GL_TEXTURE_2D); +} + +// #define USE_ALPHA_COLOR + +#define USE_GL_REPLACE +// #define USE_GL_MODULATE + +// #define USE_BLEND + +#define USE_565 +// #define USE_8888 + +// #define USE_NEAREST +#define USE_LINEAR + +#define USE_SCALE + +void setSmoothGradient(Buffer* bufferObject) { + int pixels = bufferObject->getHeight() * bufferObject->getWidth(); + int step = 0; + for (unsigned int y = 0; y < bufferObject->getHeight(); y++) { + for(unsigned int x = 0; x < bufferObject->getWidth() ; x++) { + int grey = step * 255 / pixels; + bufferObject->setPixel(x, y, grey, grey, grey, 255); + ++step; + } + } +} + +void setSmoothAlphaGradient(Buffer* bufferObject) { + int pixels = bufferObject->getHeight() * bufferObject->getWidth(); + int step = 0; + for (unsigned int y = 0; y < bufferObject->getHeight(); y++) { + for(unsigned int x = 0; x < bufferObject->getWidth() ; x++) { + int grey = step * 255 / pixels; + bufferObject->setPixel(x, y, 255, 255, 255, grey); + ++step; + } + } +} + +void setOrientedCheckerboard(Buffer* bufferObject) { + bufferObject->setPixel(0, 0, 0, 0, 0, 255); + for(unsigned int x = 1; x < bufferObject->getWidth() ; x++) { + bufferObject->setPixel(x, 0, 0, 255, 0, 255); + } + for (unsigned int y = 1; y < bufferObject->getHeight(); y++) { + for(unsigned int x = 0; x < bufferObject->getWidth() ; x++) { + if ((x ^ y ) & 1) { + bufferObject->setPixel(x, y, 255, 255, 255, 255); + } else { + bufferObject->setPixel(x, y, 255, 0, 0, 255); + } + } + } +} + +int create_physical_texture(unsigned int w, unsigned int h) +{ + +#ifdef USE_565 + PixelFormat format = HAL_PIXEL_FORMAT_RGB_565; +#else + PixelFormat format = HAL_PIXEL_FORMAT_RGBA_8888; +#endif + int usage = GRALLOC_USAGE_SW_READ_OFTEN | + GRALLOC_USAGE_SW_WRITE_OFTEN | + GRALLOC_USAGE_HW_TEXTURE | + GRALLOC_USAGE_HW_2D; /* This is the key to allocating the texture in pmem. */ + int32_t stride; + buffer_handle_t handle; + + // Allocate the hardware buffer + Buffer* bufferObject = new Buffer(w, h, format, usage); + + android_native_buffer_t* buffer = bufferObject->getNativeBuffer(); + + buffer->common.incRef(&buffer->common); + + // create the new EGLImageKHR + EGLint attrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_NONE }; + EGLDisplay dpy = eglGetCurrentDisplay(); + EGLImageKHR image = eglCreateImageKHR(dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, + (EGLClientBuffer)buffer, attrs); + if (image == EGL_NO_IMAGE_KHR) { + printf("Could not create an image %d\n", eglGetError()); + return -1; + } + + if (buffer->bits == NULL) { + printf("No bits allocated for image.\n"); + return -2; + } + + setOrientedCheckerboard(bufferObject); + // setSmoothGradient(bufferObject); + // setSmoothAlphaGradient(bufferObject); + + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image); +#ifdef USE_LINEAR + glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +#elif defined(USE_NEAREST) + glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); +#endif + +#ifdef USE_GL_REPLACE + glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); +#elif defined(USE_GL_MODULATE) + glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); +#endif + +#ifdef USE_ALPHA_COLOR + glColor4f(1.0f, 1.0f, 1.0f, 0.4f); +#else + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); +#endif + +#ifdef USE_BLEND + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +#endif + return 0; +} + +static const int SCALE_COUNT = 12; + +int scale(int base, int factor) { + static const float kTable[SCALE_COUNT] = { + 0.1f, 0.25f, 0.5f, 0.75f, 1.0f, + 1.5f, 2.0f, 2.5f, 3.0f, 3.5f, 4.0f, 5.0f + }; + return base * kTable[factor]; +} + +class Timer { + struct timeval first; + double elapsedSeconds; + +public: + Timer() {} + void start() { + gettimeofday(&first, NULL); + } + + void stop() { + struct timeval second, + elapsed; + gettimeofday(&second, NULL); + + if (first.tv_usec > second.tv_usec) { + second.tv_usec += 1000000; + second.tv_sec--; + } + + elapsedSeconds = (second.tv_sec - first.tv_sec) + + (second.tv_usec - first.tv_usec) / 1000000.0; + } + + double getElapsedSeconds() { + return elapsedSeconds; + } + + double getElapsedMs() { + return elapsedSeconds* 1000.0f; + } +}; + +int testTime() +{ + static const int WIDTH = 320; + static const int HEIGHT = 480; + static const int SCALE = 8; + + if (create_physical_texture(WIDTH, HEIGHT) != 0) { + return -1; + } + // Need to do a dummy eglSwapBuffers first. Don't know why. + glClearColor(0.4, 1.0, 0.4, 0.4); + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + eglSwapBuffers(eglDisplay, eglSurface); + + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + +#if defined(USE_SCALE) + static const int scaleOffset = 0; +#else + static const int scaleOffset = 1; +#endif + printf("ms\n"); + for(int j = 0; j < SCALE; j++) { + int w = WIDTH >> (j + scaleOffset); + int h = HEIGHT >> j; + int cropRect[4] = {0,h,w,-h}; // Left bottom width height. Width and Height can be neg to flip. + glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, cropRect); + Timer timer; + timer.start(); + + int copyCount = 1000; + for (int i = 0; i < copyCount; i++) { + glDrawTexiOES(0, 0, 0, w, h); + } + + timer.stop(); + printf("%g\n", timer.getElapsedMs() / copyCount); + } + + eglSwapBuffers(eglDisplay, eglSurface); + return 0; +} + +int testStretch() +{ + static const int WIDTH = 8; + static const int HEIGHT = 8; + + if (create_physical_texture(WIDTH, HEIGHT) != 0) { + return -1; + } + // Need to do a dummy eglSwapBuffers first. Don't know why. + glClearColor(0.4, 1.0, 0.4, 0.4); + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + eglSwapBuffers(eglDisplay, eglSurface); + + int cropRect[4] = {0,HEIGHT,WIDTH,-HEIGHT}; // Left bottom width height. Width and Height can be neg to flip. + glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, cropRect); + + for(int frame = 0; frame < 2; frame++) { + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + int baseX = 10; + for (int x = 0; x < SCALE_COUNT; x++) { + int baseY = 10; + int width = scale(WIDTH, x); + for (int y = 0; y < SCALE_COUNT; y++) { + int height = scale(HEIGHT, y); + glDrawTexxOES(baseX << 16, baseY << 16, 0, width << 16, height << 16); + baseY += height + 10; + } + baseX += width + 10; + } + + eglSwapBuffers(eglDisplay, eglSurface); + } + return 0; +} + +int testRot90() +{ + static const int WIDTH = 8; + static const int HEIGHT = 8; + + if (create_physical_texture(WIDTH, HEIGHT) != 0) { + return -1; + } + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrthof(0, 320, 480, 0, 0, 1); + + glMatrixMode(GL_MODELVIEW); + + glLoadIdentity(); + + // Need to do a dummy eglSwapBuffers first. Don't know why. + glClearColor(0.4, 0.4, 0.4, 0.4); + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + eglSwapBuffers(eglDisplay, eglSurface); + + glEnable(GL_TEXTURE_2D); + glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glColor4x(0x10000, 0x10000, 0x10000, 0x10000); + glDisable(GL_BLEND); + glShadeModel(GL_FLAT); + glDisable(GL_DITHER); + glDisable(GL_CULL_FACE); + + for(int frame = 0; frame < 2; frame++) { + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + int baseX = 10; + for (int x = 0; x < SCALE_COUNT; x++) { + int baseY = 10; + int width = scale(WIDTH, x); + for (int y = 0; y < SCALE_COUNT; y++) { + int height = scale(HEIGHT, y); + + // Code copied from SurfaceFlinger LayerBase.cpp + + const GLfixed texCoords[4][2] = { + { 0, 0 }, + { 0, 0x10000 }, + { 0x10000, 0x10000 }, + { 0x10000, 0 } + }; + + GLfixed fx = baseX << 16; + GLfixed fy = baseY << 16; + GLfixed fw = width << 16; + GLfixed fh = height << 16; + + /* + * Vertex pattern: + * (2)--(3) + * |\ | + * | \ | + * | \ | + * | \| + * (1)--(0) + * + */ + + const GLfixed vertices[4][2] = { + {fx + fw, fy}, + {fx, fy}, + {fx, fy + fh}, + {fx + fw, fy + fh} + }; + + static const bool rotate90 = true; + + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glVertexPointer(2, GL_FIXED, 0, vertices); + glTexCoordPointer(2, GL_FIXED, 0, texCoords); + + LOGW("testRot90 %d, %d %d, %d", baseX, baseY, width, height); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + baseY += height + 10; + } + baseX += width + 10; + } + + eglSwapBuffers(eglDisplay, eglSurface); + } + return 0; +} + +int main(int argc, char **argv) +{ + + int q; + int start, end; + + if (init_gralloc()) { + printf("gralloc initialization failed - exiting\n"); + return 0; + } + + printf("Initializing EGL...\n"); + + if(!init_gl_surface()) + { + printf("GL initialisation failed - exiting\n"); + return 0; + } + + init_scene(); + + printf("Start test...\n"); + // testTime(); + // testStretch(); + testRot90(); + free_gl_surface(); + + return 0; +} From 7e25da07af7f4f8a876ac97be6e4745877aecb08 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Fri, 10 Apr 2009 20:27:25 -0700 Subject: [PATCH 02/83] fix KeyedVector::replaceValueAt, which wouldn't even compile if used. --- include/utils/KeyedVector.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/utils/KeyedVector.h b/include/utils/KeyedVector.h index f4513ee20fb5a..6bcdea4ff1826 100644 --- a/include/utils/KeyedVector.h +++ b/include/utils/KeyedVector.h @@ -164,7 +164,7 @@ ssize_t KeyedVector::replaceValueFor(const KEY& key, const VALUE& val template inline ssize_t KeyedVector::replaceValueAt(size_t index, const VALUE& item) { if (index Date: Fri, 10 Apr 2009 20:34:46 -0700 Subject: [PATCH 03/83] more debugging tools around BufferMapper --- include/ui/BufferMapper.h | 14 +++++ libs/surfaceflinger/BufferAllocator.cpp | 16 ++--- libs/surfaceflinger/LayerBitmap.h | 2 +- libs/ui/BufferMapper.cpp | 78 +++++++++++++++++++++++++ opengl/libagl/egl.cpp | 13 +++-- 5 files changed, 110 insertions(+), 13 deletions(-) diff --git a/include/ui/BufferMapper.h b/include/ui/BufferMapper.h index 8a33b2eab9a57..9e5c5d7fd7fa3 100644 --- a/include/ui/BufferMapper.h +++ b/include/ui/BufferMapper.h @@ -19,8 +19,11 @@ #include #include + +#include #include #include +#include #include @@ -42,11 +45,22 @@ public: status_t lock(buffer_handle_t handle, int usage, const Rect& bounds); status_t unlock(buffer_handle_t handle); + // dumps information about the mapping of this handle + void dump(buffer_handle_t handle); + private: friend class Singleton; BufferMapper(); mutable Mutex mLock; gralloc_module_t const *mAllocMod; + + struct map_info_t { + int count; + KeyedVector callstacks; + }; + KeyedVector mMapInfo; + void logMapLocked(buffer_handle_t handle); + void logUnmapLocked(buffer_handle_t handle); }; // --------------------------------------------------------------------------- diff --git a/libs/surfaceflinger/BufferAllocator.cpp b/libs/surfaceflinger/BufferAllocator.cpp index ac32985890ac8..96a2c32f38326 100644 --- a/libs/surfaceflinger/BufferAllocator.cpp +++ b/libs/surfaceflinger/BufferAllocator.cpp @@ -104,11 +104,13 @@ status_t BufferAllocator::free(buffer_handle_t handle) { Mutex::Autolock _l(mLock); -#if ANDROID_GRALLOC_DEBUG - if (handle->data[2]) { - CallStack s; - s.update(); - s.dump(""); +#if ANDROID_GRALLOC_DEBUG + void* base = (void*)(handle->data[2]); + if (base) { + CallStack s; + s.update(); + s.dump(""); + BufferMapper::get().dump(handle); } #endif @@ -143,9 +145,7 @@ status_t BufferAllocator::unmap(buffer_handle_t handle) { Mutex::Autolock _l(mLock); gralloc_module_t* mod = (gralloc_module_t*)mAllocDev->common.module; - status_t err = mod->unmap(mod, handle); - LOGW_IF(err, "unmap(...) failed %d (%s)", err, strerror(-err)); - + status_t err = BufferMapper::get().unmap(handle); if (err == NO_ERROR) { Mutex::Autolock _l(sLock); KeyedVector& list(sAllocList); diff --git a/libs/surfaceflinger/LayerBitmap.h b/libs/surfaceflinger/LayerBitmap.h index d1f78021640e8..e6737550f2812 100644 --- a/libs/surfaceflinger/LayerBitmap.h +++ b/libs/surfaceflinger/LayerBitmap.h @@ -81,7 +81,7 @@ public: private: friend class LightRefBase; Buffer(const Buffer& rhs); - ~Buffer(); + virtual ~Buffer(); Buffer& operator = (const Buffer& rhs); const Buffer& operator = (const Buffer& rhs) const; diff --git a/libs/ui/BufferMapper.cpp b/libs/ui/BufferMapper.cpp index a97188e73d851..c7e439c3c9684 100644 --- a/libs/ui/BufferMapper.cpp +++ b/libs/ui/BufferMapper.cpp @@ -34,6 +34,13 @@ #include +// --------------------------------------------------------------------------- +// enable mapping debugging +#define DEBUG_MAPPINGS 1 +// never remove mappings from the list +#define DEBUG_MAPPINGS_KEEP_ALL 1 +// --------------------------------------------------------------------------- + namespace android { // --------------------------------------------------------------------------- @@ -53,6 +60,10 @@ status_t BufferMapper::map(buffer_handle_t handle, void** addr) Mutex::Autolock _l(mLock); status_t err = mAllocMod->map(mAllocMod, handle, addr); LOGW_IF(err, "map(...) failed %d (%s)", err, strerror(-err)); +#if DEBUG_MAPPINGS + if (err == NO_ERROR) + logMapLocked(handle); +#endif return err; } @@ -61,6 +72,10 @@ status_t BufferMapper::unmap(buffer_handle_t handle) Mutex::Autolock _l(mLock); status_t err = mAllocMod->unmap(mAllocMod, handle); LOGW_IF(err, "unmap(...) failed %d (%s)", err, strerror(-err)); +#if DEBUG_MAPPINGS + if (err == NO_ERROR) + logUnmapLocked(handle); +#endif return err; } @@ -79,5 +94,68 @@ status_t BufferMapper::unlock(buffer_handle_t handle) return err; } +void BufferMapper::logMapLocked(buffer_handle_t handle) +{ + CallStack stack; + stack.update(2); + + map_info_t info; + ssize_t index = mMapInfo.indexOfKey(handle); + if (index >= 0) { + info = mMapInfo.valueAt(index); + } + + ssize_t stackIndex = info.callstacks.indexOfKey(stack); + if (stackIndex >= 0) { + info.callstacks.editValueAt(stackIndex) += 1; + } else { + info.callstacks.add(stack, 1); + } + + if (index < 0) { + info.count = 1; + mMapInfo.add(handle, info); + } else { + info.count++; + mMapInfo.replaceValueAt(index, info); + } +} + +void BufferMapper::logUnmapLocked(buffer_handle_t handle) +{ + ssize_t index = mMapInfo.indexOfKey(handle); + if (index < 0) { + LOGE("unmapping %p which doesn't exist!", handle); + return; + } + + map_info_t& info = mMapInfo.editValueAt(index); + info.count--; + if (info.count == 0) { +#if DEBUG_MAPPINGS_KEEP_ALL + info.callstacks.clear(); +#else + mMapInfo.removeItemsAt(index, 1); +#endif + } +} + +void BufferMapper::dump(buffer_handle_t handle) +{ + Mutex::Autolock _l(mLock); + ssize_t index = mMapInfo.indexOfKey(handle); + if (index < 0) { + LOGD("handle %p is not mapped through BufferMapper", handle); + return; + } + + const map_info_t& info = mMapInfo.valueAt(index); + LOGD("dumping buffer_handle_t %p mappings (count=%d)", handle, info.count); + for (size_t i=0 ; i(pModule); if (native_buffer->getHandle(native_buffer, &bufferHandle) < 0) return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); - if (module->map(module, bufferHandle, &native_buffer->bits) < 0) + int err = module->map(module, bufferHandle, &native_buffer->bits); + if (err < 0) { + LOGW_IF(err, "map(...) failed %d (%s)", err, strerror(-err)); return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); - + } + native_buffer->common.incRef(&native_buffer->common); return (EGLImageKHR)native_buffer; } @@ -1725,8 +1728,10 @@ EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img) buffer_handle_t bufferHandle; gralloc_module_t const* module = reinterpret_cast(pModule); - if (native_buffer->getHandle(native_buffer, &bufferHandle) == 0) { - module->unmap(module, bufferHandle); + int err = native_buffer->getHandle(native_buffer, &bufferHandle); + if (err == 0) { + int err = module->unmap(module, bufferHandle); + LOGW_IF(err, "unmap(...) failed %d (%s)", err, strerror(-err)); } } From e909ae55e3dc4e14e926df7548bb7407530d09ad Mon Sep 17 00:00:00 2001 From: Jack Palevich Date: Mon, 13 Apr 2009 22:03:39 -0700 Subject: [PATCH 04/83] Add clarifying comment. (Primarily as a test of the master_gl branch.) --- opengl/tests/copybits/copybits.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opengl/tests/copybits/copybits.cpp b/opengl/tests/copybits/copybits.cpp index ff17cc941d100..404932ad24705 100644 --- a/opengl/tests/copybits/copybits.cpp +++ b/opengl/tests/copybits/copybits.cpp @@ -43,7 +43,7 @@ GLuint texture; hw_module_t const* gralloc_module; alloc_device_t *sAllocDev; -#define FIXED_ONE 0x10000 +#define FIXED_ONE 0x10000 /* 1.0 in 16.16 fixed point. */ int init_gl_surface(); void free_gl_surface(); From a6b40ba521d5c2fc23da74015531bd4ed8657921 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Wed, 15 Apr 2009 18:34:24 -0700 Subject: [PATCH 05/83] fix a rookie mistake causing Singleton<> to be a "multiton". Also improve the BufferMapper's debugging, but turn it off. Squashed commit of the following: commit 04e9cae7f806bd65f2cfe35c011b47a36773bbe5 Author: Mathias Agopian Date: Wed Apr 15 18:30:30 2009 -0700 fix and improve BufferMapper's tracking of mapped buffers. commit 1a8deaed15811092b2349cc3c40cafb5f722046c Author: Mathias Agopian Date: Wed Apr 15 00:52:02 2009 -0700 fix some bugs with the Singleton<> class. untested. commit ed01cc06ad70cf640ce1258f01189cb1a96fd3a8 Author: Mathias Agopian Date: Tue Apr 14 19:29:25 2009 -0700 some work to debug the Singleton<> template. --- include/ui/BufferMapper.h | 14 ++--- include/utils/Singleton.h | 3 -- libs/surfaceflinger/BufferAllocator.cpp | 19 +++++-- libs/ui/BufferMapper.cpp | 72 ++++++++++++------------- libs/ui/Surface.cpp | 11 ++-- 5 files changed, 64 insertions(+), 55 deletions(-) diff --git a/include/ui/BufferMapper.h b/include/ui/BufferMapper.h index 9e5c5d7fd7fa3..ff90033002963 100644 --- a/include/ui/BufferMapper.h +++ b/include/ui/BufferMapper.h @@ -40,8 +40,8 @@ class BufferMapper : public Singleton { public: static inline BufferMapper& get() { return getInstance(); } - status_t map(buffer_handle_t handle, void** addr); - status_t unmap(buffer_handle_t handle); + status_t map(buffer_handle_t handle, void** addr, const void* id); + status_t unmap(buffer_handle_t handle, const void* id); status_t lock(buffer_handle_t handle, int usage, const Rect& bounds); status_t unlock(buffer_handle_t handle); @@ -54,13 +54,13 @@ private: mutable Mutex mLock; gralloc_module_t const *mAllocMod; + void logMapLocked(buffer_handle_t handle, const void* id); + void logUnmapLocked(buffer_handle_t handle, const void* id); struct map_info_t { - int count; - KeyedVector callstacks; + const void* id; + CallStack stack; }; - KeyedVector mMapInfo; - void logMapLocked(buffer_handle_t handle); - void logUnmapLocked(buffer_handle_t handle); + KeyedVector > mMapInfo; }; // --------------------------------------------------------------------------- diff --git a/include/utils/Singleton.h b/include/utils/Singleton.h index 776f93bb7535c..ee07df11f4795 100644 --- a/include/utils/Singleton.h +++ b/include/utils/Singleton.h @@ -49,9 +49,6 @@ private: static TYPE* sInstance; }; -template Mutex Singleton::sLock; -template TYPE* Singleton::sInstance(0); - // --------------------------------------------------------------------------- }; // namespace android diff --git a/libs/surfaceflinger/BufferAllocator.cpp b/libs/surfaceflinger/BufferAllocator.cpp index 96a2c32f38326..28fe81002f9e5 100644 --- a/libs/surfaceflinger/BufferAllocator.cpp +++ b/libs/surfaceflinger/BufferAllocator.cpp @@ -19,6 +19,8 @@ #include #include #include + +#include #include #include @@ -32,6 +34,9 @@ namespace android { // --------------------------------------------------------------------------- +template Mutex Singleton::sLock; +template<> BufferAllocator* Singleton::sInstance(0); + Mutex BufferAllocator::sLock; KeyedVector BufferAllocator::sAllocList; @@ -106,7 +111,14 @@ status_t BufferAllocator::free(buffer_handle_t handle) #if ANDROID_GRALLOC_DEBUG void* base = (void*)(handle->data[2]); +#endif + + status_t err = mAllocDev->free(mAllocDev, handle); + LOGW_IF(err, "free(...) failed %d (%s)", err, strerror(-err)); + +#if ANDROID_GRALLOC_DEBUG if (base) { + LOGD("freeing mapped handle %p from:", handle); CallStack s; s.update(); s.dump(""); @@ -114,9 +126,6 @@ status_t BufferAllocator::free(buffer_handle_t handle) } #endif - status_t err = mAllocDev->free(mAllocDev, handle); - LOGW_IF(err, "free(...) failed %d (%s)", err, strerror(-err)); - if (err == NO_ERROR) { Mutex::Autolock _l(sLock); KeyedVector& list(sAllocList); @@ -129,7 +138,7 @@ status_t BufferAllocator::free(buffer_handle_t handle) status_t BufferAllocator::map(buffer_handle_t handle, void** addr) { Mutex::Autolock _l(mLock); - status_t err = BufferMapper::get().map(handle, addr); + status_t err = BufferMapper::get().map(handle, addr, this); if (err == NO_ERROR) { Mutex::Autolock _l(sLock); KeyedVector& list(sAllocList); @@ -145,7 +154,7 @@ status_t BufferAllocator::unmap(buffer_handle_t handle) { Mutex::Autolock _l(mLock); gralloc_module_t* mod = (gralloc_module_t*)mAllocDev->common.module; - status_t err = BufferMapper::get().unmap(handle); + status_t err = BufferMapper::get().unmap(handle, this); if (err == NO_ERROR) { Mutex::Autolock _l(sLock); KeyedVector& list(sAllocList); diff --git a/libs/ui/BufferMapper.cpp b/libs/ui/BufferMapper.cpp index c7e439c3c9684..e6ca239831fa3 100644 --- a/libs/ui/BufferMapper.cpp +++ b/libs/ui/BufferMapper.cpp @@ -36,14 +36,17 @@ // --------------------------------------------------------------------------- // enable mapping debugging -#define DEBUG_MAPPINGS 1 +#define DEBUG_MAPPINGS 0 // never remove mappings from the list -#define DEBUG_MAPPINGS_KEEP_ALL 1 +#define DEBUG_MAPPINGS_KEEP_ALL 0 // --------------------------------------------------------------------------- namespace android { // --------------------------------------------------------------------------- +template Mutex Singleton::sLock; +template<> BufferMapper* Singleton::sInstance(0); + BufferMapper::BufferMapper() : mAllocMod(0) { @@ -55,26 +58,26 @@ BufferMapper::BufferMapper() } } -status_t BufferMapper::map(buffer_handle_t handle, void** addr) +status_t BufferMapper::map(buffer_handle_t handle, void** addr, const void* id) { Mutex::Autolock _l(mLock); status_t err = mAllocMod->map(mAllocMod, handle, addr); LOGW_IF(err, "map(...) failed %d (%s)", err, strerror(-err)); #if DEBUG_MAPPINGS if (err == NO_ERROR) - logMapLocked(handle); + logMapLocked(handle, id); #endif return err; } -status_t BufferMapper::unmap(buffer_handle_t handle) +status_t BufferMapper::unmap(buffer_handle_t handle, const void* id) { Mutex::Autolock _l(mLock); status_t err = mAllocMod->unmap(mAllocMod, handle); LOGW_IF(err, "unmap(...) failed %d (%s)", err, strerror(-err)); #if DEBUG_MAPPINGS if (err == NO_ERROR) - logUnmapLocked(handle); + logUnmapLocked(handle, id); #endif return err; } @@ -94,49 +97,46 @@ status_t BufferMapper::unlock(buffer_handle_t handle) return err; } -void BufferMapper::logMapLocked(buffer_handle_t handle) +void BufferMapper::logMapLocked(buffer_handle_t handle, const void* id) { CallStack stack; stack.update(2); map_info_t info; + info.id = id; + info.stack = stack; + ssize_t index = mMapInfo.indexOfKey(handle); if (index >= 0) { - info = mMapInfo.valueAt(index); - } - - ssize_t stackIndex = info.callstacks.indexOfKey(stack); - if (stackIndex >= 0) { - info.callstacks.editValueAt(stackIndex) += 1; + Vector& infos = mMapInfo.editValueAt(index); + infos.add(info); } else { - info.callstacks.add(stack, 1); - } - - if (index < 0) { - info.count = 1; - mMapInfo.add(handle, info); - } else { - info.count++; - mMapInfo.replaceValueAt(index, info); + Vector infos; + infos.add(info); + mMapInfo.add(handle, infos); } } -void BufferMapper::logUnmapLocked(buffer_handle_t handle) +void BufferMapper::logUnmapLocked(buffer_handle_t handle, const void* id) { ssize_t index = mMapInfo.indexOfKey(handle); if (index < 0) { - LOGE("unmapping %p which doesn't exist!", handle); + LOGE("unmapping %p which doesn't exist in our map!", handle); return; } - map_info_t& info = mMapInfo.editValueAt(index); - info.count--; - if (info.count == 0) { -#if DEBUG_MAPPINGS_KEEP_ALL - info.callstacks.clear(); -#else + Vector& infos = mMapInfo.editValueAt(index); + ssize_t count = infos.size(); + for (int i=0 ; i& infos = mMapInfo.valueAt(index); + ssize_t count = infos.size(); + for (int i=0 ; i Mutex Singleton::sLock; +template<> SurfaceBuffer* Singleton::sInstance(0); + SurfaceBuffer::SurfaceBuffer() : BASE(), handle(0), mOwner(false) { @@ -199,10 +202,10 @@ Surface::~Surface() if (mOwner && mToken>=0 && mClient!=0) { mClient->destroySurface(mToken); if (mBuffers[0] != 0) { - BufferMapper::get().unmap(mBuffers[0]->getHandle()); + BufferMapper::get().unmap(mBuffers[0]->getHandle(), this); } if (mBuffers[1] != 0) { - BufferMapper::get().unmap(mBuffers[1]->getHandle()); + BufferMapper::get().unmap(mBuffers[1]->getHandle(), this); } } mClient.clear(); @@ -572,10 +575,10 @@ status_t Surface::getBufferLocked(int index) if (buffer != 0) { sp& currentBuffer(mBuffers[index]); if (currentBuffer != 0) { - BufferMapper::get().unmap(currentBuffer->getHandle()); + BufferMapper::get().unmap(currentBuffer->getHandle(), this); currentBuffer.clear(); } - err = BufferMapper::get().map(buffer->getHandle(), &buffer->bits); + err = BufferMapper::get().map(buffer->getHandle(), &buffer->bits, this); LOGW_IF(err, "map(...) failed %d (%s)", err, strerror(-err)); if (err == NO_ERROR) { currentBuffer = buffer; From 402c34649f514669517c2208e35caa58ff8bb2b9 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Tue, 14 Apr 2009 18:21:47 -0700 Subject: [PATCH 06/83] fix some issues with Surface's lifetime management. To deal with Java's lack of destructors and delayed garbage collection, we used to duplicate Surface.cpp objects in some case; this caused some issues because Surface is supposed to be reference-counted and unique. --- core/java/android/view/Surface.java | 6 +- core/jni/android_view_Surface.cpp | 44 ++++++++------ include/ui/Surface.h | 11 +++- libs/ui/Surface.cpp | 90 +++++++++++++++-------------- 4 files changed, 88 insertions(+), 63 deletions(-) diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java index 0178d635fb3bd..f82cedce4c08e 100644 --- a/core/java/android/view/Surface.java +++ b/core/java/android/view/Surface.java @@ -283,7 +283,7 @@ public class Surface implements Parcelable { public native void readFromParcel(Parcel source); public native void writeToParcel(Parcel dest, int flags); - + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { @@ -304,7 +304,7 @@ public class Surface implements Parcelable { /* no user serviceable parts here ... */ @Override protected void finalize() throws Throwable { - clear(); + release(); } private native void init(SurfaceSession s, @@ -312,4 +312,6 @@ public class Surface implements Parcelable { throws OutOfResourcesException; private native void init(Parcel source); + + private native void release(); } diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp index 54d8b14f062e7..5b675e53defc4 100644 --- a/core/jni/android_view_Surface.cpp +++ b/core/jni/android_view_Surface.cpp @@ -173,6 +173,15 @@ static void Surface_initParcel(JNIEnv* env, jobject clazz, jobject argParcel) } static void Surface_clear(JNIEnv* env, jobject clazz, uintptr_t *ostack) +{ + const sp& surface = getSurface(env, clazz); + if (Surface::isValid(surface)) { + surface->clear(); + } + setSurface(env, clazz, 0); +} + +static void Surface_release(JNIEnv* env, jobject clazz, uintptr_t *ostack) { setSurface(env, clazz, 0); } @@ -180,7 +189,7 @@ static void Surface_clear(JNIEnv* env, jobject clazz, uintptr_t *ostack) static jboolean Surface_isValid(JNIEnv* env, jobject clazz) { const sp& surface = getSurface(env, clazz); - return surface->isValid() ? JNI_TRUE : JNI_FALSE; + return Surface::isValid(surface) ? JNI_TRUE : JNI_FALSE; } static inline SkBitmap::Config convertPixelFormat(PixelFormat format) @@ -201,7 +210,7 @@ static inline SkBitmap::Config convertPixelFormat(PixelFormat format) static jobject Surface_lockCanvas(JNIEnv* env, jobject clazz, jobject dirtyRect) { const sp& surface = getSurface(env, clazz); - if (!surface->isValid()) + if (!Surface::isValid(surface)) return 0; // get dirty region @@ -270,7 +279,7 @@ static void Surface_unlockCanvasAndPost( } const sp& surface = getSurface(env, clazz); - if (!surface->isValid()) + if (!Surface::isValid(surface)) return; // detach the canvas from the surface @@ -337,7 +346,7 @@ static void Surface_setLayer( JNIEnv* env, jobject clazz, jint zorder) { const sp& surface = getSurface(env, clazz); - if (surface->isValid()) { + if (Surface::isValid(surface)) { if (surface->setLayer(zorder) < 0) { doThrow(env, "java/lang/IllegalArgumentException", NULL); } @@ -348,7 +357,7 @@ static void Surface_setPosition( JNIEnv* env, jobject clazz, jint x, jint y) { const sp& surface = getSurface(env, clazz); - if (surface->isValid()) { + if (Surface::isValid(surface)) { if (surface->setPosition(x, y) < 0) { doThrow(env, "java/lang/IllegalArgumentException", NULL); } @@ -359,7 +368,7 @@ static void Surface_setSize( JNIEnv* env, jobject clazz, jint w, jint h) { const sp& surface = getSurface(env, clazz); - if (surface->isValid()) { + if (Surface::isValid(surface)) { if (surface->setSize(w, h) < 0) { doThrow(env, "java/lang/IllegalArgumentException", NULL); } @@ -370,7 +379,7 @@ static void Surface_hide( JNIEnv* env, jobject clazz) { const sp& surface = getSurface(env, clazz); - if (surface->isValid()) { + if (Surface::isValid(surface)) { if (surface->hide() < 0) { doThrow(env, "java/lang/IllegalArgumentException", NULL); } @@ -381,7 +390,7 @@ static void Surface_show( JNIEnv* env, jobject clazz) { const sp& surface = getSurface(env, clazz); - if (surface->isValid()) { + if (Surface::isValid(surface)) { if (surface->show() < 0) { doThrow(env, "java/lang/IllegalArgumentException", NULL); } @@ -392,7 +401,7 @@ static void Surface_freeze( JNIEnv* env, jobject clazz) { const sp& surface = getSurface(env, clazz); - if (surface->isValid()) { + if (Surface::isValid(surface)) { if (surface->freeze() < 0) { doThrow(env, "java/lang/IllegalArgumentException", NULL); } @@ -403,7 +412,7 @@ static void Surface_unfreeze( JNIEnv* env, jobject clazz) { const sp& surface = getSurface(env, clazz); - if (surface->isValid()) { + if (Surface::isValid(surface)) { if (surface->unfreeze() < 0) { doThrow(env, "java/lang/IllegalArgumentException", NULL); } @@ -414,7 +423,7 @@ static void Surface_setFlags( JNIEnv* env, jobject clazz, jint flags, jint mask) { const sp& surface = getSurface(env, clazz); - if (surface->isValid()) { + if (Surface::isValid(surface)) { if (surface->setFlags(flags, mask) < 0) { doThrow(env, "java/lang/IllegalArgumentException", NULL); } @@ -425,7 +434,7 @@ static void Surface_setTransparentRegion( JNIEnv* env, jobject clazz, jobject argRegion) { const sp& surface = getSurface(env, clazz); - if (surface->isValid()) { + if (Surface::isValid(surface)) { SkRegion* nativeRegion = (SkRegion*)env->GetIntField(argRegion, no.native_region); if (surface->setTransparentRegionHint(Region(*nativeRegion)) < 0) { doThrow(env, "java/lang/IllegalArgumentException", NULL); @@ -437,7 +446,7 @@ static void Surface_setAlpha( JNIEnv* env, jobject clazz, jfloat alpha) { const sp& surface = getSurface(env, clazz); - if (surface->isValid()) { + if (Surface::isValid(surface)) { if (surface->setAlpha(alpha) < 0) { doThrow(env, "java/lang/IllegalArgumentException", NULL); } @@ -449,7 +458,7 @@ static void Surface_setMatrix( jfloat dsdx, jfloat dtdx, jfloat dsdy, jfloat dtdy) { const sp& surface = getSurface(env, clazz); - if (surface->isValid()) { + if (Surface::isValid(surface)) { if (surface->setMatrix(dsdx, dtdx, dsdy, dtdy) < 0) { doThrow(env, "java/lang/IllegalArgumentException", NULL); } @@ -461,7 +470,7 @@ static void Surface_setFreezeTint( jint tint) { const sp& surface = getSurface(env, clazz); - if (surface->isValid()) { + if (Surface::isValid(surface)) { if (surface->setFreezeTint(tint) < 0) { doThrow(env, "java/lang/IllegalArgumentException", NULL); } @@ -484,7 +493,7 @@ static void Surface_copyFrom( if (!Surface::isSameSurface(surface, rhs)) { // we reassign the surface only if it's a different one // otherwise we would loose our client-side state. - setSurface(env, clazz, rhs->dup()); + setSurface(env, clazz, rhs); } } @@ -540,7 +549,8 @@ static JNINativeMethod gSurfaceMethods[] = { {"nativeClassInit", "()V", (void*)nativeClassInit }, {"init", "(Landroid/view/SurfaceSession;IIIIII)V", (void*)Surface_init }, {"init", "(Landroid/os/Parcel;)V", (void*)Surface_initParcel }, - {"clear", "()V", (void*)Surface_clear }, + {"clear", "()V", (void*)Surface_clear }, + {"release", "()V", (void*)Surface_release }, {"copyFrom", "(Landroid/view/Surface;)V", (void*)Surface_copyFrom }, {"isValid", "()Z", (void*)Surface_isValid }, {"lockCanvasNative", "(Landroid/graphics/Rect;)Landroid/graphics/Canvas;", (void*)Surface_lockCanvas }, diff --git a/include/ui/Surface.h b/include/ui/Surface.h index d92da4919e63b..1637961b6af8b 100644 --- a/include/ui/Surface.h +++ b/include/ui/Surface.h @@ -90,9 +90,15 @@ public: uint32_t reserved[2]; }; - bool isValid() const { return this && mToken>=0 && mClient!=0; } + static bool isValid(const sp& surface) { + return (surface != 0) && surface->mToken>=0 && surface->mClient!=0; + } + SurfaceID ID() const { return mToken; } + // release surface data from java + void clear(); + status_t lock(SurfaceInfo* info, bool blocking = true); status_t lock(SurfaceInfo* info, Region* dirty, bool blocking = true); status_t unlockAndPost(); @@ -103,7 +109,6 @@ public: void setSwapRectangle(const Rect& r); const Rect& swapRectangle() const; - sp dup() const; static sp readFromParcel(Parcel* parcel); static status_t writeToParcel(const sp& surface, Parcel* parcel); static bool isSameSurface(const sp& lhs, const sp& rhs); @@ -149,6 +154,8 @@ private: ~Surface(); + void destroy(); + Region dirtyRegion() const; void setDirtyRegion(const Region& region) const; diff --git a/libs/ui/Surface.cpp b/libs/ui/Surface.cpp index 1ceece019527a..51abd95faa051 100644 --- a/libs/ui/Surface.cpp +++ b/libs/ui/Surface.cpp @@ -176,61 +176,60 @@ Surface::Surface(const sp& client, const_cast(android_native_window_t::flags) = 0; } -Surface::Surface(Surface const* rhs) - : mOwner(false) -{ - // FIXME: we really should get rid of this ctor. the memcpy below - //should be safe for now, but android_native_window_t is not supposed - // to be clonable. - memcpy( static_cast(this), - static_cast(rhs), - sizeof(android_native_window_t)); - - mToken = rhs->mToken; - mIdentity = rhs->mIdentity; - mClient = rhs->mClient; - mSurface = rhs->mSurface; - mBuffers[0] = rhs->mBuffers[0]; - mBuffers[1] = rhs->mBuffers[1]; - mFormat = rhs->mFormat; - mFlags = rhs->mFlags; - mSwapRectangle.makeInvalid(); -} - Surface::~Surface() { - if (mOwner && mToken>=0 && mClient!=0) { - mClient->destroySurface(mToken); - if (mBuffers[0] != 0) { - BufferMapper::get().unmap(mBuffers[0]->getHandle(), this); - } - if (mBuffers[1] != 0) { - BufferMapper::get().unmap(mBuffers[1]->getHandle(), this); + // this is a client-side operation, the surface is destroyed, unmap + // its buffers in this process. + for (int i=0 ; i<2 ; i++) { + if (mBuffers[i] != 0) { + BufferMapper::get().unmap(mBuffers[i]->getHandle(), this); } } + + destroy(); +} + +void Surface::destroy() +{ + // Destroy the surface in SurfaceFlinger if we were the owner + // (in any case, a client won't be able to, because it won't have the + // right permission). + if (mOwner && mToken>=0 && mClient!=0) { + mClient->destroySurface(mToken); + } + + // clear all references and trigger an IPC now, to make sure things + // happen without delay, since these resources are quite heavy. mClient.clear(); mSurface.clear(); IPCThreadState::self()->flushCommands(); } -sp Surface::dup() const +void Surface::clear() { - // FIXME: we should get rid of Surface::dup() - Surface const * r = this; - if (this && mOwner) { - // the only reason we need to do this is because of Java's garbage - // collector: because we're creating a copy of the Surface - // instead of a reference, we can guarantee that when our last - // reference goes away, the real surface will be deleted. - // Without this hack (the code is correct too), we'd have to - // wait for a GC for the surface to go away. - r = new Surface(this); - } - return const_cast(r); + // here, the window manager tells us explicitly that we should destroy + // the surface's resource. Soon after this call, it will also release + // its last reference (which will call the dtor); however, it is possible + // that a client living in the same process still holds references which + // would delay the call to the dtor -- that is why we need this explicit + // "clear()" call. + + // FIXME: we should probably unmap the buffers here. The problem is that + // the app could be in the middle of using them, and if we don't unmap now + // and we're in the system process, the mapping will be lost (because + // the buffer will be freed, and the handles destroyed) + + Mutex::Autolock _l(mSurfaceLock); + destroy(); } status_t Surface::validate(per_client_cblk_t const* cblk) const { + if (mToken<0 || mClient==0) { + LOGE("invalid token (%d, identity=%u) or client (%p)", + mToken, mIdentity, mClient.get()); + return NO_INIT; + } if (cblk == 0) { LOGE("cblk is null (surface id=%d, identity=%u)", mToken, mIdentity); return NO_INIT; @@ -330,6 +329,13 @@ int Surface::dequeueBuffer(android_native_buffer_t** buffer) int Surface::lockBuffer(android_native_buffer_t* buffer) { + Mutex::Autolock _l(mSurfaceLock); + + per_client_cblk_t* const cblk = mClient->mControl; + status_t err = validate(cblk); + if (err != NO_ERROR) + return err; + // FIXME: lockBuffer() needs proper implementation return 0; } @@ -543,7 +549,7 @@ status_t Surface::writeToParcel(const sp& surface, Parcel* parcel) uint32_t identity = 0; sp client; sp sur; - if (surface->isValid()) { + if (Surface::isValid(surface)) { token = surface->mToken; identity = surface->mIdentity; client = surface->mClient; From ed81f2216a0f200e279de61ec96fbedf5c21f0c7 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Tue, 14 Apr 2009 23:02:51 -0700 Subject: [PATCH 07/83] fix a few typos in comments. this is really intended as a git pull/push test. --- libs/surfaceflinger/SurfaceFlinger.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp index 8dca12489bebc..a5c1e8fb8671a 100644 --- a/libs/surfaceflinger/SurfaceFlinger.cpp +++ b/libs/surfaceflinger/SurfaceFlinger.cpp @@ -562,7 +562,7 @@ void SurfaceFlinger::handleConsoleEvents() } if (mDeferReleaseConsole && hw.canDraw()) { - // We got the release signal before the aquire signal + // We got the release signal before the acquire signal mDeferReleaseConsole = false; hw.releaseScreen(); } @@ -739,7 +739,7 @@ void SurfaceFlinger::computeVisibleRegions( // accumulate to the screen dirty region dirtyRegion.orSelf(dirty); - // updade aboveOpaqueLayers/aboveCoveredLayers for next (lower) layer + // Update aboveOpaqueLayers/aboveCoveredLayers for next (lower) layer aboveOpaqueLayers.orSelf(opaqueRegion); aboveCoveredLayers.orSelf(bounds); @@ -747,7 +747,7 @@ void SurfaceFlinger::computeVisibleRegions( layer->setVisibleRegion(visibleRegion); layer->setCoveredRegion(coveredRegion); - // If a secure layer is partially visible, lockdown the screen! + // If a secure layer is partially visible, lock down the screen! if (layer->isSecure() && !visibleRegion.isEmpty()) { secureFrameBuffer = true; } @@ -1131,7 +1131,7 @@ status_t SurfaceFlinger::freezeDisplay(DisplayID dpy, uint32_t flags) setTransactionFlags(eTransactionNeeded); // flags is intended to communicate some sort of animation behavior - // (for instance fadding) + // (for instance fading) return NO_ERROR; } @@ -1145,7 +1145,7 @@ status_t SurfaceFlinger::unfreezeDisplay(DisplayID dpy, uint32_t flags) setTransactionFlags(eTransactionNeeded); // flags is intended to communicate some sort of animation behavior - // (for instance fadding) + // (for instance fading) return NO_ERROR; } From 6d2c0bc7bfe10a9b70ca608baf626c47a228fa6b Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Thu, 16 Apr 2009 16:19:50 -0700 Subject: [PATCH 08/83] split Surface.cpp into Surface and SurfaceControl SurfaceControl is used for controling the geometry of the surface (for the WM), while Surface is used to access the buffers (for SF's clients). SurfaceFlingerClient now uses the SurfaceID instead of Surface*. Currently Surface still has the SurfaceControl API and is implemented by calling into SurfaceControl. --- include/ui/Surface.h | 72 +++++++ include/ui/SurfaceComposerClient.h | 29 +-- libs/ui/Surface.cpp | 313 +++++++++++++++++++++++------ libs/ui/SurfaceComposerClient.cpp | 60 +++--- 4 files changed, 369 insertions(+), 105 deletions(-) diff --git a/include/ui/Surface.h b/include/ui/Surface.h index 1637961b6af8b..87a11c2824f21 100644 --- a/include/ui/Surface.h +++ b/include/ui/Surface.h @@ -76,6 +76,76 @@ private: // --------------------------------------------------------------------------- +class SurfaceControl : public RefBase +{ +public: + static bool isValid(const sp& surface) { + return (surface != 0) && surface->mToken>=0 && surface->mClient!=0; + } + + SurfaceID ID() const { return mToken; } + uint32_t getFlags() const { return mFlags; } + uint32_t getIdentity() const { return mIdentity; } + + // release surface data from java + void clear(); + + static sp readFromParcel(Parcel* parcel); + static status_t writeToParcel(const sp& surface, Parcel* parcel); + static bool isSameSurface(const sp& lhs, const sp& rhs); + + status_t setLayer(int32_t layer); + status_t setPosition(int32_t x, int32_t y); + status_t setSize(uint32_t w, uint32_t h); + status_t hide(); + status_t show(int32_t layer = -1); + status_t freeze(); + status_t unfreeze(); + status_t setFlags(uint32_t flags, uint32_t mask); + status_t setTransparentRegionHint(const Region& transparent); + status_t setAlpha(float alpha=1.0f); + status_t setMatrix(float dsdx, float dtdx, float dsdy, float dtdy); + status_t setFreezeTint(uint32_t tint); + +private: + friend class SurfaceComposerClient; + + // camera and camcorder need access to the ISurface binder interface for preview + friend class Camera; + friend class MediaRecorder; + // mediaplayer needs access to ISurface for display + friend class MediaPlayer; + friend class Test; + const sp& getISurface() const { return mSurface; } + + // can't be copied + SurfaceControl& operator = (SurfaceControl& rhs); + SurfaceControl(const SurfaceControl& rhs); + + friend class Surface; + SurfaceControl(const sp& client, + const sp& surface, + const ISurfaceFlingerClient::surface_data_t& data, + uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, + bool owner = true); + + ~SurfaceControl(); + + status_t validate(per_client_cblk_t const* cblk) const; + void destroy(); + + sp mClient; + sp mSurface; + SurfaceID mToken; + uint32_t mIdentity; + PixelFormat mFormat; + uint32_t mFlags; + const bool mOwner; + mutable Mutex mLock; +}; + +// --------------------------------------------------------------------------- + class Surface : public EGLNativeBase { @@ -192,6 +262,8 @@ private: mutable Rect mSwapRectangle; mutable uint8_t mBackbufferIndex; mutable Mutex mSurfaceLock; + + sp mSurfaceControl; }; }; // namespace android diff --git a/include/ui/SurfaceComposerClient.h b/include/ui/SurfaceComposerClient.h index 86de6ea343935..a175a18a0dc31 100644 --- a/include/ui/SurfaceComposerClient.h +++ b/include/ui/SurfaceComposerClient.h @@ -111,22 +111,23 @@ public: private: friend class Surface; + friend class SurfaceControl; SurfaceComposerClient(const sp& sm, const sp& conn); - status_t hide(Surface* surface); - status_t show(Surface* surface, int32_t layer = -1); - status_t freeze(Surface* surface); - status_t unfreeze(Surface* surface); - status_t setFlags(Surface* surface, uint32_t flags, uint32_t mask); - status_t setTransparentRegionHint(Surface* surface, const Region& transparent); - status_t setLayer(Surface* surface, int32_t layer); - status_t setAlpha(Surface* surface, float alpha=1.0f); - status_t setFreezeTint(Surface* surface, uint32_t tint); - status_t setMatrix(Surface* surface, float dsdx, float dtdx, float dsdy, float dtdy); - status_t setPosition(Surface* surface, int32_t x, int32_t y); - status_t setSize(Surface* surface, uint32_t w, uint32_t h); + status_t hide(SurfaceID id); + status_t show(SurfaceID id, int32_t layer = -1); + status_t freeze(SurfaceID id); + status_t unfreeze(SurfaceID id); + status_t setFlags(SurfaceID id, uint32_t flags, uint32_t mask); + status_t setTransparentRegionHint(SurfaceID id, const Region& transparent); + status_t setLayer(SurfaceID id, int32_t layer); + status_t setAlpha(SurfaceID id, float alpha=1.0f); + status_t setFreezeTint(SurfaceID id, uint32_t tint); + status_t setMatrix(SurfaceID id, float dsdx, float dtdx, float dsdy, float dtdy); + status_t setPosition(SurfaceID id, int32_t x, int32_t y); + status_t setSize(SurfaceID id, uint32_t w, uint32_t h); void signalServer(); @@ -135,8 +136,8 @@ private: void _init(const sp& sm, const sp& conn); - inline layer_state_t* _get_state_l(const sp& surface); - layer_state_t* _lockLayerState(const sp& surface); + inline layer_state_t* _get_state_l(SurfaceID id); + layer_state_t* _lockLayerState(SurfaceID id); inline void _unlockLayerState(); mutable Mutex mLock; diff --git a/libs/ui/Surface.cpp b/libs/ui/Surface.cpp index 51abd95faa051..63699c7fd7b16 100644 --- a/libs/ui/Surface.cpp +++ b/libs/ui/Surface.cpp @@ -143,6 +143,216 @@ static void copyBlt(const android_native_buffer_t* dst, } } + +// ============================================================================ +// SurfaceControl +// ============================================================================ + + +SurfaceControl::SurfaceControl(const sp& client, + const sp& surface, + const ISurfaceFlingerClient::surface_data_t& data, + uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, + bool owner) + : mClient(client), mSurface(surface), + mToken(data.token), mIdentity(data.identity), + mFormat(format), mFlags(flags), mOwner(owner) +{ +} + +SurfaceControl::~SurfaceControl() +{ + destroy(); +} + +void SurfaceControl::destroy() +{ + // Destroy the surface in SurfaceFlinger if we were the owner + // (in any case, a client won't be able to, because it won't have the + // right permission). + if (mOwner && mToken>=0 && mClient!=0) { + mClient->destroySurface(mToken); + } + + // clear all references and trigger an IPC now, to make sure things + // happen without delay, since these resources are quite heavy. + mClient.clear(); + mSurface.clear(); + IPCThreadState::self()->flushCommands(); +} + +void SurfaceControl::clear() +{ + // here, the window manager tells us explicitly that we should destroy + // the surface's resource. Soon after this call, it will also release + // its last reference (which will call the dtor); however, it is possible + // that a client living in the same process still holds references which + // would delay the call to the dtor -- that is why we need this explicit + // "clear()" call. + destroy(); +} + +status_t SurfaceControl::setLayer(int32_t layer) { + const sp& client(mClient); + if (client == 0) return INVALID_OPERATION; + status_t err = validate(client->mControl); + if (err < 0) return err; + return client->setLayer(mToken, layer); +} +status_t SurfaceControl::setPosition(int32_t x, int32_t y) { + const sp& client(mClient); + if (client == 0) return INVALID_OPERATION; + status_t err = validate(client->mControl); + if (err < 0) return err; + return client->setPosition(mToken, x, y); +} +status_t SurfaceControl::setSize(uint32_t w, uint32_t h) { + const sp& client(mClient); + if (client == 0) return INVALID_OPERATION; + status_t err = validate(client->mControl); + if (err < 0) return err; + return client->setSize(mToken, w, h); +} +status_t SurfaceControl::hide() { + const sp& client(mClient); + if (client == 0) return INVALID_OPERATION; + status_t err = validate(client->mControl); + if (err < 0) return err; + return client->hide(mToken); +} +status_t SurfaceControl::show(int32_t layer) { + const sp& client(mClient); + if (client == 0) return INVALID_OPERATION; + status_t err = validate(client->mControl); + if (err < 0) return err; + return client->show(mToken, layer); +} +status_t SurfaceControl::freeze() { + const sp& client(mClient); + if (client == 0) return INVALID_OPERATION; + status_t err = validate(client->mControl); + if (err < 0) return err; + return client->freeze(mToken); +} +status_t SurfaceControl::unfreeze() { + const sp& client(mClient); + if (client == 0) return INVALID_OPERATION; + status_t err = validate(client->mControl); + if (err < 0) return err; + return client->unfreeze(mToken); +} +status_t SurfaceControl::setFlags(uint32_t flags, uint32_t mask) { + const sp& client(mClient); + if (client == 0) return INVALID_OPERATION; + status_t err = validate(client->mControl); + if (err < 0) return err; + return client->setFlags(mToken, flags, mask); +} +status_t SurfaceControl::setTransparentRegionHint(const Region& transparent) { + const sp& client(mClient); + if (client == 0) return INVALID_OPERATION; + status_t err = validate(client->mControl); + if (err < 0) return err; + return client->setTransparentRegionHint(mToken, transparent); +} +status_t SurfaceControl::setAlpha(float alpha) { + const sp& client(mClient); + if (client == 0) return INVALID_OPERATION; + status_t err = validate(client->mControl); + if (err < 0) return err; + return client->setAlpha(mToken, alpha); +} +status_t SurfaceControl::setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) { + const sp& client(mClient); + if (client == 0) return INVALID_OPERATION; + status_t err = validate(client->mControl); + if (err < 0) return err; + return client->setMatrix(mToken, dsdx, dtdx, dsdy, dtdy); +} +status_t SurfaceControl::setFreezeTint(uint32_t tint) { + const sp& client(mClient); + if (client == 0) return INVALID_OPERATION; + status_t err = validate(client->mControl); + if (err < 0) return err; + return client->setFreezeTint(mToken, tint); +} + +sp SurfaceControl::readFromParcel(Parcel* parcel) +{ + sp client; + ISurfaceFlingerClient::surface_data_t data; + sp clientBinder= parcel->readStrongBinder(); + sp surface = interface_cast(parcel->readStrongBinder()); + data.token = parcel->readInt32(); + data.identity = parcel->readInt32(); + PixelFormat format = parcel->readInt32(); + uint32_t flags = parcel->readInt32(); + + if (clientBinder != NULL) + client = SurfaceComposerClient::clientForConnection(clientBinder); + + return new SurfaceControl(client, surface, data, 0, 0, format, flags, false); +} + +status_t SurfaceControl::writeToParcel(const sp& surface, Parcel* parcel) +{ + uint32_t flags=0; + uint32_t format=0; + SurfaceID token = -1; + uint32_t identity = 0; + sp client; + sp sur; + if (SurfaceControl::isValid(surface)) { + token = surface->mToken; + identity = surface->mIdentity; + client = surface->mClient; + sur = surface->mSurface; + format = surface->mFormat; + flags = surface->mFlags; + } + parcel->writeStrongBinder(client!=0 ? client->connection() : NULL); + parcel->writeStrongBinder(sur!=0 ? sur->asBinder() : NULL); + parcel->writeInt32(token); + parcel->writeInt32(identity); + parcel->writeInt32(format); + parcel->writeInt32(flags); + return NO_ERROR; +} + +bool SurfaceControl::isSameSurface( + const sp& lhs, const sp& rhs) +{ + if (lhs == 0 || rhs == 0) + return false; + return lhs->mSurface->asBinder() == rhs->mSurface->asBinder(); +} + + +status_t SurfaceControl::validate(per_client_cblk_t const* cblk) const +{ + if (mToken<0 || mClient==0) { + LOGE("invalid token (%d, identity=%u) or client (%p)", + mToken, mIdentity, mClient.get()); + return NO_INIT; + } + if (cblk == 0) { + LOGE("cblk is null (surface id=%d, identity=%u)", mToken, mIdentity); + return NO_INIT; + } + status_t err = cblk->validate(mToken); + if (err != NO_ERROR) { + LOGE("surface (id=%d, identity=%u) is invalid, err=%d (%s)", + mToken, mIdentity, err, strerror(-err)); + return err; + } + if (mIdentity != uint32_t(cblk->layers[mToken].identity)) { + LOGE("using an invalid surface id=%d, identity=%u should be %d", + mToken, mIdentity, cblk->layers[mToken].identity); + return NO_INIT; + } + return NO_ERROR; +} + // ============================================================================ // Surface // ============================================================================ @@ -156,6 +366,9 @@ Surface::Surface(const sp& client, mToken(data.token), mIdentity(data.identity), mFormat(format), mFlags(flags), mOwner(owner) { + mSurfaceControl = new SurfaceControl( + client, surface, data, w, h, format, flags, owner); + android_native_window_t::connect = connect; android_native_window_t::disconnect = disconnect; android_native_window_t::setSwapInterval = setSwapInterval; @@ -191,12 +404,7 @@ Surface::~Surface() void Surface::destroy() { - // Destroy the surface in SurfaceFlinger if we were the owner - // (in any case, a client won't be able to, because it won't have the - // right permission). - if (mOwner && mToken>=0 && mClient!=0) { - mClient->destroySurface(mToken); - } + mSurfaceControl->destroy(); // clear all references and trigger an IPC now, to make sure things // happen without delay, since these resources are quite heavy. @@ -207,20 +415,7 @@ void Surface::destroy() void Surface::clear() { - // here, the window manager tells us explicitly that we should destroy - // the surface's resource. Soon after this call, it will also release - // its last reference (which will call the dtor); however, it is possible - // that a client living in the same process still holds references which - // would delay the call to the dtor -- that is why we need this explicit - // "clear()" call. - - // FIXME: we should probably unmap the buffers here. The problem is that - // the app could be in the middle of using them, and if we don't unmap now - // and we're in the system process, the mapping will be lost (because - // the buffer will be freed, and the handles destroyed) - - Mutex::Autolock _l(mSurfaceLock); - destroy(); + mSurfaceControl->clear(); } status_t Surface::validate(per_client_cblk_t const* cblk) const @@ -473,44 +668,6 @@ void Surface::_send_dirty_region( } } - -status_t Surface::setLayer(int32_t layer) { - return mClient->setLayer(this, layer); -} -status_t Surface::setPosition(int32_t x, int32_t y) { - return mClient->setPosition(this, x, y); -} -status_t Surface::setSize(uint32_t w, uint32_t h) { - return mClient->setSize(this, w, h); -} -status_t Surface::hide() { - return mClient->hide(this); -} -status_t Surface::show(int32_t layer) { - return mClient->show(this, layer); -} -status_t Surface::freeze() { - return mClient->freeze(this); -} -status_t Surface::unfreeze() { - return mClient->unfreeze(this); -} -status_t Surface::setFlags(uint32_t flags, uint32_t mask) { - return mClient->setFlags(this, flags, mask); -} -status_t Surface::setTransparentRegionHint(const Region& transparent) { - return mClient->setTransparentRegionHint(this, transparent); -} -status_t Surface::setAlpha(float alpha) { - return mClient->setAlpha(this, alpha); -} -status_t Surface::setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) { - return mClient->setMatrix(this, dsdx, dtdx, dsdy, dtdy); -} -status_t Surface::setFreezeTint(uint32_t tint) { - return mClient->setFreezeTint(this, tint); -} - Region Surface::dirtyRegion() const { return mDirtyRegion; } @@ -593,5 +750,45 @@ status_t Surface::getBufferLocked(int index) return err; } + + +status_t Surface::setLayer(int32_t layer) { + return mSurfaceControl->setLayer(layer); +} +status_t Surface::setPosition(int32_t x, int32_t y) { + return mSurfaceControl->setPosition(x, y); +} +status_t Surface::setSize(uint32_t w, uint32_t h) { + return mSurfaceControl->setSize(w, h); +} +status_t Surface::hide() { + return mSurfaceControl->hide(); +} +status_t Surface::show(int32_t layer) { + return mSurfaceControl->show(layer); +} +status_t Surface::freeze() { + return mSurfaceControl->freeze(); +} +status_t Surface::unfreeze() { + return mSurfaceControl->unfreeze(); +} +status_t Surface::setFlags(uint32_t flags, uint32_t mask) { + return mSurfaceControl->setFlags(flags, mask); +} +status_t Surface::setTransparentRegionHint(const Region& transparent) { + return mSurfaceControl->setTransparentRegionHint(transparent); +} +status_t Surface::setAlpha(float alpha) { + return mSurfaceControl->setAlpha(alpha); +} +status_t Surface::setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) { + return mSurfaceControl->setMatrix(dsdx, dtdx, dsdy, dtdy); +} +status_t Surface::setFreezeTint(uint32_t tint) { + return mSurfaceControl->setFreezeTint(tint); +} + + }; // namespace android diff --git a/libs/ui/SurfaceComposerClient.cpp b/libs/ui/SurfaceComposerClient.cpp index e1b13c7b8eed9..4ccd3965c35f6 100644 --- a/libs/ui/SurfaceComposerClient.cpp +++ b/libs/ui/SurfaceComposerClient.cpp @@ -616,14 +616,8 @@ status_t SurfaceComposerClient::closeTransaction() return NO_ERROR; } -layer_state_t* SurfaceComposerClient::_get_state_l(const sp& surface) +layer_state_t* SurfaceComposerClient::_get_state_l(SurfaceID index) { - SurfaceID index = surface->ID(); - per_client_cblk_t* const cblk = mControl; - status_t err = surface->validate(cblk); - if (err != NO_ERROR) - return 0; - // API usage error, do nothing. if (mTransactionOpen<=0) { LOGE("Not in transaction (client=%p, SurfaceID=%d, mTransactionOpen=%d", @@ -642,11 +636,11 @@ layer_state_t* SurfaceComposerClient::_get_state_l(const sp& surface) return mStates.editArray() + i; } -layer_state_t* SurfaceComposerClient::_lockLayerState(const sp& surface) +layer_state_t* SurfaceComposerClient::_lockLayerState(SurfaceID id) { layer_state_t* s; mLock.lock(); - s = _get_state_l(surface); + s = _get_state_l(id); if (!s) mLock.unlock(); return s; } @@ -656,9 +650,9 @@ void SurfaceComposerClient::_unlockLayerState() mLock.unlock(); } -status_t SurfaceComposerClient::setPosition(Surface* surface, int32_t x, int32_t y) +status_t SurfaceComposerClient::setPosition(SurfaceID id, int32_t x, int32_t y) { - layer_state_t* s = _lockLayerState(surface); + layer_state_t* s = _lockLayerState(id); if (!s) return BAD_INDEX; s->what |= ISurfaceComposer::ePositionChanged; s->x = x; @@ -667,9 +661,9 @@ status_t SurfaceComposerClient::setPosition(Surface* surface, int32_t x, int32_t return NO_ERROR; } -status_t SurfaceComposerClient::setSize(Surface* surface, uint32_t w, uint32_t h) +status_t SurfaceComposerClient::setSize(SurfaceID id, uint32_t w, uint32_t h) { - layer_state_t* s = _lockLayerState(surface); + layer_state_t* s = _lockLayerState(id); if (!s) return BAD_INDEX; s->what |= ISurfaceComposer::eSizeChanged; s->w = w; @@ -678,9 +672,9 @@ status_t SurfaceComposerClient::setSize(Surface* surface, uint32_t w, uint32_t h return NO_ERROR; } -status_t SurfaceComposerClient::setLayer(Surface* surface, int32_t z) +status_t SurfaceComposerClient::setLayer(SurfaceID id, int32_t z) { - layer_state_t* s = _lockLayerState(surface); + layer_state_t* s = _lockLayerState(id); if (!s) return BAD_INDEX; s->what |= ISurfaceComposer::eLayerChanged; s->z = z; @@ -688,32 +682,32 @@ status_t SurfaceComposerClient::setLayer(Surface* surface, int32_t z) return NO_ERROR; } -status_t SurfaceComposerClient::hide(Surface* surface) +status_t SurfaceComposerClient::hide(SurfaceID id) { - return setFlags(surface, ISurfaceComposer::eLayerHidden, + return setFlags(id, ISurfaceComposer::eLayerHidden, ISurfaceComposer::eLayerHidden); } -status_t SurfaceComposerClient::show(Surface* surface, int32_t) +status_t SurfaceComposerClient::show(SurfaceID id, int32_t) { - return setFlags(surface, 0, ISurfaceComposer::eLayerHidden); + return setFlags(id, 0, ISurfaceComposer::eLayerHidden); } -status_t SurfaceComposerClient::freeze(Surface* surface) +status_t SurfaceComposerClient::freeze(SurfaceID id) { - return setFlags(surface, ISurfaceComposer::eLayerFrozen, + return setFlags(id, ISurfaceComposer::eLayerFrozen, ISurfaceComposer::eLayerFrozen); } -status_t SurfaceComposerClient::unfreeze(Surface* surface) +status_t SurfaceComposerClient::unfreeze(SurfaceID id) { - return setFlags(surface, 0, ISurfaceComposer::eLayerFrozen); + return setFlags(id, 0, ISurfaceComposer::eLayerFrozen); } -status_t SurfaceComposerClient::setFlags(Surface* surface, +status_t SurfaceComposerClient::setFlags(SurfaceID id, uint32_t flags, uint32_t mask) { - layer_state_t* s = _lockLayerState(surface); + layer_state_t* s = _lockLayerState(id); if (!s) return BAD_INDEX; s->what |= ISurfaceComposer::eVisibilityChanged; s->flags &= ~mask; @@ -724,9 +718,9 @@ status_t SurfaceComposerClient::setFlags(Surface* surface, } status_t SurfaceComposerClient::setTransparentRegionHint( - Surface* surface, const Region& transparentRegion) + SurfaceID id, const Region& transparentRegion) { - layer_state_t* s = _lockLayerState(surface); + layer_state_t* s = _lockLayerState(id); if (!s) return BAD_INDEX; s->what |= ISurfaceComposer::eTransparentRegionChanged; s->transparentRegion = transparentRegion; @@ -734,9 +728,9 @@ status_t SurfaceComposerClient::setTransparentRegionHint( return NO_ERROR; } -status_t SurfaceComposerClient::setAlpha(Surface* surface, float alpha) +status_t SurfaceComposerClient::setAlpha(SurfaceID id, float alpha) { - layer_state_t* s = _lockLayerState(surface); + layer_state_t* s = _lockLayerState(id); if (!s) return BAD_INDEX; s->what |= ISurfaceComposer::eAlphaChanged; s->alpha = alpha; @@ -745,11 +739,11 @@ status_t SurfaceComposerClient::setAlpha(Surface* surface, float alpha) } status_t SurfaceComposerClient::setMatrix( - Surface* surface, + SurfaceID id, float dsdx, float dtdx, float dsdy, float dtdy ) { - layer_state_t* s = _lockLayerState(surface); + layer_state_t* s = _lockLayerState(id); if (!s) return BAD_INDEX; s->what |= ISurfaceComposer::eMatrixChanged; layer_state_t::matrix22_t matrix; @@ -762,9 +756,9 @@ status_t SurfaceComposerClient::setMatrix( return NO_ERROR; } -status_t SurfaceComposerClient::setFreezeTint(Surface* surface, uint32_t tint) +status_t SurfaceComposerClient::setFreezeTint(SurfaceID id, uint32_t tint) { - layer_state_t* s = _lockLayerState(surface); + layer_state_t* s = _lockLayerState(id); if (!s) return BAD_INDEX; s->what |= ISurfaceComposer::eFreezeTintChanged; s->tint = tint; From 17f638b39f2e8b610ecfa1290e5bc42ab7700c98 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Thu, 16 Apr 2009 20:04:08 -0700 Subject: [PATCH 09/83] more splitting of Surface/SurfaceControl. Surface.java is now implemented in terms of Surface and SurfaceControl. The WindowManager side of Surface.java holds a SurfaceControl, while the client-side holds a Surface. When the client is in the system process, Surface.java holds both (which is a problem we'll try to fix later). --- core/java/android/view/Surface.java | 4 +- core/jni/android_view_Surface.cpp | 210 +++++++------ include/ui/Surface.h | 101 +++---- include/ui/SurfaceComposerClient.h | 2 +- libs/surfaceflinger/Android.mk | 1 - libs/surfaceflinger/BootAnimation.cpp | 11 +- libs/surfaceflinger/BootAnimation.h | 1 + libs/surfaceflinger/CPUGauge.cpp | 169 ----------- libs/surfaceflinger/CPUGauge.h | 74 ----- libs/surfaceflinger/SurfaceFlinger.cpp | 38 +-- libs/surfaceflinger/SurfaceFlinger.h | 7 - libs/ui/Surface.cpp | 397 ++++++++++--------------- libs/ui/SurfaceComposerClient.cpp | 6 +- 13 files changed, 338 insertions(+), 683 deletions(-) delete mode 100644 libs/surfaceflinger/CPUGauge.cpp delete mode 100644 libs/surfaceflinger/CPUGauge.h diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java index f82cedce4c08e..a87c622ed4849 100644 --- a/core/java/android/view/Surface.java +++ b/core/java/android/view/Surface.java @@ -127,6 +127,8 @@ public class Surface implements Parcelable { @SuppressWarnings("unused") private int mSurface; @SuppressWarnings("unused") + private int mSurfaceControl; + @SuppressWarnings("unused") private int mSaveCount; @SuppressWarnings("unused") private Canvas mCanvas; @@ -270,7 +272,7 @@ public class Surface implements Parcelable { @Override public String toString() { - return "Surface(native-token=" + mSurface + ")"; + return "Surface(native-token=" + mSurfaceControl + ")"; } private Surface(Parcel source) throws OutOfResourcesException { diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp index 5b675e53defc4..c2eb5e83fda14 100644 --- a/core/jni/android_view_Surface.cpp +++ b/core/jni/android_view_Surface.cpp @@ -45,6 +45,7 @@ struct sso_t { static sso_t sso; struct so_t { + jfieldID surfaceControl; jfieldID surface; jfieldID saveCount; jfieldID canvas; @@ -121,6 +122,27 @@ static void SurfaceSession_kill(JNIEnv* env, jobject clazz) // ---------------------------------------------------------------------------- +static sp getSurfaceControl(JNIEnv* env, jobject clazz) +{ + SurfaceControl* const p = + (SurfaceControl*)env->GetIntField(clazz, so.surfaceControl); + return sp(p); +} + +static void setSurfaceControl(JNIEnv* env, jobject clazz, + const sp& surface) +{ + SurfaceControl* const p = + (SurfaceControl*)env->GetIntField(clazz, so.surfaceControl); + if (surface.get()) { + surface->incStrong(clazz); + } + if (p) { + p->decStrong(clazz); + } + env->SetIntField(clazz, so.surfaceControl, (int)surface.get()); +} + static sp getSurface(JNIEnv* env, jobject clazz) { Surface* const p = (Surface*)env->GetIntField(clazz, so.surface); @@ -153,12 +175,12 @@ static void Surface_init( SurfaceComposerClient* client = (SurfaceComposerClient*)env->GetIntField(session, sso.client); - sp surface(client->createSurface(pid, dpy, w, h, format, flags)); + sp surface(client->createSurface(pid, dpy, w, h, format, flags)); if (surface == 0) { doThrow(env, OutOfResourcesException); return; } - setSurface(env, clazz, surface); + setSurfaceControl(env, clazz, surface); } static void Surface_initParcel(JNIEnv* env, jobject clazz, jobject argParcel) @@ -168,27 +190,33 @@ static void Surface_initParcel(JNIEnv* env, jobject clazz, jobject argParcel) doThrow(env, "java/lang/NullPointerException", NULL); return; } - const sp& rhs = Surface::readFromParcel(parcel); + sp rhs = new Surface(*parcel); setSurface(env, clazz, rhs); } static void Surface_clear(JNIEnv* env, jobject clazz, uintptr_t *ostack) { - const sp& surface = getSurface(env, clazz); - if (Surface::isValid(surface)) { + const sp& surface(getSurfaceControl(env, clazz)); + if (SurfaceControl::isValid(surface)) { surface->clear(); } + setSurfaceControl(env, clazz, 0); setSurface(env, clazz, 0); } static void Surface_release(JNIEnv* env, jobject clazz, uintptr_t *ostack) { + setSurfaceControl(env, clazz, 0); setSurface(env, clazz, 0); } static jboolean Surface_isValid(JNIEnv* env, jobject clazz) { - const sp& surface = getSurface(env, clazz); + const sp& surfaceControl(getSurfaceControl(env, clazz)); + if (surfaceControl != 0) { + return SurfaceControl::isValid(surfaceControl) ? JNI_TRUE : JNI_FALSE; + } + const sp& surface(getSurface(env, clazz)); return Surface::isValid(surface) ? JNI_TRUE : JNI_FALSE; } @@ -209,7 +237,7 @@ static inline SkBitmap::Config convertPixelFormat(PixelFormat format) static jobject Surface_lockCanvas(JNIEnv* env, jobject clazz, jobject dirtyRect) { - const sp& surface = getSurface(env, clazz); + const sp& surface(getSurface(env, clazz)); if (!Surface::isValid(surface)) return 0; @@ -278,7 +306,7 @@ static void Surface_unlockCanvasAndPost( return; } - const sp& surface = getSurface(env, clazz); + const sp& surface(getSurface(env, clazz)); if (!Surface::isValid(surface)) return; @@ -345,138 +373,128 @@ static void Surface_unfreezeDisplay( static void Surface_setLayer( JNIEnv* env, jobject clazz, jint zorder) { - const sp& surface = getSurface(env, clazz); - if (Surface::isValid(surface)) { - if (surface->setLayer(zorder) < 0) { - doThrow(env, "java/lang/IllegalArgumentException", NULL); - } - } + const sp& surface(getSurfaceControl(env, clazz)); + if (surface == 0) return; + status_t err = surface->setLayer(zorder); + if (err<0 && err!=NO_INIT) + doThrow(env, "java/lang/IllegalArgumentException", NULL); } static void Surface_setPosition( JNIEnv* env, jobject clazz, jint x, jint y) { - const sp& surface = getSurface(env, clazz); - if (Surface::isValid(surface)) { - if (surface->setPosition(x, y) < 0) { - doThrow(env, "java/lang/IllegalArgumentException", NULL); - } - } + const sp& surface(getSurfaceControl(env, clazz)); + if (surface == 0) return; + status_t err = surface->setPosition(x, y); + if (err<0 && err!=NO_INIT) + doThrow(env, "java/lang/IllegalArgumentException", NULL); } static void Surface_setSize( JNIEnv* env, jobject clazz, jint w, jint h) { - const sp& surface = getSurface(env, clazz); - if (Surface::isValid(surface)) { - if (surface->setSize(w, h) < 0) { - doThrow(env, "java/lang/IllegalArgumentException", NULL); - } - } + const sp& surface(getSurfaceControl(env, clazz)); + if (surface == 0) return; + status_t err = surface->setSize(w, h); + if (err<0 && err!=NO_INIT) + doThrow(env, "java/lang/IllegalArgumentException", NULL); } static void Surface_hide( JNIEnv* env, jobject clazz) { - const sp& surface = getSurface(env, clazz); - if (Surface::isValid(surface)) { - if (surface->hide() < 0) { - doThrow(env, "java/lang/IllegalArgumentException", NULL); - } - } + const sp& surface(getSurfaceControl(env, clazz)); + if (surface == 0) return; + status_t err = surface->hide(); + if (err<0 && err!=NO_INIT) + doThrow(env, "java/lang/IllegalArgumentException", NULL); } static void Surface_show( JNIEnv* env, jobject clazz) { - const sp& surface = getSurface(env, clazz); - if (Surface::isValid(surface)) { - if (surface->show() < 0) { - doThrow(env, "java/lang/IllegalArgumentException", NULL); - } - } + const sp& surface(getSurfaceControl(env, clazz)); + if (surface == 0) return; + status_t err = surface->show(); + if (err<0 && err!=NO_INIT) + doThrow(env, "java/lang/IllegalArgumentException", NULL); } static void Surface_freeze( JNIEnv* env, jobject clazz) { - const sp& surface = getSurface(env, clazz); - if (Surface::isValid(surface)) { - if (surface->freeze() < 0) { - doThrow(env, "java/lang/IllegalArgumentException", NULL); - } - } + const sp& surface(getSurfaceControl(env, clazz)); + if (surface == 0) return; + status_t err = surface->freeze(); + if (err<0 && err!=NO_INIT) + doThrow(env, "java/lang/IllegalArgumentException", NULL); } static void Surface_unfreeze( JNIEnv* env, jobject clazz) { - const sp& surface = getSurface(env, clazz); - if (Surface::isValid(surface)) { - if (surface->unfreeze() < 0) { - doThrow(env, "java/lang/IllegalArgumentException", NULL); - } - } + const sp& surface(getSurfaceControl(env, clazz)); + if (surface == 0) return; + status_t err = surface->unfreeze(); + if (err<0 && err!=NO_INIT) + doThrow(env, "java/lang/IllegalArgumentException", NULL); } static void Surface_setFlags( JNIEnv* env, jobject clazz, jint flags, jint mask) { - const sp& surface = getSurface(env, clazz); - if (Surface::isValid(surface)) { - if (surface->setFlags(flags, mask) < 0) { - doThrow(env, "java/lang/IllegalArgumentException", NULL); - } - } + const sp& surface(getSurfaceControl(env, clazz)); + if (surface == 0) return; + status_t err = surface->setFlags(flags, mask); + if (err<0 && err!=NO_INIT) + doThrow(env, "java/lang/IllegalArgumentException", NULL); } static void Surface_setTransparentRegion( JNIEnv* env, jobject clazz, jobject argRegion) { - const sp& surface = getSurface(env, clazz); - if (Surface::isValid(surface)) { - SkRegion* nativeRegion = (SkRegion*)env->GetIntField(argRegion, no.native_region); - if (surface->setTransparentRegionHint(Region(*nativeRegion)) < 0) { - doThrow(env, "java/lang/IllegalArgumentException", NULL); - } - } + const sp& surface(getSurfaceControl(env, clazz)); + if (surface == 0) return; + SkRegion* nativeRegion = (SkRegion*)env->GetIntField(argRegion, no.native_region); + status_t err = surface->setTransparentRegionHint(Region(*nativeRegion)); + if (err<0 && err!=NO_INIT) + doThrow(env, "java/lang/IllegalArgumentException", NULL); } static void Surface_setAlpha( JNIEnv* env, jobject clazz, jfloat alpha) { - const sp& surface = getSurface(env, clazz); - if (Surface::isValid(surface)) { - if (surface->setAlpha(alpha) < 0) { - doThrow(env, "java/lang/IllegalArgumentException", NULL); - } - } + const sp& surface(getSurfaceControl(env, clazz)); + if (surface == 0) return; + status_t err = surface->setAlpha(alpha); + if (err<0 && err!=NO_INIT) + doThrow(env, "java/lang/IllegalArgumentException", NULL); } static void Surface_setMatrix( JNIEnv* env, jobject clazz, jfloat dsdx, jfloat dtdx, jfloat dsdy, jfloat dtdy) { - const sp& surface = getSurface(env, clazz); - if (Surface::isValid(surface)) { - if (surface->setMatrix(dsdx, dtdx, dsdy, dtdy) < 0) { - doThrow(env, "java/lang/IllegalArgumentException", NULL); - } - } + const sp& surface(getSurfaceControl(env, clazz)); + if (surface == 0) return; + status_t err = surface->setMatrix(dsdx, dtdx, dsdy, dtdy); + if (err<0 && err!=NO_INIT) + doThrow(env, "java/lang/IllegalArgumentException", NULL); } static void Surface_setFreezeTint( JNIEnv* env, jobject clazz, jint tint) { - const sp& surface = getSurface(env, clazz); - if (Surface::isValid(surface)) { - if (surface->setFreezeTint(tint) < 0) { - doThrow(env, "java/lang/IllegalArgumentException", NULL); - } - } + const sp& surface(getSurfaceControl(env, clazz)); + if (surface == 0) return; + status_t err = surface->setFreezeTint(tint); + if (err<0 && err!=NO_INIT) + doThrow(env, "java/lang/IllegalArgumentException", NULL); } +// ---------------------------------------------------------------------------- + static void Surface_copyFrom( JNIEnv* env, jobject clazz, jobject other) { @@ -488,16 +506,23 @@ static void Surface_copyFrom( return; } - const sp& surface = getSurface(env, clazz); - const sp& rhs = getSurface(env, other); - if (!Surface::isSameSurface(surface, rhs)) { + /* + * This is used by the WindowManagerService just after constructing + * a Surface and is necessary for returning the Surface reference to + * the caller. At this point, we should only have a SurfaceControl. + * + */ + + const sp& surface = getSurfaceControl(env, clazz); + const sp& rhs = getSurfaceControl(env, other); + if (!SurfaceControl::isSameSurface(surface, rhs)) { // we reassign the surface only if it's a different one // otherwise we would loose our client-side state. - setSurface(env, clazz, rhs); + setSurfaceControl(env, clazz, rhs); + setSurface(env, clazz, rhs->getSurface()); } } - static void Surface_readFromParcel( JNIEnv* env, jobject clazz, jobject argParcel) { @@ -507,9 +532,9 @@ static void Surface_readFromParcel( return; } - const sp& surface = getSurface(env, clazz); - const sp& rhs = Surface::readFromParcel(parcel); - if (!Surface::isSameSurface(surface, rhs)) { + const sp& control(getSurface(env, clazz)); + sp rhs = new Surface(*parcel); + if (!Surface::isSameSurface(control, rhs)) { // we reassign the surface only if it's a different one // otherwise we would loose our client-side state. setSurface(env, clazz, rhs); @@ -527,8 +552,8 @@ static void Surface_writeToParcel( return; } - const sp& surface = getSurface(env, clazz); - Surface::writeToParcel(surface, parcel); + const sp& control(getSurfaceControl(env, clazz)); + SurfaceControl::writeSurfaceToParcel(control, parcel); } // ---------------------------------------------------------------------------- @@ -579,7 +604,8 @@ static JNINativeMethod gSurfaceMethods[] = { void nativeClassInit(JNIEnv* env, jclass clazz) { - so.surface = env->GetFieldID(clazz, "mSurface", "I"); + so.surface = env->GetFieldID(clazz, "mSurface", "I"); + so.surfaceControl = env->GetFieldID(clazz, "mSurfaceControl", "I"); so.saveCount = env->GetFieldID(clazz, "mSaveCount", "I"); so.canvas = env->GetFieldID(clazz, "mCanvas", "Landroid/graphics/Canvas;"); diff --git a/include/ui/Surface.h b/include/ui/Surface.h index 87a11c2824f21..d1ead1d22ad77 100644 --- a/include/ui/Surface.h +++ b/include/ui/Surface.h @@ -75,13 +75,19 @@ private: }; // --------------------------------------------------------------------------- +class Surface; class SurfaceControl : public RefBase { public: static bool isValid(const sp& surface) { - return (surface != 0) && surface->mToken>=0 && surface->mClient!=0; + return (surface != 0) && surface->isValid(); } + bool isValid() { + return mToken>=0 && mClient!=0; + } + static bool isSameSurface( + const sp& lhs, const sp& rhs); SurfaceID ID() const { return mToken; } uint32_t getFlags() const { return mFlags; } @@ -90,10 +96,6 @@ public: // release surface data from java void clear(); - static sp readFromParcel(Parcel* parcel); - static status_t writeToParcel(const sp& surface, Parcel* parcel); - static bool isSameSurface(const sp& lhs, const sp& rhs); - status_t setLayer(int32_t layer); status_t setPosition(int32_t x, int32_t y); status_t setSize(uint32_t w, uint32_t h); @@ -107,7 +109,17 @@ public: status_t setMatrix(float dsdx, float dtdx, float dsdy, float dtdy); status_t setFreezeTint(uint32_t tint); + static status_t writeSurfaceToParcel( + const sp& control, Parcel* parcel); + + sp getSurface() const; + private: + // can't be copied + SurfaceControl& operator = (SurfaceControl& rhs); + SurfaceControl(const SurfaceControl& rhs); + + friend class SurfaceComposerClient; // camera and camcorder need access to the ISurface binder interface for preview @@ -115,22 +127,22 @@ private: friend class MediaRecorder; // mediaplayer needs access to ISurface for display friend class MediaPlayer; + // for testing friend class Test; const sp& getISurface() const { return mSurface; } - // can't be copied - SurfaceControl& operator = (SurfaceControl& rhs); - SurfaceControl(const SurfaceControl& rhs); friend class Surface; - SurfaceControl(const sp& client, + + SurfaceControl( + const sp& client, const sp& surface, const ISurfaceFlingerClient::surface_data_t& data, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, bool owner = true); ~SurfaceControl(); - + status_t validate(per_client_cblk_t const* cblk) const; void destroy(); @@ -142,6 +154,8 @@ private: uint32_t mFlags; const bool mOwner; mutable Mutex mLock; + + mutable sp mSurfaceData; }; // --------------------------------------------------------------------------- @@ -160,45 +174,40 @@ public: uint32_t reserved[2]; }; - static bool isValid(const sp& surface) { - return (surface != 0) && surface->mToken>=0 && surface->mClient!=0; - } - - SurfaceID ID() const { return mToken; } + Surface(const Parcel& data); + + static bool isValid(const sp& surface) { + return (surface != 0) && surface->isValid(); + } + bool isValid() { + return mToken>=0 && mClient!=0; + } + static bool isSameSurface( + const sp& lhs, const sp& rhs); + SurfaceID ID() const { return mToken; } + uint32_t getFlags() const { return mFlags; } + uint32_t getIdentity() const { return mIdentity; } - // release surface data from java - void clear(); status_t lock(SurfaceInfo* info, bool blocking = true); status_t lock(SurfaceInfo* info, Region* dirty, bool blocking = true); status_t unlockAndPost(); - - uint32_t getFlags() const { return mFlags; } // setSwapRectangle() is mainly used by EGL void setSwapRectangle(const Rect& r); const Rect& swapRectangle() const; - static sp readFromParcel(Parcel* parcel); - static status_t writeToParcel(const sp& surface, Parcel* parcel); - static bool isSameSurface(const sp& lhs, const sp& rhs); - - status_t setLayer(int32_t layer); - status_t setPosition(int32_t x, int32_t y); - status_t setSize(uint32_t w, uint32_t h); - status_t hide(); - status_t show(int32_t layer = -1); - status_t freeze(); - status_t unfreeze(); - status_t setFlags(uint32_t flags, uint32_t mask); - status_t setTransparentRegionHint(const Region& transparent); - status_t setAlpha(float alpha=1.0f); - status_t setMatrix(float dsdx, float dtdx, float dsdy, float dtdy); - status_t setFreezeTint(uint32_t tint); - - uint32_t getIdentity() const { return mIdentity; } private: + // can't be copied + Surface& operator = (Surface& rhs); + Surface(const Surface& rhs); + + Surface(const sp& control); + void init(); + ~Surface(); + friend class SurfaceComposerClient; + friend class SurfaceControl; // camera and camcorder need access to the ISurface binder interface for preview friend class Camera; @@ -210,22 +219,8 @@ private: status_t getBufferLocked(int index); - // can't be copied - Surface& operator = (Surface& rhs); - Surface(const Surface& rhs); - - Surface(const sp& client, - const sp& surface, - const ISurfaceFlingerClient::surface_data_t& data, - uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, - bool owner = true); - - Surface(Surface const* rhs); - - ~Surface(); - void destroy(); - + Region dirtyRegion() const; void setDirtyRegion(const Region& region) const; @@ -262,8 +257,6 @@ private: mutable Rect mSwapRectangle; mutable uint8_t mBackbufferIndex; mutable Mutex mSurfaceLock; - - sp mSurfaceControl; }; }; // namespace android diff --git a/include/ui/SurfaceComposerClient.h b/include/ui/SurfaceComposerClient.h index a175a18a0dc31..2a35256d28892 100644 --- a/include/ui/SurfaceComposerClient.h +++ b/include/ui/SurfaceComposerClient.h @@ -62,7 +62,7 @@ public: // surface creation / destruction //! Create a surface - sp createSurface( + sp createSurface( int pid, //!< pid of the process the surfacec is for DisplayID display, //!< Display to create this surface on uint32_t w, //!< width in pixel diff --git a/libs/surfaceflinger/Android.mk b/libs/surfaceflinger/Android.mk index ebd588b3e6aa4..b8077c708cb84 100644 --- a/libs/surfaceflinger/Android.mk +++ b/libs/surfaceflinger/Android.mk @@ -8,7 +8,6 @@ LOCAL_SRC_FILES:= \ BootAnimation.cpp \ BlurFilter.cpp.arm \ BufferAllocator.cpp \ - CPUGauge.cpp \ Layer.cpp \ LayerBase.cpp \ LayerBuffer.cpp \ diff --git a/libs/surfaceflinger/BootAnimation.cpp b/libs/surfaceflinger/BootAnimation.cpp index 4aa8c2c346a9f..519b112285ee3 100644 --- a/libs/surfaceflinger/BootAnimation.cpp +++ b/libs/surfaceflinger/BootAnimation.cpp @@ -128,12 +128,14 @@ status_t BootAnimation::readyToRun() { return -1; // create the native surface - sp s = session()->createSurface(getpid(), 0, dinfo.w, dinfo.h, - PIXEL_FORMAT_RGB_565); + sp control = session()->createSurface( + getpid(), 0, dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565); session()->openTransaction(); - s->setLayer(0x40000000); + control->setLayer(0x40000000); session()->closeTransaction(); + sp s = control->getSurface(); + // initialize opengl and egl const EGLint attribs[] = { EGL_RED_SIZE, 5, EGL_GREEN_SIZE, 6, EGL_BLUE_SIZE, 5, EGL_DEPTH_SIZE, 0, EGL_NONE }; @@ -156,6 +158,7 @@ status_t BootAnimation::readyToRun() { mSurface = surface; mWidth = w; mHeight = h; + mFlingerSurfaceControl = control; mFlingerSurface = s; // initialize GL @@ -176,7 +179,7 @@ bool BootAnimation::threadLoop() { eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroyContext(mDisplay, mContext); eglDestroySurface(mDisplay, mSurface); - mFlingerSurface.clear(); + mFlingerSurfaceControl.clear(); return r; } diff --git a/libs/surfaceflinger/BootAnimation.h b/libs/surfaceflinger/BootAnimation.h index 84846238bc5c7..0e354344f7845 100644 --- a/libs/surfaceflinger/BootAnimation.h +++ b/libs/surfaceflinger/BootAnimation.h @@ -71,6 +71,7 @@ private: EGLDisplay mDisplay; EGLDisplay mContext; EGLDisplay mSurface; + sp mFlingerSurfaceControl; sp mFlingerSurface; Barrier mBarrier; }; diff --git a/libs/surfaceflinger/CPUGauge.cpp b/libs/surfaceflinger/CPUGauge.cpp deleted file mode 100644 index 91dd2362583c3..0000000000000 --- a/libs/surfaceflinger/CPUGauge.cpp +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (C) 2007 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. - */ - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include "CPUGauge.h" - -namespace android { - -CPUGauge::CPUGauge( const sp& composer, - nsecs_t interval, - int clock, - int refclock) - : Thread(false), - mInterval(interval), mClock(clock), mRefClock(refclock), - mReferenceTime(0), - mReferenceWorkingTime(0), mCpuUsage(0), - mRefIdleTime(0), mIdleTime(0) -{ - mFd = fopen("/proc/stat", "r"); - setvbuf(mFd, NULL, _IONBF, 0); - - mSession = SurfaceComposerClient::clientForConnection( - composer->createConnection()->asBinder()); -} - -CPUGauge::~CPUGauge() -{ - fclose(mFd); -} - -const sp& CPUGauge::session() const -{ - return mSession; -} - -void CPUGauge::onFirstRef() -{ - run("CPU Gauge"); -} - -status_t CPUGauge::readyToRun() -{ - LOGI("Starting CPU gauge..."); - return NO_ERROR; -} - -bool CPUGauge::threadLoop() -{ - DisplayInfo dinfo; - session()->getDisplayInfo(0, &dinfo); - sp s(session()->createSurface(getpid(), 0, dinfo.w, 4, PIXEL_FORMAT_OPAQUE)); - session()->openTransaction(); - s->setLayer(INT_MAX); - session()->closeTransaction(); - - static const GGLfixed colors[4][4] = { - { 0x00000, 0x10000, 0x00000, 0x10000 }, - { 0x10000, 0x10000, 0x00000, 0x10000 }, - { 0x10000, 0x00000, 0x00000, 0x10000 }, - { 0x00000, 0x00000, 0x00000, 0x10000 }, - }; - - GGLContext* gl; - gglInit(&gl); - gl->activeTexture(gl, 0); - gl->disable(gl, GGL_TEXTURE_2D); - gl->disable(gl, GGL_BLEND); - - const int w = dinfo.w; - - while(!exitPending()) - { - mLock.lock(); - const float cpuUsage = this->cpuUsage(); - const float totalCpuUsage = 1.0f - idle(); - mLock.unlock(); - - Surface::SurfaceInfo info; - s->lock(&info); - GGLSurface fb; - fb.version = sizeof(GGLSurface); - fb.width = info.w; - fb.height = info.h; - fb.stride = info.s; - fb.format = info.format; - fb.data = (GGLubyte*)info.bits; - - gl->colorBuffer(gl, &fb); - gl->color4xv(gl, colors[3]); - gl->recti(gl, 0, 0, w, 4); - gl->color4xv(gl, colors[2]); // red - gl->recti(gl, 0, 0, int(totalCpuUsage*w), 2); - gl->color4xv(gl, colors[0]); // green - gl->recti(gl, 0, 2, int(cpuUsage*w), 4); - - s->unlockAndPost(); - - usleep(ns2us(mInterval)); - } - - gglUninit(gl); - return false; -} - -void CPUGauge::sample() -{ - if (mLock.tryLock() == NO_ERROR) { - const nsecs_t now = systemTime(mRefClock); - const nsecs_t referenceTime = now-mReferenceTime; - if (referenceTime >= mInterval) { - const float reftime = 1.0f / referenceTime; - const nsecs_t nowWorkingTime = systemTime(mClock); - - char buf[256]; - fgets(buf, 256, mFd); - rewind(mFd); - char *str = buf+5; - char const * const usermode = strsep(&str, " "); (void)usermode; - char const * const usernice = strsep(&str, " "); (void)usernice; - char const * const systemmode = strsep(&str, " ");(void)systemmode; - char const * const idle = strsep(&str, " "); - const nsecs_t nowIdleTime = atoi(idle) * 10000000LL; - mIdleTime = float(nowIdleTime - mRefIdleTime) * reftime; - mRefIdleTime = nowIdleTime; - - const nsecs_t workingTime = nowWorkingTime - mReferenceWorkingTime; - const float newCpuUsage = float(workingTime) * reftime; - if (mCpuUsage != newCpuUsage) { - mCpuUsage = newCpuUsage; - mReferenceWorkingTime = nowWorkingTime; - mReferenceTime = now; - } - } - mLock.unlock(); - } -} - - -}; // namespace android diff --git a/libs/surfaceflinger/CPUGauge.h b/libs/surfaceflinger/CPUGauge.h deleted file mode 100644 index 5bb53c07ff8e8..0000000000000 --- a/libs/surfaceflinger/CPUGauge.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2007 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. - */ - -#ifndef ANDROID_CPUGAUGE_H -#define ANDROID_CPUGAUGE_H - -#include -#include -#include - -#include -#include - -#include - -#include - -namespace android { - -class CPUGauge : public Thread -{ -public: - CPUGauge( const sp& composer, - nsecs_t interval=s2ns(1), - int clock=SYSTEM_TIME_THREAD, - int refclock=SYSTEM_TIME_MONOTONIC); - - ~CPUGauge(); - - const sp& session() const; - - void sample(); - - inline float cpuUsage() const { return mCpuUsage; } - inline float idle() const { return mIdleTime; } - -private: - virtual void onFirstRef(); - virtual status_t readyToRun(); - virtual bool threadLoop(); - - Mutex mLock; - - sp mSession; - - const nsecs_t mInterval; - const int mClock; - const int mRefClock; - - nsecs_t mReferenceTime; - nsecs_t mReferenceWorkingTime; - float mCpuUsage; - nsecs_t mRefIdleTime; - float mIdleTime; - FILE* mFd; -}; - - -}; // namespace android - -#endif // ANDROID_CPUGAUGE_H diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp index a5c1e8fb8671a..a63a28268b999 100644 --- a/libs/surfaceflinger/SurfaceFlinger.cpp +++ b/libs/surfaceflinger/SurfaceFlinger.cpp @@ -45,7 +45,6 @@ #include "clz.h" #include "BufferAllocator.h" -#include "CPUGauge.h" #include "Layer.h" #include "LayerBlur.h" #include "LayerBuffer.h" @@ -179,7 +178,6 @@ SurfaceFlinger::SurfaceFlinger() mFreezeCount(0), mFreezeDisplayTime(0), mDebugRegion(0), - mDebugCpu(0), mDebugFps(0), mDebugBackground(0), mDebugNoBootAnimation(0), @@ -199,8 +197,6 @@ void SurfaceFlinger::init() char value[PROPERTY_VALUE_MAX]; property_get("debug.sf.showupdates", value, "0"); mDebugRegion = atoi(value); - property_get("debug.sf.showcpu", value, "0"); - mDebugCpu = atoi(value); property_get("debug.sf.showbackground", value, "0"); mDebugBackground = atoi(value); property_get("debug.sf.showfps", value, "0"); @@ -209,7 +205,6 @@ void SurfaceFlinger::init() mDebugNoBootAnimation = atoi(value); LOGI_IF(mDebugRegion, "showupdates enabled"); - LOGI_IF(mDebugCpu, "showcpu enabled"); LOGI_IF(mDebugBackground, "showbackground enabled"); LOGI_IF(mDebugFps, "showfps enabled"); LOGI_IF(mDebugNoBootAnimation, "boot animation disabled"); @@ -413,10 +408,6 @@ status_t SurfaceFlinger::readyToRun() mOrientationAnimation = new OrientationAnimation(this); - // start CPU gauge display - if (mDebugCpu) - mCpuGauge = new CPUGauge(this, ms2ns(500)); - // the boot animation! if (mDebugNoBootAnimation == false) mBootAnimation = new BootAnimation(this); @@ -509,11 +500,6 @@ bool SurfaceFlinger::threadLoop() unlockClients(); executeScheduledBroadcasts(); - // sample the cpu gauge - if (UNLIKELY(mDebugCpu)) { - handleDebugCpu(); - } - postFramebuffer(); } else { // pretend we did the post @@ -905,13 +891,6 @@ void SurfaceFlinger::executeScheduledBroadcasts() mLastScheduledBroadcast = 0; } -void SurfaceFlinger::handleDebugCpu() -{ - Mutex::Autolock _l(mDebugLock); - if (mCpuGauge != 0) - mCpuGauge->sample(); -} - void SurfaceFlinger::debugFlashRegions() { if (UNLIKELY(!mDirtyRegion.isRect())) { @@ -1502,20 +1481,7 @@ status_t SurfaceFlinger::onTransact( } int n; switch (code) { - case 1000: // SHOW_CPU - n = data.readInt32(); - mDebugCpu = n ? 1 : 0; - if (mDebugCpu) { - if (mCpuGauge == 0) { - mCpuGauge = new CPUGauge(this, ms2ns(500)); - } - } else { - if (mCpuGauge != 0) { - mCpuGauge->requestExitAndWait(); - Mutex::Autolock _l(mDebugLock); - mCpuGauge.clear(); - } - } + case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE return NO_ERROR; case 1001: // SHOW_FPS n = data.readInt32(); @@ -1540,7 +1506,7 @@ status_t SurfaceFlinger::onTransact( mFreezeCount = data.readInt32(); return NO_ERROR; case 1010: // interrogate. - reply->writeInt32(mDebugCpu); + reply->writeInt32(0); reply->writeInt32(0); reply->writeInt32(mDebugRegion); reply->writeInt32(mDebugBackground); diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h index 57c6ca8503a7a..cb84542f20879 100644 --- a/libs/surfaceflinger/SurfaceFlinger.h +++ b/libs/surfaceflinger/SurfaceFlinger.h @@ -38,7 +38,6 @@ #include "Barrier.h" #include "BootAnimation.h" -#include "CPUGauge.h" #include "Layer.h" #include "Tokenizer.h" @@ -277,7 +276,6 @@ private: bool lockPageFlip(const LayerVector& currentLayers); void unlockPageFlip(const LayerVector& currentLayers); void handleRepaint(); - void handleDebugCpu(); void scheduleBroadcast(Client* client); void executeScheduledBroadcasts(); void postFramebuffer(); @@ -349,13 +347,8 @@ private: friend class OrientationAnimation; OrientationAnimation* mOrientationAnimation; - // access protected by mDebugLock - mutable Mutex mDebugLock; - sp mCpuGauge; - // don't use a lock for these, we don't care int mDebugRegion; - int mDebugCpu; int mDebugFps; int mDebugBackground; int mDebugNoBootAnimation; diff --git a/libs/ui/Surface.cpp b/libs/ui/Surface.cpp index 63699c7fd7b16..cf1b76cd814d5 100644 --- a/libs/ui/Surface.cpp +++ b/libs/ui/Surface.cpp @@ -148,8 +148,8 @@ static void copyBlt(const android_native_buffer_t* dst, // SurfaceControl // ============================================================================ - -SurfaceControl::SurfaceControl(const sp& client, +SurfaceControl::SurfaceControl( + const sp& client, const sp& surface, const ISurfaceFlingerClient::surface_data_t& data, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, @@ -159,7 +159,6 @@ SurfaceControl::SurfaceControl(const sp& client, mFormat(format), mFlags(flags), mOwner(owner) { } - SurfaceControl::~SurfaceControl() { destroy(); @@ -192,133 +191,6 @@ void SurfaceControl::clear() destroy(); } -status_t SurfaceControl::setLayer(int32_t layer) { - const sp& client(mClient); - if (client == 0) return INVALID_OPERATION; - status_t err = validate(client->mControl); - if (err < 0) return err; - return client->setLayer(mToken, layer); -} -status_t SurfaceControl::setPosition(int32_t x, int32_t y) { - const sp& client(mClient); - if (client == 0) return INVALID_OPERATION; - status_t err = validate(client->mControl); - if (err < 0) return err; - return client->setPosition(mToken, x, y); -} -status_t SurfaceControl::setSize(uint32_t w, uint32_t h) { - const sp& client(mClient); - if (client == 0) return INVALID_OPERATION; - status_t err = validate(client->mControl); - if (err < 0) return err; - return client->setSize(mToken, w, h); -} -status_t SurfaceControl::hide() { - const sp& client(mClient); - if (client == 0) return INVALID_OPERATION; - status_t err = validate(client->mControl); - if (err < 0) return err; - return client->hide(mToken); -} -status_t SurfaceControl::show(int32_t layer) { - const sp& client(mClient); - if (client == 0) return INVALID_OPERATION; - status_t err = validate(client->mControl); - if (err < 0) return err; - return client->show(mToken, layer); -} -status_t SurfaceControl::freeze() { - const sp& client(mClient); - if (client == 0) return INVALID_OPERATION; - status_t err = validate(client->mControl); - if (err < 0) return err; - return client->freeze(mToken); -} -status_t SurfaceControl::unfreeze() { - const sp& client(mClient); - if (client == 0) return INVALID_OPERATION; - status_t err = validate(client->mControl); - if (err < 0) return err; - return client->unfreeze(mToken); -} -status_t SurfaceControl::setFlags(uint32_t flags, uint32_t mask) { - const sp& client(mClient); - if (client == 0) return INVALID_OPERATION; - status_t err = validate(client->mControl); - if (err < 0) return err; - return client->setFlags(mToken, flags, mask); -} -status_t SurfaceControl::setTransparentRegionHint(const Region& transparent) { - const sp& client(mClient); - if (client == 0) return INVALID_OPERATION; - status_t err = validate(client->mControl); - if (err < 0) return err; - return client->setTransparentRegionHint(mToken, transparent); -} -status_t SurfaceControl::setAlpha(float alpha) { - const sp& client(mClient); - if (client == 0) return INVALID_OPERATION; - status_t err = validate(client->mControl); - if (err < 0) return err; - return client->setAlpha(mToken, alpha); -} -status_t SurfaceControl::setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) { - const sp& client(mClient); - if (client == 0) return INVALID_OPERATION; - status_t err = validate(client->mControl); - if (err < 0) return err; - return client->setMatrix(mToken, dsdx, dtdx, dsdy, dtdy); -} -status_t SurfaceControl::setFreezeTint(uint32_t tint) { - const sp& client(mClient); - if (client == 0) return INVALID_OPERATION; - status_t err = validate(client->mControl); - if (err < 0) return err; - return client->setFreezeTint(mToken, tint); -} - -sp SurfaceControl::readFromParcel(Parcel* parcel) -{ - sp client; - ISurfaceFlingerClient::surface_data_t data; - sp clientBinder= parcel->readStrongBinder(); - sp surface = interface_cast(parcel->readStrongBinder()); - data.token = parcel->readInt32(); - data.identity = parcel->readInt32(); - PixelFormat format = parcel->readInt32(); - uint32_t flags = parcel->readInt32(); - - if (clientBinder != NULL) - client = SurfaceComposerClient::clientForConnection(clientBinder); - - return new SurfaceControl(client, surface, data, 0, 0, format, flags, false); -} - -status_t SurfaceControl::writeToParcel(const sp& surface, Parcel* parcel) -{ - uint32_t flags=0; - uint32_t format=0; - SurfaceID token = -1; - uint32_t identity = 0; - sp client; - sp sur; - if (SurfaceControl::isValid(surface)) { - token = surface->mToken; - identity = surface->mIdentity; - client = surface->mClient; - sur = surface->mSurface; - format = surface->mFormat; - flags = surface->mFlags; - } - parcel->writeStrongBinder(client!=0 ? client->connection() : NULL); - parcel->writeStrongBinder(sur!=0 ? sur->asBinder() : NULL); - parcel->writeInt32(token); - parcel->writeInt32(identity); - parcel->writeInt32(format); - parcel->writeInt32(flags); - return NO_ERROR; -} - bool SurfaceControl::isSameSurface( const sp& lhs, const sp& rhs) { @@ -327,6 +199,90 @@ bool SurfaceControl::isSameSurface( return lhs->mSurface->asBinder() == rhs->mSurface->asBinder(); } +status_t SurfaceControl::setLayer(int32_t layer) { + const sp& client(mClient); + if (client == 0) return NO_INIT; + status_t err = validate(client->mControl); + if (err < 0) return err; + return client->setLayer(mToken, layer); +} +status_t SurfaceControl::setPosition(int32_t x, int32_t y) { + const sp& client(mClient); + if (client == 0) return NO_INIT; + status_t err = validate(client->mControl); + if (err < 0) return err; + return client->setPosition(mToken, x, y); +} +status_t SurfaceControl::setSize(uint32_t w, uint32_t h) { + const sp& client(mClient); + if (client == 0) return NO_INIT; + status_t err = validate(client->mControl); + if (err < 0) return err; + return client->setSize(mToken, w, h); +} +status_t SurfaceControl::hide() { + const sp& client(mClient); + if (client == 0) return NO_INIT; + status_t err = validate(client->mControl); + if (err < 0) return err; + return client->hide(mToken); +} +status_t SurfaceControl::show(int32_t layer) { + const sp& client(mClient); + if (client == 0) return NO_INIT; + status_t err = validate(client->mControl); + if (err < 0) return err; + return client->show(mToken, layer); +} +status_t SurfaceControl::freeze() { + const sp& client(mClient); + if (client == 0) return NO_INIT; + status_t err = validate(client->mControl); + if (err < 0) return err; + return client->freeze(mToken); +} +status_t SurfaceControl::unfreeze() { + const sp& client(mClient); + if (client == 0) return NO_INIT; + status_t err = validate(client->mControl); + if (err < 0) return err; + return client->unfreeze(mToken); +} +status_t SurfaceControl::setFlags(uint32_t flags, uint32_t mask) { + const sp& client(mClient); + if (client == 0) return NO_INIT; + status_t err = validate(client->mControl); + if (err < 0) return err; + return client->setFlags(mToken, flags, mask); +} +status_t SurfaceControl::setTransparentRegionHint(const Region& transparent) { + const sp& client(mClient); + if (client == 0) return NO_INIT; + status_t err = validate(client->mControl); + if (err < 0) return err; + return client->setTransparentRegionHint(mToken, transparent); +} +status_t SurfaceControl::setAlpha(float alpha) { + const sp& client(mClient); + if (client == 0) return NO_INIT; + status_t err = validate(client->mControl); + if (err < 0) return err; + return client->setAlpha(mToken, alpha); +} +status_t SurfaceControl::setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) { + const sp& client(mClient); + if (client == 0) return NO_INIT; + status_t err = validate(client->mControl); + if (err < 0) return err; + return client->setMatrix(mToken, dsdx, dtdx, dsdy, dtdy); +} +status_t SurfaceControl::setFreezeTint(uint32_t tint) { + const sp& client(mClient); + if (client == 0) return NO_INIT; + status_t err = validate(client->mControl); + if (err < 0) return err; + return client->setFreezeTint(mToken, tint); +} status_t SurfaceControl::validate(per_client_cblk_t const* cblk) const { @@ -353,22 +309,72 @@ status_t SurfaceControl::validate(per_client_cblk_t const* cblk) const return NO_ERROR; } +status_t SurfaceControl::writeSurfaceToParcel( + const sp& control, Parcel* parcel) +{ + uint32_t flags = 0; + uint32_t format = 0; + SurfaceID token = -1; + uint32_t identity = 0; + sp client; + sp sur; + if (SurfaceControl::isValid(control)) { + token = control->mToken; + identity = control->mIdentity; + client = control->mClient; + sur = control->mSurface; + format = control->mFormat; + flags = control->mFlags; + } + parcel->writeStrongBinder(client!=0 ? client->connection() : NULL); + parcel->writeStrongBinder(sur!=0 ? sur->asBinder() : NULL); + parcel->writeInt32(token); + parcel->writeInt32(identity); + parcel->writeInt32(format); + parcel->writeInt32(flags); + return NO_ERROR; +} + +sp SurfaceControl::getSurface() const +{ + Mutex::Autolock _l(mLock); + if (mSurfaceData == 0) { + mSurfaceData = new Surface(const_cast(this)); + } + return mSurfaceData; +} + // ============================================================================ // Surface // ============================================================================ -Surface::Surface(const sp& client, - const sp& surface, - const ISurfaceFlingerClient::surface_data_t& data, - uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, - bool owner) - : mClient(client), mSurface(surface), - mToken(data.token), mIdentity(data.identity), - mFormat(format), mFlags(flags), mOwner(owner) +Surface::Surface(const sp& surface) + : mClient(surface->mClient), mSurface(surface->mSurface), + mToken(surface->mToken), mIdentity(surface->mIdentity), + mFormat(surface->mFormat), mFlags(surface->mFlags), + mOwner(surface->mOwner) { - mSurfaceControl = new SurfaceControl( - client, surface, data, w, h, format, flags, owner); + init(); +} +Surface::Surface(const Parcel& parcel) + : mOwner(false) +{ + sp clientBinder = parcel.readStrongBinder(); + mSurface = interface_cast(parcel.readStrongBinder()); + mToken = parcel.readInt32(); + mIdentity = parcel.readInt32(); + mFormat = parcel.readInt32(); + mFlags = parcel.readInt32(); + + if (clientBinder != NULL) + mClient = SurfaceComposerClient::clientForConnection(clientBinder); + + init(); +} + +void Surface::init() +{ android_native_window_t::connect = connect; android_native_window_t::disconnect = disconnect; android_native_window_t::setSwapInterval = setSwapInterval; @@ -389,6 +395,7 @@ Surface::Surface(const sp& client, const_cast(android_native_window_t::flags) = 0; } + Surface::~Surface() { // this is a client-side operation, the surface is destroyed, unmap @@ -399,13 +406,6 @@ Surface::~Surface() } } - destroy(); -} - -void Surface::destroy() -{ - mSurfaceControl->destroy(); - // clear all references and trigger an IPC now, to make sure things // happen without delay, since these resources are quite heavy. mClient.clear(); @@ -413,11 +413,6 @@ void Surface::destroy() IPCThreadState::self()->flushCommands(); } -void Surface::clear() -{ - mSurfaceControl->clear(); -} - status_t Surface::validate(per_client_cblk_t const* cblk) const { if (mToken<0 || mClient==0) { @@ -443,6 +438,15 @@ status_t Surface::validate(per_client_cblk_t const* cblk) const return NO_ERROR; } + +bool Surface::isSameSurface( + const sp& lhs, const sp& rhs) +{ + if (lhs == 0 || rhs == 0) + return false; + return lhs->mSurface->asBinder() == rhs->mSurface->asBinder(); +} + // ---------------------------------------------------------------------------- int Surface::setSwapRectangle(android_native_window_t* window, @@ -681,55 +685,6 @@ void Surface::setSwapRectangle(const Rect& r) { mSwapRectangle = r; } -sp Surface::readFromParcel(Parcel* parcel) -{ - sp client; - ISurfaceFlingerClient::surface_data_t data; - sp clientBinder= parcel->readStrongBinder(); - sp surface = interface_cast(parcel->readStrongBinder()); - data.token = parcel->readInt32(); - data.identity = parcel->readInt32(); - PixelFormat format = parcel->readInt32(); - uint32_t flags = parcel->readInt32(); - - if (clientBinder != NULL) - client = SurfaceComposerClient::clientForConnection(clientBinder); - - return new Surface(client, surface, data, 0, 0, format, flags, false); -} - -status_t Surface::writeToParcel(const sp& surface, Parcel* parcel) -{ - uint32_t flags=0; - uint32_t format=0; - SurfaceID token = -1; - uint32_t identity = 0; - sp client; - sp sur; - if (Surface::isValid(surface)) { - token = surface->mToken; - identity = surface->mIdentity; - client = surface->mClient; - sur = surface->mSurface; - format = surface->mFormat; - flags = surface->mFlags; - } - parcel->writeStrongBinder(client!=0 ? client->connection() : NULL); - parcel->writeStrongBinder(sur!=0 ? sur->asBinder() : NULL); - parcel->writeInt32(token); - parcel->writeInt32(identity); - parcel->writeInt32(format); - parcel->writeInt32(flags); - return NO_ERROR; -} - -bool Surface::isSameSurface(const sp& lhs, const sp& rhs) -{ - if (lhs == 0 || rhs == 0) - return false; - return lhs->mSurface->asBinder() == rhs->mSurface->asBinder(); -} - status_t Surface::getBufferLocked(int index) { status_t err = NO_MEMORY; @@ -750,45 +705,5 @@ status_t Surface::getBufferLocked(int index) return err; } - - -status_t Surface::setLayer(int32_t layer) { - return mSurfaceControl->setLayer(layer); -} -status_t Surface::setPosition(int32_t x, int32_t y) { - return mSurfaceControl->setPosition(x, y); -} -status_t Surface::setSize(uint32_t w, uint32_t h) { - return mSurfaceControl->setSize(w, h); -} -status_t Surface::hide() { - return mSurfaceControl->hide(); -} -status_t Surface::show(int32_t layer) { - return mSurfaceControl->show(layer); -} -status_t Surface::freeze() { - return mSurfaceControl->freeze(); -} -status_t Surface::unfreeze() { - return mSurfaceControl->unfreeze(); -} -status_t Surface::setFlags(uint32_t flags, uint32_t mask) { - return mSurfaceControl->setFlags(flags, mask); -} -status_t Surface::setTransparentRegionHint(const Region& transparent) { - return mSurfaceControl->setTransparentRegionHint(transparent); -} -status_t Surface::setAlpha(float alpha) { - return mSurfaceControl->setAlpha(alpha); -} -status_t Surface::setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) { - return mSurfaceControl->setMatrix(dsdx, dtdx, dsdy, dtdy); -} -status_t Surface::setFreezeTint(uint32_t tint) { - return mSurfaceControl->setFreezeTint(tint); -} - - }; // namespace android diff --git a/libs/ui/SurfaceComposerClient.cpp b/libs/ui/SurfaceComposerClient.cpp index 4ccd3965c35f6..413167f1ecdfc 100644 --- a/libs/ui/SurfaceComposerClient.cpp +++ b/libs/ui/SurfaceComposerClient.cpp @@ -458,7 +458,7 @@ void SurfaceComposerClient::signalServer() mSignalServer->signal(); } -sp SurfaceComposerClient::createSurface( +sp SurfaceComposerClient::createSurface( int pid, DisplayID display, uint32_t w, @@ -466,14 +466,14 @@ sp SurfaceComposerClient::createSurface( PixelFormat format, uint32_t flags) { - sp result; + sp result; if (mStatus == NO_ERROR) { ISurfaceFlingerClient::surface_data_t data; sp surface = mClient->createSurface(&data, pid, display, w, h, format, flags); if (surface != 0) { if (uint32_t(data.token) < NUM_LAYERS_MAX) { - result = new Surface(this, surface, data, w, h, format, flags); + result = new SurfaceControl(this, surface, data, w, h, format, flags); } } } From 69d62097e8195c947de7e4cdc4a491181aa56e61 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Thu, 16 Apr 2009 20:30:22 -0700 Subject: [PATCH 10/83] cleanup, remove unused fields. Also make sure that we don't systematically allocate a Surface in Surface.java if only a SurfaceControl is needed (Common case). --- core/jni/android_view_Surface.cpp | 25 +++++++++++++++++++++---- include/ui/Surface.h | 5 +---- libs/ui/Surface.cpp | 15 +++++---------- 3 files changed, 27 insertions(+), 18 deletions(-) diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp index c2eb5e83fda14..823fafd98feab 100644 --- a/core/jni/android_view_Surface.cpp +++ b/core/jni/android_view_Surface.cpp @@ -145,8 +145,27 @@ static void setSurfaceControl(JNIEnv* env, jobject clazz, static sp getSurface(JNIEnv* env, jobject clazz) { - Surface* const p = (Surface*)env->GetIntField(clazz, so.surface); - return sp(p); + sp result((Surface*)env->GetIntField(clazz, so.surface)); + if (result == 0) { + /* + * if this method is called from the WindowManager's process, it means + * the client is is not remote, and therefore is allowed to have + * a Surface (data), so we create it here. + * If we don't have a SurfaceControl, it means we're in a different + * process. + */ + + SurfaceControl* const control = + (SurfaceControl*)env->GetIntField(clazz, so.surfaceControl); + if (control) { + result = control->getSurface(); + if (result != 0) { + result->incStrong(clazz); + env->SetIntField(clazz, so.surface, (int)result.get()); + } + } + } + return result; } static void setSurface(JNIEnv* env, jobject clazz, const sp& surface) @@ -510,7 +529,6 @@ static void Surface_copyFrom( * This is used by the WindowManagerService just after constructing * a Surface and is necessary for returning the Surface reference to * the caller. At this point, we should only have a SurfaceControl. - * */ const sp& surface = getSurfaceControl(env, clazz); @@ -519,7 +537,6 @@ static void Surface_copyFrom( // we reassign the surface only if it's a different one // otherwise we would loose our client-side state. setSurfaceControl(env, clazz, rhs); - setSurface(env, clazz, rhs->getSurface()); } } diff --git a/include/ui/Surface.h b/include/ui/Surface.h index d1ead1d22ad77..16d2edb8e223a 100644 --- a/include/ui/Surface.h +++ b/include/ui/Surface.h @@ -138,8 +138,7 @@ private: const sp& client, const sp& surface, const ISurfaceFlingerClient::surface_data_t& data, - uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, - bool owner = true); + uint32_t w, uint32_t h, PixelFormat format, uint32_t flags); ~SurfaceControl(); @@ -152,7 +151,6 @@ private: uint32_t mIdentity; PixelFormat mFormat; uint32_t mFlags; - const bool mOwner; mutable Mutex mLock; mutable sp mSurfaceData; @@ -252,7 +250,6 @@ private: uint32_t mIdentity; PixelFormat mFormat; uint32_t mFlags; - const bool mOwner; mutable Region mDirtyRegion; mutable Rect mSwapRectangle; mutable uint8_t mBackbufferIndex; diff --git a/libs/ui/Surface.cpp b/libs/ui/Surface.cpp index cf1b76cd814d5..47880f55151db 100644 --- a/libs/ui/Surface.cpp +++ b/libs/ui/Surface.cpp @@ -152,13 +152,13 @@ SurfaceControl::SurfaceControl( const sp& client, const sp& surface, const ISurfaceFlingerClient::surface_data_t& data, - uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, - bool owner) + uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) : mClient(client), mSurface(surface), mToken(data.token), mIdentity(data.identity), - mFormat(format), mFlags(flags), mOwner(owner) + mFormat(format), mFlags(flags) { } + SurfaceControl::~SurfaceControl() { destroy(); @@ -166,10 +166,7 @@ SurfaceControl::~SurfaceControl() void SurfaceControl::destroy() { - // Destroy the surface in SurfaceFlinger if we were the owner - // (in any case, a client won't be able to, because it won't have the - // right permission). - if (mOwner && mToken>=0 && mClient!=0) { + if (isValid()) { mClient->destroySurface(mToken); } @@ -351,14 +348,12 @@ sp SurfaceControl::getSurface() const Surface::Surface(const sp& surface) : mClient(surface->mClient), mSurface(surface->mSurface), mToken(surface->mToken), mIdentity(surface->mIdentity), - mFormat(surface->mFormat), mFlags(surface->mFlags), - mOwner(surface->mOwner) + mFormat(surface->mFormat), mFlags(surface->mFlags) { init(); } Surface::Surface(const Parcel& parcel) - : mOwner(false) { sp clientBinder = parcel.readStrongBinder(); mSurface = interface_cast(parcel.readStrongBinder()); From 2b1927f686eaec23a5798966b96aadaee3e2eb85 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Fri, 17 Apr 2009 14:15:18 -0700 Subject: [PATCH 11/83] Squashed commit of the following: commit e5c24638f98162c3b75b4c67a16b510d38e31341 Author: Mathias Agopian Date: Fri Apr 17 14:09:03 2009 -0700 oops forgot this file. commit 282642632d0cb12882eecf42e0fdfb2343275de1 Author: Mathias Agopian Date: Fri Apr 17 14:07:32 2009 -0700 use a helper macro for creating Singleton<>'s static attributes instances. --- include/utils/Singleton.h | 12 ++++++++++++ libs/surfaceflinger/BufferAllocator.cpp | 3 +-- libs/ui/BufferMapper.cpp | 3 +-- libs/ui/Surface.cpp | 3 +-- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/include/utils/Singleton.h b/include/utils/Singleton.h index ee07df11f4795..2f7c7c2dbf258 100644 --- a/include/utils/Singleton.h +++ b/include/utils/Singleton.h @@ -49,6 +49,18 @@ private: static TYPE* sInstance; }; +/* + * use ANDROID_SINGLETON_STATIC_INSTANCE(TYPE) in your implementation file + * (eg: .cpp) to create the static instance of Singleton<>'s attributes, + * and avoid to have a copy of them in each compilation units Singleton + * is used. + */ + +#define ANDROID_SINGLETON_STATIC_INSTANCE(TYPE) \ + template< class TYPE > Mutex Singleton< TYPE >::sLock; \ + template<> TYPE* Singleton< TYPE >::sInstance(0); + + // --------------------------------------------------------------------------- }; // namespace android diff --git a/libs/surfaceflinger/BufferAllocator.cpp b/libs/surfaceflinger/BufferAllocator.cpp index 28fe81002f9e5..fec7c8770584f 100644 --- a/libs/surfaceflinger/BufferAllocator.cpp +++ b/libs/surfaceflinger/BufferAllocator.cpp @@ -34,8 +34,7 @@ namespace android { // --------------------------------------------------------------------------- -template Mutex Singleton::sLock; -template<> BufferAllocator* Singleton::sInstance(0); +ANDROID_SINGLETON_STATIC_INSTANCE( BufferAllocator ) Mutex BufferAllocator::sLock; KeyedVector BufferAllocator::sAllocList; diff --git a/libs/ui/BufferMapper.cpp b/libs/ui/BufferMapper.cpp index e6ca239831fa3..85a029bcc0d28 100644 --- a/libs/ui/BufferMapper.cpp +++ b/libs/ui/BufferMapper.cpp @@ -44,8 +44,7 @@ namespace android { // --------------------------------------------------------------------------- -template Mutex Singleton::sLock; -template<> BufferMapper* Singleton::sInstance(0); +ANDROID_SINGLETON_STATIC_INSTANCE( BufferMapper ) BufferMapper::BufferMapper() : mAllocMod(0) diff --git a/libs/ui/Surface.cpp b/libs/ui/Surface.cpp index 47880f55151db..fb105b346c7e7 100644 --- a/libs/ui/Surface.cpp +++ b/libs/ui/Surface.cpp @@ -50,8 +50,7 @@ namespace android { // SurfaceBuffer // ============================================================================ -template Mutex Singleton::sLock; -template<> SurfaceBuffer* Singleton::sInstance(0); +ANDROID_SINGLETON_STATIC_INSTANCE( SurfaceBuffer ) SurfaceBuffer::SurfaceBuffer() : BASE(), handle(0), mOwner(false) From 6cf0db228ca275dfcda57d79c55e5fa306809632 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Fri, 17 Apr 2009 19:36:26 -0700 Subject: [PATCH 12/83] more Surface lifetime management Surfaces are now destroyed once all references from the clients are gone, but they go through a partial destruction as soon as the window manager requests it. This last part is still buggy. see comments in SurfaceFlinger::destroySurface() --- libs/surfaceflinger/BootAnimation.cpp | 1 + libs/surfaceflinger/Layer.cpp | 17 ++++-- libs/surfaceflinger/Layer.h | 5 +- libs/surfaceflinger/LayerBase.cpp | 27 ++++++---- libs/surfaceflinger/LayerBase.h | 24 ++++++--- libs/surfaceflinger/LayerBuffer.cpp | 21 ++++++-- libs/surfaceflinger/LayerBuffer.h | 12 ++--- libs/surfaceflinger/SurfaceFlinger.cpp | 72 ++++++++++++++++++++++---- libs/surfaceflinger/SurfaceFlinger.h | 6 ++- 9 files changed, 141 insertions(+), 44 deletions(-) diff --git a/libs/surfaceflinger/BootAnimation.cpp b/libs/surfaceflinger/BootAnimation.cpp index 519b112285ee3..ee36b6703a390 100644 --- a/libs/surfaceflinger/BootAnimation.cpp +++ b/libs/surfaceflinger/BootAnimation.cpp @@ -179,6 +179,7 @@ bool BootAnimation::threadLoop() { eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroyContext(mDisplay, mContext); eglDestroySurface(mDisplay, mSurface); + mFlingerSurface.clear(); mFlingerSurfaceControl.clear(); return r; } diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp index 980b78b7a7679..5fdec3f64e3a3 100644 --- a/libs/surfaceflinger/Layer.cpp +++ b/libs/surfaceflinger/Layer.cpp @@ -87,6 +87,12 @@ sp Layer::createSurface() const return mSurface; } +status_t Layer::ditch() +{ + mSurface.clear(); + return NO_ERROR; +} + status_t Layer::setBuffers( Client* client, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) @@ -119,7 +125,7 @@ status_t Layer::setBuffers( Client* client, return err; } } - mSurface = new SurfaceLayer(clientIndex(), this); + mSurface = new SurfaceLayer(mFlinger, clientIndex(), this); return NO_ERROR; } @@ -626,8 +632,13 @@ void Layer::finishPageFlip() // --------------------------------------------------------------------------- -Layer::SurfaceLayer::SurfaceLayer(SurfaceID id, const sp& owner) - : Surface(id, owner->getIdentity(), owner) +Layer::SurfaceLayer::SurfaceLayer(const sp& flinger, + SurfaceID id, const sp& owner) + : Surface(flinger, id, owner->getIdentity(), owner) +{ +} + +Layer::SurfaceLayer::~SurfaceLayer() { } diff --git a/libs/surfaceflinger/Layer.h b/libs/surfaceflinger/Layer.h index dc03d35f848e9..3f3953fb9133e 100644 --- a/libs/surfaceflinger/Layer.h +++ b/libs/surfaceflinger/Layer.h @@ -81,6 +81,7 @@ public: virtual bool needsBlending() const { return mNeedsBlending; } virtual bool isSecure() const { return mSecure; } virtual sp createSurface() const; + virtual status_t ditch(); const LayerBitmap& getBuffer(int i) const { return mBuffers[i]; } LayerBitmap& getBuffer(int i) { return mBuffers[i]; } @@ -108,7 +109,9 @@ private: class SurfaceLayer : public LayerBaseClient::Surface { public: - SurfaceLayer(SurfaceID id, const sp& owner); + SurfaceLayer(const sp& flinger, + SurfaceID id, const sp& owner); + ~SurfaceLayer(); private: virtual sp getBuffer(); diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp index 6da0bf77e10b8..8609225b5908e 100644 --- a/libs/surfaceflinger/LayerBase.cpp +++ b/libs/surfaceflinger/LayerBase.cpp @@ -681,25 +681,32 @@ sp LayerBaseClient::getSurface() sp LayerBaseClient::createSurface() const { - return new Surface(clientIndex(), mIdentity, + return new Surface(mFlinger, clientIndex(), mIdentity, const_cast(this)); } // --------------------------------------------------------------------------- -LayerBaseClient::Surface::Surface(SurfaceID id, int identity, +LayerBaseClient::Surface::Surface( + const sp& flinger, + SurfaceID id, int identity, const sp& owner) - : mToken(id), mIdentity(identity), mOwner(owner) -{ + : mFlinger(flinger), mToken(id), mIdentity(identity), mOwner(owner) +{ } -LayerBaseClient::Surface::~Surface() { - // TODO: We now have a point here were we can clean-up the - // client's mess. - // This is also where surface id should be recycled. - //LOGD("Surface %d, heaps={%p, %p} destroyed", - // mId, mHeap[0].get(), mHeap[1].get()); +LayerBaseClient::Surface::~Surface() +{ + /* + * This is a good place to clean-up all client resources + */ + + // destroy client resources + sp layer = getOwner(); + if (layer != 0) { + mFlinger->destroySurface(layer); + } } sp LayerBaseClient::Surface::getOwner() const { diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h index 2a4e13391c25d..ccff36d36cf1b 100644 --- a/libs/surfaceflinger/LayerBase.h +++ b/libs/surfaceflinger/LayerBase.h @@ -203,14 +203,19 @@ public: /** * isSecure - true if this surface is secure, that is if it prevents - * screenshots or vns servers. + * screenshots or VNC servers. */ virtual bool isSecure() const { return false; } - enum { // flags for doTransaction() - eVisibleRegion = 0x00000002, - eRestartTransaction = 0x00000008 - }; + /** signal this layer that it's not needed any longer */ + virtual status_t ditch() { return NO_ERROR; } + + + + enum { // flags for doTransaction() + eVisibleRegion = 0x00000002, + eRestartTransaction = 0x00000008 + }; inline const State& drawingState() const { return mDrawingState; } @@ -244,7 +249,7 @@ protected: GLint textureName, const GGLSurface& t, GLuint& textureWidth, GLuint& textureHeight) const; - SurfaceFlinger* mFlinger; + sp mFlinger; uint32_t mFlags; // cached during validateVisibility() @@ -316,7 +321,9 @@ public: ISurfaceFlingerClient::surface_data_t* params) const; protected: - Surface(SurfaceID id, int identity, const sp& owner); + Surface(const sp& flinger, + SurfaceID id, int identity, + const sp& owner); virtual ~Surface(); virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags); @@ -330,8 +337,9 @@ public: virtual sp createOverlay(uint32_t w, uint32_t h, int32_t format); - private: + protected: friend class LayerBaseClient; + sp mFlinger; int32_t mToken; int32_t mIdentity; wp mOwner; diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp index f22ff59c6e487..97d6f9748e613 100644 --- a/libs/surfaceflinger/LayerBuffer.cpp +++ b/libs/surfaceflinger/LayerBuffer.cpp @@ -50,10 +50,21 @@ LayerBuffer::~LayerBuffer() { } +void LayerBuffer::onFirstRef() +{ + mSurface = new SurfaceBuffer(mFlinger, clientIndex(), + const_cast(this)); +} + sp LayerBuffer::createSurface() const { - return new SurfaceBuffer(clientIndex(), - const_cast(this)); + return mSurface; +} + +status_t LayerBuffer::ditch() +{ + mSurface.clear(); + return NO_ERROR; } bool LayerBuffer::needsBlending() const { @@ -167,9 +178,9 @@ sp LayerBuffer::clearSource() { // LayerBuffer::SurfaceBuffer // ============================================================================ -LayerBuffer::SurfaceBuffer::SurfaceBuffer(SurfaceID id, - const sp& owner) - : LayerBaseClient::Surface(id, owner->getIdentity(), owner) +LayerBuffer::SurfaceBuffer::SurfaceBuffer(const sp& flinger, + SurfaceID id, const sp& owner) + : LayerBaseClient::Surface(flinger, id, owner->getIdentity(), owner) { } diff --git a/libs/surfaceflinger/LayerBuffer.h b/libs/surfaceflinger/LayerBuffer.h index 2d441217f94e4..5284409c164d2 100644 --- a/libs/surfaceflinger/LayerBuffer.h +++ b/libs/surfaceflinger/LayerBuffer.h @@ -50,7 +50,6 @@ class LayerBuffer : public LayerBaseClient LayerBuffer& mLayer; }; - public: static const uint32_t typeInfo; static const char* const typeID; @@ -61,9 +60,11 @@ public: Client* client, int32_t i); virtual ~LayerBuffer(); + virtual void onFirstRef(); virtual bool needsBlending() const; virtual sp createSurface() const; + virtual status_t ditch(); virtual void onDraw(const Region& clip) const; virtual uint32_t doTransaction(uint32_t flags); virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion); @@ -177,7 +178,8 @@ private: class SurfaceBuffer : public LayerBaseClient::Surface { public: - SurfaceBuffer(SurfaceID id, const sp& owner); + SurfaceBuffer(const sp& flinger, + SurfaceID id, const sp& owner); virtual ~SurfaceBuffer(); virtual status_t registerBuffers(const ISurface::BufferHeap& buffers); @@ -191,12 +193,10 @@ private: return static_cast(Surface::getOwner().get()); } }; - - friend class SurfaceFlinger; - sp getClientSurface() const; - + mutable Mutex mLock; sp mSource; + sp mSurface; bool mInvalidate; bool mNeedsBlending; }; diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp index a63a28268b999..6b2a103d61ce5 100644 --- a/libs/surfaceflinger/SurfaceFlinger.cpp +++ b/libs/surfaceflinger/SurfaceFlinger.cpp @@ -1033,7 +1033,8 @@ status_t SurfaceFlinger::removeLayer_l(const sp& layerBase) ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase); if (index >= 0) { mLayersRemoved = true; - sp layer = LayerBase::dynamicCast< LayerBaseClient* >(layerBase.get()); + sp layer = + LayerBase::dynamicCast< LayerBaseClient* >(layerBase.get()); if (layer != 0) { mLayerMap.removeItem(layer->serverIndex()); } @@ -1041,11 +1042,23 @@ status_t SurfaceFlinger::removeLayer_l(const sp& layerBase) } // it's possible that we don't find a layer, because it might // have been destroyed already -- this is not technically an error - // from the user because there is a race between destroySurface, - // destroyclient and destroySurface-from-a-transaction. + // from the user because there is a race between BClient::destroySurface(), + // ~BClient() and destroySurface-from-a-transaction. return (index == NAME_NOT_FOUND) ? status_t(NO_ERROR) : index; } +status_t SurfaceFlinger::purgatorizeLayer_l(const sp& layerBase) +{ + // First add the layer to the purgatory list, which makes sure it won't + // go away, then remove it from the main list (through a transaction). + ssize_t err = removeLayer_l(layerBase); + if (err >= 0) { + mLayerPurgatory.add(layerBase); + } + return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err; +} + + void SurfaceFlinger::free_resources_l() { // Destroy layers that were removed @@ -1252,14 +1265,53 @@ sp SurfaceFlinger::createPushBuffersSurfaceLocked( return layer; } -status_t SurfaceFlinger::destroySurface(SurfaceID index) +status_t SurfaceFlinger::removeSurface(SurfaceID index) { + /* + * called by the window manager, when a surface should be marked for + * destruction. + */ + + // TODO: here we should make the surface disappear from the screen + // and mark it for removal. however, we can't free anything until all + // client are done. All operations on this surface should return errors. + + status_t err = NAME_NOT_FOUND; + sp layer; + + { // scope for the lock + Mutex::Autolock _l(mStateLock); + layer = getLayerUser_l(index); + err = purgatorizeLayer_l(layer); + if (err == NO_ERROR) { + setTransactionFlags(eTransactionNeeded); + } + } + + if (layer != 0) { + // do this outside of mStateLock + layer->ditch(); + } + return err; +} + +status_t SurfaceFlinger::destroySurface(const sp& layer) +{ + /* + * called by ~ISurface() when all references are gone + */ + + /* FIXME: + * - this can calls ~Layer(), which is wrong because we're not in the + * GL thread, and ~Layer() currently calls OpenGL. + * - ideally we want to release as much GL state as possible after + * purgatorizeLayer_l() has been called and the surface is not in any + * active list. + * - ideally we'd call ~Layer() without mStateLock held + */ + Mutex::Autolock _l(mStateLock); - const sp& layer = getLayerUser_l(index); - status_t err = removeLayer_l(layer); - if (err < 0) - return err; - setTransactionFlags(eTransactionNeeded); + mLayerPurgatory.remove(layer); return NO_ERROR; } @@ -1626,7 +1678,7 @@ sp BClient::createSurface( status_t BClient::destroySurface(SurfaceID sid) { sid |= (mId << 16); // add the client-part to id - return mFlinger->destroySurface(sid); + return mFlinger->removeSurface(sid); } status_t BClient::setState(int32_t count, const layer_state_t* states) diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h index cb84542f20879..b488ab5143f55 100644 --- a/libs/surfaceflinger/SurfaceFlinger.h +++ b/libs/surfaceflinger/SurfaceFlinger.h @@ -203,7 +203,8 @@ private: Client* client, DisplayID display, int32_t id, uint32_t w, uint32_t h, uint32_t flags); - status_t destroySurface(SurfaceID surface_id); + status_t removeSurface(SurfaceID surface_id); + status_t destroySurface(const sp& layer); status_t setClientState(ClientID cid, int32_t count, const layer_state_t* states); @@ -287,6 +288,7 @@ private: sp getLayerUser_l(SurfaceID index) const; status_t addLayer_l(const sp& layer); status_t removeLayer_l(const sp& layer); + status_t purgatorizeLayer_l(const sp& layer); void free_resources_l(); uint32_t getTransactionFlags(uint32_t flags); @@ -315,7 +317,9 @@ private: volatile int32_t mTransactionFlags; volatile int32_t mTransactionCount; Condition mTransactionCV; + SortedVector< sp > mLayerPurgatory; + // protected by mStateLock (but we could use another lock) Tokenizer mTokens; DefaultKeyedVector mClientsMap; From 6ead5d9f140529edfb744584fa5427b84b4dc13a Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Mon, 20 Apr 2009 19:39:12 -0700 Subject: [PATCH 13/83] a brand new MessageQueue for SurfaceFlinger. --- include/private/ui/SurfaceFlingerSynchro.h | 28 --- include/utils/MemoryDealer.h | 15 +- libs/surfaceflinger/Android.mk | 1 + libs/surfaceflinger/MessageQueue.cpp | 161 +++++++++++++++ libs/surfaceflinger/MessageQueue.h | 224 +++++++++++++++++++++ libs/surfaceflinger/SurfaceFlinger.cpp | 75 ++++--- libs/surfaceflinger/SurfaceFlinger.h | 29 +-- libs/ui/SurfaceFlingerSynchro.cpp | 81 -------- 8 files changed, 453 insertions(+), 161 deletions(-) create mode 100644 libs/surfaceflinger/MessageQueue.cpp create mode 100644 libs/surfaceflinger/MessageQueue.h diff --git a/include/private/ui/SurfaceFlingerSynchro.h b/include/private/ui/SurfaceFlingerSynchro.h index ff91b61b10608..7386d337675c6 100644 --- a/include/private/ui/SurfaceFlingerSynchro.h +++ b/include/private/ui/SurfaceFlingerSynchro.h @@ -21,7 +21,6 @@ #include #include #include -#include #include namespace android { @@ -31,7 +30,6 @@ class SurfaceFlinger; class SurfaceFlingerSynchro { public: - // client constructor SurfaceFlingerSynchro(const sp& flinger); ~SurfaceFlingerSynchro(); @@ -40,34 +38,8 @@ public: status_t signal(); private: - class Barrier { - public: - Barrier(); - ~Barrier(); - void open(); - void close(); - void waitAndClose(); - status_t waitAndClose(nsecs_t timeout); - private: - enum { OPENED, CLOSED }; - mutable Mutex lock; - mutable Condition cv; - volatile int state; - }; - friend class SurfaceFlinger; - - // server constructor - SurfaceFlingerSynchro(); - - void open(); - - // wait until there is some work to do - status_t wait(); - status_t wait(nsecs_t timeout); - sp mSurfaceComposer; - Barrier mBarrier; }; }; // namespace android diff --git a/include/utils/MemoryDealer.h b/include/utils/MemoryDealer.h index 454b6270e4bd1..79d7883af153e 100644 --- a/include/utils/MemoryDealer.h +++ b/include/utils/MemoryDealer.h @@ -117,13 +117,22 @@ public: mFirst = mLast = newNode; newNode->prev = newNode->next = 0; } else { - insertBefore(mFirst, newNode); + newNode->prev = 0; + newNode->next = mFirst; + mFirst->prev = newNode; + mFirst = newNode; } } void insertTail(NODE* newNode) { - if (mLast == 0) insertBeginning(newNode); - else insertAfter(mLast, newNode); + if (mLast == 0) { + insertHead(newNode); + } else { + newNode->prev = mLast; + newNode->next = 0; + mLast->next = newNode; + mLast = newNode; + } } NODE* remove(NODE* node) { diff --git a/libs/surfaceflinger/Android.mk b/libs/surfaceflinger/Android.mk index b8077c708cb84..2b360d620595b 100644 --- a/libs/surfaceflinger/Android.mk +++ b/libs/surfaceflinger/Android.mk @@ -16,6 +16,7 @@ LOCAL_SRC_FILES:= \ LayerDim.cpp \ LayerOrientationAnim.cpp \ LayerOrientationAnimRotate.cpp \ + MessageQueue.cpp \ OrientationAnimation.cpp \ SurfaceFlinger.cpp \ Tokenizer.cpp \ diff --git a/libs/surfaceflinger/MessageQueue.cpp b/libs/surfaceflinger/MessageQueue.cpp new file mode 100644 index 0000000000000..907938300ff13 --- /dev/null +++ b/libs/surfaceflinger/MessageQueue.cpp @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2009 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. + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include "MessageQueue.h" + +namespace android { + +// --------------------------------------------------------------------------- + +MessageQueue::MessageQueue() +{ + mInvalidateMessage = new MessageBase(INVALIDATE); +} + +MessageQueue::~MessageQueue() +{ +} + +MessageList::NODE_PTR MessageQueue::waitMessage(nsecs_t timeout) +{ + MessageList::NODE_PTR result; + bool again; + do { + const nsecs_t timeoutTime = systemTime() + timeout; + while (true) { + Mutex::Autolock _l(mLock); + nsecs_t now = systemTime(); + nsecs_t nextEventTime = -1; + + // invalidate messages are always handled first + if (mInvalidate) { + mInvalidate = false; + mInvalidateMessage->when = now; + result = mInvalidateMessage; + break; + } + + result = mMessages.head(); + + if (result != 0) { + if (result->when <= now) { + // there is a message to deliver + mMessages.remove(result); + result->detach(); + break; + } + if (timeout>=0 && timeoutTime < now) { + // we timed-out, return a NULL message + result = 0; + break; + } + nextEventTime = result->when; + result = 0; + } + + if (timeout >= 0 && nextEventTime > 0) { + if (nextEventTime > timeoutTime) { + nextEventTime = timeoutTime; + } + } + + if (nextEventTime >= 0) { + //LOGD("nextEventTime = %lld ms", nextEventTime); + if (nextEventTime > 0) { + // we're about to wait, flush the binder command buffer + IPCThreadState::self()->flushCommands(); + mCondition.wait(mLock, nextEventTime); + } + } else { + //LOGD("going to wait"); + // we're about to wait, flush the binder command buffer + IPCThreadState::self()->flushCommands(); + mCondition.wait(mLock); + } + } + // here we're not holding the lock anymore + + if (result == 0) + break; + + again = result->handler(); + if (again) { + // the message has been processed. release our reference to it + // without holding the lock. + result = 0; + } + + } while (again); + return result; +} + +status_t MessageQueue::postMessage( + const MessageList::NODE_PTR& message, nsecs_t relTime, uint32_t flags) +{ + return queueMessage(message, relTime, flags); +} + +status_t MessageQueue::invalidate() { + Mutex::Autolock _l(mLock); + mInvalidate = true; + mCondition.signal(); + return NO_ERROR; +} + +status_t MessageQueue::queueMessage( + const MessageList::NODE_PTR& message, nsecs_t relTime, uint32_t flags) +{ + Mutex::Autolock _l(mLock); + message->when = systemTime() + relTime; + mMessages.insert(message); + + //LOGD("MessageQueue::queueMessage time = %lld ms", message->when); + //dumpLocked(message); + + mCondition.signal(); + return NO_ERROR; +} + +void MessageQueue::dump(const MessageList::NODE_PTR& message) +{ + Mutex::Autolock _l(mLock); + dumpLocked(message); +} + +void MessageQueue::dumpLocked(const MessageList::NODE_PTR& message) +{ + MessageList::NODE_PTR l(mMessages.head()); + int c = 0; + while (l != 0) { + const char tick = (l == message) ? '>' : ' '; + LOGD("%c %d: msg{.what=%08x, when=%lld}", tick, c, l->what, l->when); + l = l->getNext(); + c++; + } +} + +// --------------------------------------------------------------------------- + +}; // namespace android diff --git a/libs/surfaceflinger/MessageQueue.h b/libs/surfaceflinger/MessageQueue.h new file mode 100644 index 0000000000000..d894fe28d43b5 --- /dev/null +++ b/libs/surfaceflinger/MessageQueue.h @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2009 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. + */ + +#ifndef ANDROID_MESSAGE_QUEUE_H +#define ANDROID_MESSAGE_QUEUE_H + +#include +#include +#include + +#include +#include + + +namespace android { + +// --------------------------------------------------------------------------- + +template +class DoublyLinkedList +{ +protected: + typedef NODE_PTR_TYPE NODE_PTR; + + NODE_PTR mFirst; + NODE_PTR mLast; + +public: + class Node { + friend class DoublyLinkedList; + mutable NODE_PTR next; + mutable NODE_PTR prev; + public: + typedef NODE_PTR PTR; + inline NODE_PTR getNext() const { return next; } + inline NODE_PTR getPrev() const { return prev; } + void detach() { + prev = 0; + next = 0; + } + }; + + DoublyLinkedList() : mFirst(0), mLast(0) { } + ~DoublyLinkedList() { } + + bool isEmpty() const { return mFirst == 0; } + const NODE_PTR& head() const { return mFirst; } + const NODE_PTR& tail() const { return mLast; } + const NODE_PTR& head() { return mFirst; } + const NODE_PTR& tail() { return mLast; } + + void insertAfter(const NODE_PTR& node, const NODE_PTR& newNode) { + newNode->prev = node; + newNode->next = node->next; + if (node->next == 0) mLast = newNode; + else node->next->prev = newNode; + node->next = newNode; + } + + void insertBefore(const NODE_PTR& node, const NODE_PTR& newNode) { + newNode->prev = node->prev; + newNode->next = node; + if (node->prev == 0) mFirst = newNode; + else node->prev->next = newNode; + node->prev = newNode; + } + + void insertHead(const NODE_PTR& newNode) { + if (mFirst == 0) { + mFirst = mLast = newNode; + newNode->prev = newNode->next = 0; + } else { + newNode->prev = 0; + newNode->next = mFirst; + mFirst->prev = newNode; + mFirst = newNode; + } + } + + void insertTail(const NODE_PTR& newNode) { + if (mLast == 0) { + insertHead(newNode); + } else { + newNode->prev = mLast; + newNode->next = 0; + mLast->next = newNode; + mLast = newNode; + } + } + + NODE_PTR remove(const NODE_PTR& node) { + if (node->prev == 0) mFirst = node->next; + else node->prev->next = node->next; + if (node->next == 0) mLast = node->prev; + else node->next->prev = node->prev; + return node; + } +}; + +// --------------------------------------------------------------------------- + +template +class SortedList : protected DoublyLinkedList< NODE_PTR_TYPE > +{ + typedef DoublyLinkedList< NODE_PTR_TYPE > forward; +public: + typedef NODE_PTR_TYPE NODE_PTR; + inline bool isEmpty() const { return forward::isEmpty(); } + inline const NODE_PTR& head() const { return forward::head(); } + inline const NODE_PTR& tail() const { return forward::tail(); } + inline const NODE_PTR& head() { return forward::head(); } + inline const NODE_PTR& tail() { return forward::tail(); } + inline NODE_PTR remove(const NODE_PTR& node) { return forward::remove(node); } + void insert(const NODE_PTR& node) { + NODE_PTR l(head()); + while (l != 0) { + if (*node < *l) { + insertBefore(l, node); + return; + } + l = l->getNext(); + } + insertTail(node); + } +}; + +// ============================================================================ + +class MessageBase : + public LightRefBase, + public DoublyLinkedList< sp >::Node +{ +public: + nsecs_t when; + uint32_t what; + int32_t arg0; + + MessageBase(uint32_t what=0, int32_t arg0=0) + : when(0), what(what), arg0(arg0) { } + + // return true if message has a handler + virtual bool handler() { return false; } + +protected: + virtual ~MessageBase() { } + +private: + friend class LightRefBase; +}; + +inline bool operator < (const MessageBase& lhs, const MessageBase& rhs) { + return lhs.when < rhs.when; +} + +// --------------------------------------------------------------------------- + +/* + * MessageList is a sorted list of sp + */ + +typedef SortedList< MessageBase::Node::PTR > MessageList; + +// --------------------------------------------------------------------------- + +class MessageQueue +{ +public: + + // this is a work-around the multichar constant warning. A macro would + // work too, but would pollute the namespace. + template + struct WHAT { + static const uint32_t Value = + (uint32_t(a&0xff)<<24)|(uint32_t(b&0xff)<<16)| + (uint32_t(c&0xff)<<8)|uint32_t(d&0xff); + }; + + MessageQueue(); + ~MessageQueue(); + + // pre-defined messages + enum { + INVALIDATE = WHAT<'_','p','d','t'>::Value + }; + + MessageList::NODE_PTR waitMessage(nsecs_t timeout = -1); + + status_t postMessage(const MessageList::NODE_PTR& message, + nsecs_t reltime=0, uint32_t flags = 0); + + status_t invalidate(); + + void dump(const MessageList::NODE_PTR& message); + +private: + status_t queueMessage(const MessageList::NODE_PTR& message, + nsecs_t reltime, uint32_t flags); + void dumpLocked(const MessageList::NODE_PTR& message); + + Mutex mLock; + Condition mCondition; + MessageList mMessages; + bool mInvalidate; + MessageList::NODE_PTR mInvalidateMessage; +}; + +// --------------------------------------------------------------------------- + +}; // namespace android + +#endif /* ANDROID_MESSAGE_QUEUE_H */ diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp index 6b2a103d61ce5..1b6d6def59c53 100644 --- a/libs/surfaceflinger/SurfaceFlinger.cpp +++ b/libs/surfaceflinger/SurfaceFlinger.cpp @@ -56,7 +56,6 @@ #include "DisplayHardware/DisplayHardware.h" - #define DISPLAY_COUNT 1 namespace android { @@ -181,8 +180,6 @@ SurfaceFlinger::SurfaceFlinger() mDebugFps(0), mDebugBackground(0), mDebugNoBootAnimation(0), - mSyncObject(), - mDeplayedTransactionPending(0), mConsoleSignals(0), mSecureFrameBuffer(0) { @@ -423,45 +420,53 @@ status_t SurfaceFlinger::readyToRun() void SurfaceFlinger::waitForEvent() { - // wait for something to do - if (UNLIKELY(isFrozen())) { - // wait 5 seconds - const nsecs_t freezeDisplayTimeout = ms2ns(5000); - const nsecs_t now = systemTime(); - if (mFreezeDisplayTime == 0) { - mFreezeDisplayTime = now; + while (true) { + nsecs_t timeout = -1; + if (UNLIKELY(isFrozen())) { + // wait 5 seconds + const nsecs_t freezeDisplayTimeout = ms2ns(5000); + const nsecs_t now = systemTime(); + if (mFreezeDisplayTime == 0) { + mFreezeDisplayTime = now; + } + nsecs_t waitTime = freezeDisplayTimeout - (now - mFreezeDisplayTime); + timeout = waitTime>0 ? waitTime : 0; } - nsecs_t waitTime = freezeDisplayTimeout - (now - mFreezeDisplayTime); - int err = (waitTime > 0) ? mSyncObject.wait(waitTime) : TIMED_OUT; - if (err != NO_ERROR) { + + MessageList::NODE_PTR msg = mEventQueue.waitMessage(timeout); + if (msg != 0) { + mFreezeDisplayTime = 0; + switch (msg->what) { + case MessageQueue::INVALIDATE: + // invalidate message, just return to the main loop + return; + } + } else { + // we timed out if (isFrozen()) { // we timed out and are still frozen LOGW("timeout expired mFreezeDisplay=%d, mFreezeCount=%d", mFreezeDisplay, mFreezeCount); mFreezeCount = 0; mFreezeDisplay = false; + return; } } - } else { - mFreezeDisplayTime = 0; - mSyncObject.wait(); } } void SurfaceFlinger::signalEvent() { - mSyncObject.open(); + mEventQueue.invalidate(); } void SurfaceFlinger::signal() const { - mSyncObject.open(); + // this is the IPC call + const_cast(this)->signalEvent(); } void SurfaceFlinger::signalDelayedEvent(nsecs_t delay) { - if (android_atomic_or(1, &mDeplayedTransactionPending) == 0) { - sp delayedEvent(new DelayedTransaction(this, delay)); - delayedEvent->run("DelayedeEvent", PRIORITY_URGENT_DISPLAY); - } + mEventQueue.postMessage( new MessageBase(MessageQueue::INVALIDATE), delay); } // ---------------------------------------------------------------------------- @@ -1302,16 +1307,32 @@ status_t SurfaceFlinger::destroySurface(const sp& layer) */ /* FIXME: - * - this can calls ~Layer(), which is wrong because we're not in the - * GL thread, and ~Layer() currently calls OpenGL. * - ideally we want to release as much GL state as possible after * purgatorizeLayer_l() has been called and the surface is not in any * active list. - * - ideally we'd call ~Layer() without mStateLock held */ - Mutex::Autolock _l(mStateLock); - mLayerPurgatory.remove(layer); + class MessageDestroySurface : public MessageBase { + sp flinger; + sp layer; + public: + MessageDestroySurface(const sp& flinger, + const sp& layer) + : MessageBase(0), flinger(flinger), layer(layer) { + } + ~MessageDestroySurface() { + //LOGD("~MessageDestroySurface, layer=%p", layer.get()); + } + virtual bool handler() { + //LOGD("MessageDestroySurface handler, layer=%p", layer.get()); + Mutex::Autolock _l(flinger->mStateLock); + flinger->mLayerPurgatory.remove(layer); + return true; + } + }; + + mEventQueue.postMessage( new MessageDestroySurface(this, layer) ); + return NO_ERROR; } diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h index b488ab5143f55..76e40a1222e2c 100644 --- a/libs/surfaceflinger/SurfaceFlinger.h +++ b/libs/surfaceflinger/SurfaceFlinger.h @@ -34,13 +34,14 @@ #include #include -#include #include "Barrier.h" #include "BootAnimation.h" #include "Layer.h" #include "Tokenizer.h" +#include "MessageQueue.h" + struct copybit_device_t; struct overlay_device_t; @@ -235,25 +236,6 @@ private: uint8_t freezeDisplay; }; - class DelayedTransaction : public Thread - { - friend class SurfaceFlinger; - sp mFlinger; - nsecs_t mDelay; - public: - DelayedTransaction(const sp& flinger, nsecs_t delay) - : Thread(false), mFlinger(flinger), mDelay(delay) { - } - virtual bool threadLoop() { - usleep(mDelay / 1000); - if (android_atomic_and(~1, - &mFlinger->mDeplayedTransactionPending) == 1) { - mFlinger->signalEvent(); - } - return false; - } - }; - virtual bool threadLoop(); virtual status_t readyToRun(); virtual void onFirstRef(); @@ -310,6 +292,11 @@ private: void debugShowFPS() const; void drawWormhole() const; + + mutable MessageQueue mEventQueue; + + + // access must be protected by mStateLock mutable Mutex mStateLock; State mCurrentState; @@ -359,8 +346,6 @@ private: // these are thread safe mutable Barrier mReadyToRunBarrier; - mutable SurfaceFlingerSynchro mSyncObject; - volatile int32_t mDeplayedTransactionPending; // atomic variables enum { diff --git a/libs/ui/SurfaceFlingerSynchro.cpp b/libs/ui/SurfaceFlingerSynchro.cpp index 5cd9755cc8a64..c81db71a81283 100644 --- a/libs/ui/SurfaceFlingerSynchro.cpp +++ b/libs/ui/SurfaceFlingerSynchro.cpp @@ -14,19 +14,7 @@ * limitations under the License. */ -#define LOG_TAG "SurfaceFlingerSynchro" - #include -#include -#include -#include -#include -#include -#include -#include - -#include -#include #include @@ -34,61 +22,10 @@ namespace android { // --------------------------------------------------------------------------- -SurfaceFlingerSynchro::Barrier::Barrier() - : state(CLOSED) { -} - -SurfaceFlingerSynchro::Barrier::~Barrier() { -} - -void SurfaceFlingerSynchro::Barrier::open() { - asm volatile ("":::"memory"); - Mutex::Autolock _l(lock); - state = OPENED; - cv.broadcast(); -} - -void SurfaceFlingerSynchro::Barrier::close() { - Mutex::Autolock _l(lock); - state = CLOSED; -} - -void SurfaceFlingerSynchro::Barrier::waitAndClose() -{ - Mutex::Autolock _l(lock); - while (state == CLOSED) { - // we're about to wait, flush the binder command buffer - IPCThreadState::self()->flushCommands(); - cv.wait(lock); - } - state = CLOSED; -} - -status_t SurfaceFlingerSynchro::Barrier::waitAndClose(nsecs_t timeout) -{ - Mutex::Autolock _l(lock); - while (state == CLOSED) { - // we're about to wait, flush the binder command buffer - IPCThreadState::self()->flushCommands(); - int err = cv.waitRelative(lock, timeout); - if (err != 0) - return err; - } - state = CLOSED; - return NO_ERROR; -} - -// --------------------------------------------------------------------------- - SurfaceFlingerSynchro::SurfaceFlingerSynchro(const sp& flinger) : mSurfaceComposer(flinger) { } - -SurfaceFlingerSynchro::SurfaceFlingerSynchro() -{ -} - SurfaceFlingerSynchro::~SurfaceFlingerSynchro() { } @@ -99,24 +36,6 @@ status_t SurfaceFlingerSynchro::signal() return NO_ERROR; } -status_t SurfaceFlingerSynchro::wait() -{ - mBarrier.waitAndClose(); - return NO_ERROR; -} - -status_t SurfaceFlingerSynchro::wait(nsecs_t timeout) -{ - if (timeout == 0) - return SurfaceFlingerSynchro::wait(); - return mBarrier.waitAndClose(timeout); -} - -void SurfaceFlingerSynchro::open() -{ - mBarrier.open(); -} - // --------------------------------------------------------------------------- }; // namespace android From a3aa6c9aa96873a70e2ff3170218a275f503520e Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Wed, 22 Apr 2009 15:23:34 -0700 Subject: [PATCH 14/83] Surfaces are now destroyed properly in SurfaceFlinger. First, the window manager tells us when a surface is no longer needed. At this point, several things happen: - the surface is removed from the active/visible list - it is added to a purgatory list, where it waits for all clients to release their reference - it destroys all data/state that can be spared Later, when all clients are done, the remains of the Surface are disposed off: it is removed from the purgatory and destroyed. In particular its gralloc buffers are destroyed at that point (when we're sure nobody is using them anymore). --- libs/surfaceflinger/Layer.cpp | 10 ++++ libs/surfaceflinger/Layer.h | 3 +- libs/surfaceflinger/LayerBase.h | 3 +- libs/surfaceflinger/MessageQueue.h | 5 +- libs/surfaceflinger/SurfaceFlinger.cpp | 77 ++++++++++++-------------- 5 files changed, 51 insertions(+), 47 deletions(-) diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp index 5fdec3f64e3a3..4e3f3a9b84357 100644 --- a/libs/surfaceflinger/Layer.cpp +++ b/libs/surfaceflinger/Layer.cpp @@ -60,16 +60,24 @@ Layer::Layer(SurfaceFlinger* flinger, DisplayID display, Client* c, int32_t i) } Layer::~Layer() +{ + destroy(); + // the actual buffers will be destroyed here +} + +void Layer::destroy() { for (int i=0 ; igraphicPlane(0).getEGLDisplay()); eglDestroyImageKHR(dpy, mTextures[i].image); + mTextures[i].image = EGL_NO_IMAGE_KHR; } } } @@ -89,7 +97,9 @@ sp Layer::createSurface() const status_t Layer::ditch() { + // the layer is not on screen anymore. free as much resources as possible mSurface.clear(); + destroy(); return NO_ERROR; } diff --git a/libs/surfaceflinger/Layer.h b/libs/surfaceflinger/Layer.h index 3f3953fb9133e..e16d9f40d9538 100644 --- a/libs/surfaceflinger/Layer.h +++ b/libs/surfaceflinger/Layer.h @@ -104,7 +104,8 @@ private: status_t resize(int32_t index, uint32_t w, uint32_t h, const char* what); Region post(uint32_t* oldState, bool& recomputeVisibleRegions); sp peekBuffer(); - + void destroy(); + class SurfaceLayer : public LayerBaseClient::Surface { diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h index ccff36d36cf1b..2ab6f6721bf35 100644 --- a/libs/surfaceflinger/LayerBase.h +++ b/libs/surfaceflinger/LayerBase.h @@ -207,7 +207,8 @@ public: */ virtual bool isSecure() const { return false; } - /** signal this layer that it's not needed any longer */ + /** signal this layer that it's not needed any longer. called from the + * main thread */ virtual status_t ditch() { return NO_ERROR; } diff --git a/libs/surfaceflinger/MessageQueue.h b/libs/surfaceflinger/MessageQueue.h index d894fe28d43b5..c118897dd699e 100644 --- a/libs/surfaceflinger/MessageQueue.h +++ b/libs/surfaceflinger/MessageQueue.h @@ -148,8 +148,9 @@ public: uint32_t what; int32_t arg0; - MessageBase(uint32_t what=0, int32_t arg0=0) - : when(0), what(what), arg0(arg0) { } + MessageBase() : when(0), what(0), arg0(0) { } + MessageBase(uint32_t what, int32_t arg0=0) + : when(0), what(what), arg0(arg0) { } // return true if message has a handler virtual bool handler() { return false; } diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp index 1b6d6def59c53..993a6ae02a2de 100644 --- a/libs/surfaceflinger/SurfaceFlinger.cpp +++ b/libs/surfaceflinger/SurfaceFlinger.cpp @@ -639,16 +639,26 @@ void SurfaceFlinger::handleTransaction(uint32_t transactionFlags) mFreezeDisplay = mCurrentState.freezeDisplay; } + if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) { + // layers have been added + mVisibleRegionsDirty = true; + } + // some layers might have been removed, so // we need to update the regions they're exposing. if (mLayersRemoved) { mVisibleRegionsDirty = true; - } - - const LayerVector& currentLayers = mCurrentState.layersSortedByZ; - if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) { - // layers have been added - mVisibleRegionsDirty = true; + const LayerVector& previousLayers(mDrawingState.layersSortedByZ); + const ssize_t count = previousLayers.size(); + for (ssize_t i=0 ; i& layer(previousLayers[i]); + if (currentLayers.indexOf( layer ) < 0) { + // this layer is not visible anymore + // FIXME: would be better to call without the lock held + //LOGD("ditching layer %p", layer.get()); + layer->ditch(); + } + } } // get rid of all resources we don't need anymore @@ -1275,27 +1285,17 @@ status_t SurfaceFlinger::removeSurface(SurfaceID index) /* * called by the window manager, when a surface should be marked for * destruction. + * + * The surface is removed from the current and drawing lists, but placed + * in the purgatory queue, so it's not destroyed right-away (we need + * to wait for all client's references to go away first). */ - - // TODO: here we should make the surface disappear from the screen - // and mark it for removal. however, we can't free anything until all - // client are done. All operations on this surface should return errors. - - status_t err = NAME_NOT_FOUND; - sp layer; - - { // scope for the lock - Mutex::Autolock _l(mStateLock); - layer = getLayerUser_l(index); - err = purgatorizeLayer_l(layer); - if (err == NO_ERROR) { - setTransactionFlags(eTransactionNeeded); - } - } - if (layer != 0) { - // do this outside of mStateLock - layer->ditch(); + Mutex::Autolock _l(mStateLock); + sp layer = getLayerUser_l(index); + status_t err = purgatorizeLayer_l(layer); + if (err == NO_ERROR) { + setTransactionFlags(eTransactionNeeded); } return err; } @@ -1304,35 +1304,26 @@ status_t SurfaceFlinger::destroySurface(const sp& layer) { /* * called by ~ISurface() when all references are gone - */ - - /* FIXME: - * - ideally we want to release as much GL state as possible after - * purgatorizeLayer_l() has been called and the surface is not in any - * active list. + * + * the surface must be removed from purgatory from the main thread + * since its dtor must run from there (b/c of OpenGL ES). */ class MessageDestroySurface : public MessageBase { - sp flinger; + SurfaceFlinger* flinger; sp layer; public: - MessageDestroySurface(const sp& flinger, - const sp& layer) - : MessageBase(0), flinger(flinger), layer(layer) { - } - ~MessageDestroySurface() { - //LOGD("~MessageDestroySurface, layer=%p", layer.get()); - } + MessageDestroySurface( + SurfaceFlinger* flinger, const sp& layer) + : flinger(flinger), layer(layer) { } virtual bool handler() { - //LOGD("MessageDestroySurface handler, layer=%p", layer.get()); Mutex::Autolock _l(flinger->mStateLock); - flinger->mLayerPurgatory.remove(layer); + ssize_t idx = flinger->mLayerPurgatory.remove(layer); + LOGE_IF(idx<0, "layer=%p is not in the purgatory list", layer.get()); return true; } }; - mEventQueue.postMessage( new MessageDestroySurface(this, layer) ); - return NO_ERROR; } From ef07dda442f210bc7a6b5fbdd4a0bed4e6d8ad50 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Tue, 21 Apr 2009 18:28:33 -0700 Subject: [PATCH 15/83] get rid of the "show fps" debug option --- libs/surfaceflinger/SurfaceFlinger.cpp | 12 +----------- libs/surfaceflinger/SurfaceFlinger.h | 1 - 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp index 993a6ae02a2de..fdfaad3dedf54 100644 --- a/libs/surfaceflinger/SurfaceFlinger.cpp +++ b/libs/surfaceflinger/SurfaceFlinger.cpp @@ -177,7 +177,6 @@ SurfaceFlinger::SurfaceFlinger() mFreezeCount(0), mFreezeDisplayTime(0), mDebugRegion(0), - mDebugFps(0), mDebugBackground(0), mDebugNoBootAnimation(0), mConsoleSignals(0), @@ -196,14 +195,11 @@ void SurfaceFlinger::init() mDebugRegion = atoi(value); property_get("debug.sf.showbackground", value, "0"); mDebugBackground = atoi(value); - property_get("debug.sf.showfps", value, "0"); - mDebugFps = atoi(value); property_get("debug.sf.nobootanimation", value, "0"); mDebugNoBootAnimation = atoi(value); LOGI_IF(mDebugRegion, "showupdates enabled"); LOGI_IF(mDebugBackground, "showbackground enabled"); - LOGI_IF(mDebugFps, "showfps enabled"); LOGI_IF(mDebugNoBootAnimation, "boot animation disabled"); } @@ -525,10 +521,6 @@ void SurfaceFlinger::postFramebuffer() if (!mInvalidRegion.isEmpty()) { const DisplayHardware& hw(graphicPlane(0).displayHardware()); - if (UNLIKELY(mDebugFps)) { - debugShowFPS(); - } - hw.flip(mInvalidRegion); mInvalidRegion.clear(); @@ -1547,9 +1539,7 @@ status_t SurfaceFlinger::onTransact( switch (code) { case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE return NO_ERROR; - case 1001: // SHOW_FPS - n = data.readInt32(); - mDebugFps = n ? 1 : 0; + case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE return NO_ERROR; case 1002: // SHOW_UPDATES n = data.readInt32(); diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h index 76e40a1222e2c..319f80e9e926f 100644 --- a/libs/surfaceflinger/SurfaceFlinger.h +++ b/libs/surfaceflinger/SurfaceFlinger.h @@ -340,7 +340,6 @@ private: // don't use a lock for these, we don't care int mDebugRegion; - int mDebugFps; int mDebugBackground; int mDebugNoBootAnimation; From 81b0aa696ac954180caec6cb8cc1bb97440e03b5 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Wed, 22 Apr 2009 15:49:28 -0700 Subject: [PATCH 16/83] get rid of an old hack to work around a bug around glDeleteTextures() in the adreno drivers --- libs/surfaceflinger/Layer.cpp | 2 +- libs/surfaceflinger/LayerBase.cpp | 2 -- libs/surfaceflinger/LayerBase.h | 2 -- libs/surfaceflinger/LayerBlur.cpp | 3 +-- libs/surfaceflinger/LayerBuffer.cpp | 2 +- libs/surfaceflinger/LayerOrientationAnim.cpp | 4 ++-- libs/surfaceflinger/LayerOrientationAnimRotate.cpp | 4 ++-- libs/surfaceflinger/SurfaceFlinger.cpp | 7 ------- 8 files changed, 7 insertions(+), 19 deletions(-) diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp index 4e3f3a9b84357..182fbb2b153af 100644 --- a/libs/surfaceflinger/Layer.cpp +++ b/libs/surfaceflinger/Layer.cpp @@ -71,7 +71,7 @@ void Layer::destroy() if (mTextures[i].name != -1U) { // FIXME: this was originally to work-around a bug in the // adreno driver. this should be fixed now. - deletedTextures.add(mTextures[i].name); + glDeleteTextures(1, &mTextures[i].name); mTextures[i].name = -1U; } if (mTextures[i].image != EGL_NO_IMAGE_KHR) { diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp index 8609225b5908e..ef5a9598d69e4 100644 --- a/libs/surfaceflinger/LayerBase.cpp +++ b/libs/surfaceflinger/LayerBase.cpp @@ -53,8 +53,6 @@ const char* const LayerBaseClient::typeID = "LayerBaseClient"; // --------------------------------------------------------------------------- -Vector LayerBase::deletedTextures; - int32_t LayerBase::sIdentity = 0; LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display) diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h index 2ab6f6721bf35..c177c2a4faf2c 100644 --- a/libs/surfaceflinger/LayerBase.h +++ b/libs/surfaceflinger/LayerBase.h @@ -72,8 +72,6 @@ public: } - static Vector deletedTextures; - LayerBase(SurfaceFlinger* flinger, DisplayID display); DisplayID dpy; diff --git a/libs/surfaceflinger/LayerBlur.cpp b/libs/surfaceflinger/LayerBlur.cpp index 54d5c52141335..cac3cf10f0dfd 100644 --- a/libs/surfaceflinger/LayerBlur.cpp +++ b/libs/surfaceflinger/LayerBlur.cpp @@ -47,8 +47,7 @@ LayerBlur::LayerBlur(SurfaceFlinger* flinger, DisplayID display, LayerBlur::~LayerBlur() { if (mTextureName != -1U) { - //glDeleteTextures(1, &mTextureName); - deletedTextures.add(mTextureName); + glDeleteTextures(1, &mTextureName); } } diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp index 97d6f9748e613..9339b8758cc1e 100644 --- a/libs/surfaceflinger/LayerBuffer.cpp +++ b/libs/surfaceflinger/LayerBuffer.cpp @@ -322,7 +322,7 @@ LayerBuffer::BufferSource::BufferSource(LayerBuffer& layer, LayerBuffer::BufferSource::~BufferSource() { if (mTextureName != -1U) { - LayerBase::deletedTextures.add(mTextureName); + glDeleteTextures(1, &mTextureName); } } diff --git a/libs/surfaceflinger/LayerOrientationAnim.cpp b/libs/surfaceflinger/LayerOrientationAnim.cpp index 095fed8418aa2..41c42d177573f 100644 --- a/libs/surfaceflinger/LayerOrientationAnim.cpp +++ b/libs/surfaceflinger/LayerOrientationAnim.cpp @@ -73,10 +73,10 @@ LayerOrientationAnim::LayerOrientationAnim( LayerOrientationAnim::~LayerOrientationAnim() { if (mTextureName != -1U) { - LayerBase::deletedTextures.add(mTextureName); + glDeleteTextures(1, &mTextureName); } if (mTextureNameIn != -1U) { - LayerBase::deletedTextures.add(mTextureNameIn); + glDeleteTextures(1, &mTextureNameIn); } } diff --git a/libs/surfaceflinger/LayerOrientationAnimRotate.cpp b/libs/surfaceflinger/LayerOrientationAnimRotate.cpp index a3bf0149c0e31..dc6b632a694d3 100644 --- a/libs/surfaceflinger/LayerOrientationAnimRotate.cpp +++ b/libs/surfaceflinger/LayerOrientationAnimRotate.cpp @@ -68,10 +68,10 @@ LayerOrientationAnimRotate::LayerOrientationAnimRotate( LayerOrientationAnimRotate::~LayerOrientationAnimRotate() { if (mTextureName != -1U) { - LayerBase::deletedTextures.add(mTextureName); + glDeleteTextures(1, &mTextureName); } if (mTextureNameIn != -1U) { - LayerBase::deletedTextures.add(mTextureNameIn); + glDeleteTextures(1, &mTextureNameIn); } } diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp index fdfaad3dedf54..be91cddfdd09a 100644 --- a/libs/surfaceflinger/SurfaceFlinger.cpp +++ b/libs/surfaceflinger/SurfaceFlinger.cpp @@ -524,13 +524,6 @@ void SurfaceFlinger::postFramebuffer() hw.flip(mInvalidRegion); mInvalidRegion.clear(); - - if (Layer::deletedTextures.size()) { - glDeleteTextures( - Layer::deletedTextures.size(), - Layer::deletedTextures.array()); - Layer::deletedTextures.clear(); - } } } From 77c4903397eb0fb81f641c0beb1762f42819357b Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Mon, 27 Apr 2009 21:40:53 -0700 Subject: [PATCH 17/83] small fix to List.h, the post-increment iterators should return "const" objects to disallow constructs such as i++++ --- include/utils/List.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/utils/List.h b/include/utils/List.h index 1a6be9ac9d902..1b01c417bdba5 100644 --- a/include/utils/List.h +++ b/include/utils/List.h @@ -84,7 +84,7 @@ public: mpNode = mpNode->getNext(); return *this; } - _Iter operator++(int) { // post-increment + const _Iter operator++(int) { // post-increment _Iter tmp = *this; ++*this; return tmp; @@ -93,7 +93,7 @@ public: mpNode = mpNode->getPrev(); return *this; } - _Iter operator--(int) { // post-increment + const _Iter operator--(int) { // post-increment _Iter tmp = *this; --*this; return tmp; From 354271fb03d45309d8e249e3411bcf16cb807489 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Mon, 27 Apr 2009 22:09:49 -0700 Subject: [PATCH 18/83] improvements (I hope) to to List.h implementation: - made the helper Node and Iterator classes protected inner classes of List so they don't pollute the android namespace. - use "int foo()" instead of "int foo(void)" which is more C++ stylish - made distance() a template function, this way we write it once and it will work with combinations of iterator and const_iterator - added the inline keyword on some function to make it clear to the compiler and the programmer that we want/intend these to be small inline functions - added templated comparison operators to Iterator so it can compare iterator and const_iterator - use size_t instead of "unsigned int" at places - distance() should return a ptrdiff_t (it's kind of mening less here because it won't really work if the distance is < 0) - made sure we handle conversions from iterator to const_iterator, but but fail at compile time in the other direction - added operator->() on iterator and const_iterator - made a bunch of private constructors explicit to avoid unwanted conversions --- include/utils/List.h | 280 +++++++++++++++++++++++++------------------ 1 file changed, 166 insertions(+), 114 deletions(-) diff --git a/include/utils/List.h b/include/utils/List.h index 1b01c417bdba5..4041a891251ee 100644 --- a/include/utils/List.h +++ b/include/utils/List.h @@ -22,147 +22,200 @@ // construction, so if the compiler's auto-generated versions won't work for // you, define your own. // -// The only class you want to use from here is "List". Do not use classes -// starting with "_" directly. +// The only class you want to use from here is "List". // #ifndef _LIBS_UTILS_LIST_H #define _LIBS_UTILS_LIST_H +#include +#include + namespace android { -/* - * One element in the list. - */ -template class _ListNode { -public: - typedef _ListNode _Node; - - _ListNode(const T& val) : mVal(val) {} - ~_ListNode(void) {} - - T& getRef(void) { return mVal; } - void setVal(const T& val) { mVal = val; } - - _Node* getPrev(void) const { return mpPrev; } - void setPrev(_Node* ptr) { mpPrev = ptr; } - _Node* getNext(void) const { return mpNext; } - void setNext(_Node* ptr) { mpNext = ptr; } - -private: - T mVal; - _Node* mpPrev; - _Node* mpNext; -}; - -/* - * Iterator for walking through the list. - */ -template class _ListIterator { -public: - typedef _ListIterator _Iter; - typedef _ListNode _Node; - - _ListIterator(void) {} - _ListIterator(_Node* ptr) : mpNode(ptr) {} - ~_ListIterator(void) {} - - /* - * Dereference operator. Used to get at the juicy insides. - */ - Tref operator*() const { return mpNode->getRef(); } - - /* - * Iterator comparison. - */ - bool operator==(const _Iter& right) const { return mpNode == right.mpNode; } - bool operator!=(const _Iter& right) const { return mpNode != right.mpNode; } - - /* - * Incr/decr, used to move through the list. - */ - _Iter& operator++(void) { // pre-increment - mpNode = mpNode->getNext(); - return *this; - } - const _Iter operator++(int) { // post-increment - _Iter tmp = *this; - ++*this; - return tmp; - } - _Iter& operator--(void) { // pre-increment - mpNode = mpNode->getPrev(); - return *this; - } - const _Iter operator--(int) { // post-increment - _Iter tmp = *this; - --*this; - return tmp; - } - - _Node* getNode(void) const { return mpNode; } - -private: - _Node* mpNode; -}; - - /* * Doubly-linked list. Instantiate with "List myList". * * Objects added to the list are copied using the assignment operator, * so this must be defined. */ -template class List { -public: - typedef _ListNode _Node; +template +class List +{ +protected: + /* + * One element in the list. + */ + class _Node { + public: + explicit _Node(const T& val) : mVal(val) {} + ~_Node() {} + inline T& getRef() { return mVal; } + inline const T& getRef() const { return mVal; } + inline _Node* getPrev() const { return mpPrev; } + inline _Node* getNext() const { return mpNext; } + inline void setVal(const T& val) { mVal = val; } + inline void setPrev(_Node* ptr) { mpPrev = ptr; } + inline void setNext(_Node* ptr) { mpNext = ptr; } + private: + friend class List; + friend class _ListIterator; + T mVal; + _Node* mpPrev; + _Node* mpNext; + }; - List(void) { + /* + * Iterator for walking through the list. + */ + + template + struct CONST_ITERATOR { + typedef _Node const * NodePtr; + typedef const TYPE Type; + }; + + template + struct NON_CONST_ITERATOR { + typedef _Node* NodePtr; + typedef TYPE Type; + }; + + template< + typename U, + template class Constness + > + class _ListIterator { + typedef _ListIterator _Iter; + typedef typename Constness::NodePtr _NodePtr; + typedef typename Constness::Type _Type; + + explicit _ListIterator(_NodePtr ptr) : mpNode(ptr) {} + + public: + _ListIterator() {} + _ListIterator(const _Iter& rhs) : mpNode(rhs.mpNode) {} + ~_ListIterator() {} + + // this will handle conversions from iterator to const_iterator + // (and also all convertible iterators) + // Here, in this implementation, the iterators can be converted + // if the nodes can be converted + template explicit + _ListIterator(const V& rhs) : mpNode(rhs.mpNode) {} + + + /* + * Dereference operator. Used to get at the juicy insides. + */ + _Type& operator*() const { return mpNode->getRef(); } + _Type* operator->() const { return &(mpNode->getRef()); } + + /* + * Iterator comparison. + */ + inline bool operator==(const _Iter& right) const { + return mpNode == right.mpNode; } + + inline bool operator!=(const _Iter& right) const { + return mpNode != right.mpNode; } + + /* + * handle comparisons between iterator and const_iterator + */ + template + inline bool operator==(const OTHER& right) const { + return mpNode == right.mpNode; } + + template + inline bool operator!=(const OTHER& right) const { + return mpNode != right.mpNode; } + + /* + * Incr/decr, used to move through the list. + */ + inline _Iter& operator++() { // pre-increment + mpNode = mpNode->getNext(); + return *this; + } + const _Iter operator++(int) { // post-increment + _Iter tmp(*this); + mpNode = mpNode->getNext(); + return tmp; + } + inline _Iter& operator--() { // pre-increment + mpNode = mpNode->getPrev(); + return *this; + } + const _Iter operator--(int) { // post-increment + _Iter tmp(*this); + mpNode = mpNode->getPrev(); + return tmp; + } + + inline _NodePtr getNode() const { return mpNode; } + + private: + friend class List; + _NodePtr mpNode; + }; + +public: + List() { prep(); } List(const List& src) { // copy-constructor prep(); insert(begin(), src.begin(), src.end()); } - virtual ~List(void) { + virtual ~List() { clear(); delete[] (unsigned char*) mpMiddle; } - typedef _ListIterator iterator; - typedef _ListIterator const_iterator; + typedef _ListIterator iterator; + typedef _ListIterator const_iterator; List& operator=(const List& right); /* returns true if the list is empty */ - bool empty(void) const { return mpMiddle->getNext() == mpMiddle; } + inline bool empty() const { return mpMiddle->getNext() == mpMiddle; } /* return #of elements in list */ - unsigned int size(void) const { - return distance(begin(), end()); + size_t size() const { + return size_t(distance(begin(), end())); } /* * Return the first element or one past the last element. The - * _ListNode* we're returning is converted to an "iterator" by a + * _Node* we're returning is converted to an "iterator" by a * constructor in _ListIterator. */ - iterator begin() { return mpMiddle->getNext(); } - const_iterator begin() const { return mpMiddle->getNext(); } - iterator end() { return mpMiddle; } - const_iterator end() const { return mpMiddle; } + inline iterator begin() { + return iterator(mpMiddle->getNext()); + } + inline const_iterator begin() const { + return const_iterator(const_cast<_Node const*>(mpMiddle->getNext())); + } + inline iterator end() { + return iterator(mpMiddle); + } + inline const_iterator end() const { + return const_iterator(const_cast<_Node const*>(mpMiddle)); + } /* add the object to the head or tail of the list */ void push_front(const T& val) { insert(begin(), val); } void push_back(const T& val) { insert(end(), val); } /* insert before the current node; returns iterator at new node */ - iterator insert(iterator posn, const T& val) { + iterator insert(iterator posn, const T& val) + { _Node* newNode = new _Node(val); // alloc & copy-construct newNode->setNext(posn.getNode()); newNode->setPrev(posn.getNode()->getPrev()); posn.getNode()->getPrev()->setNext(newNode); posn.getNode()->setPrev(newNode); - return newNode; + return iterator(newNode); } /* insert a range of elements before the current node */ @@ -178,18 +231,18 @@ public: pPrev->setNext(pNext); pNext->setPrev(pPrev); delete posn.getNode(); - return pNext; + return iterator(pNext); } /* remove a range of elements */ iterator erase(iterator first, iterator last) { while (first != last) erase(first++); // don't erase than incr later! - return last; + return iterator(last); } /* remove all contents of the list */ - void clear(void) { + void clear() { _Node* pCurrent = mpMiddle->getNext(); _Node* pNext; @@ -207,21 +260,20 @@ public: * will be equal to "last". The iterators must refer to the same * list. * - * (This is actually a generic iterator function. It should be part - * of some other class, possibly an iterator base class. It needs to - * know the difference between a list, which has to march through, - * and a vector, which can just do pointer math.) + * FIXME: This is actually a generic iterator function. It should be a + * template function at the top-level with specializations for things like + * vector<>, which can just do pointer math). Here we limit it to + * _ListIterator of the same type but different constness. */ - unsigned int distance(iterator first, iterator last) { - unsigned int count = 0; - while (first != last) { - ++first; - ++count; - } - return count; - } - unsigned int distance(const_iterator first, const_iterator last) const { - unsigned int count = 0; + template< + typename U, + template class CL, + template class CR + > + ptrdiff_t distance( + _ListIterator first, _ListIterator last) const + { + ptrdiff_t count = 0; while (first != last) { ++first; ++count; @@ -231,12 +283,12 @@ public: private: /* - * I want a _ListNode but don't need it to hold valid data. More + * I want a _Node but don't need it to hold valid data. More * to the point, I don't want T's constructor to fire, since it * might have side-effects or require arguments. So, we do this * slightly uncouth storage alloc. */ - void prep(void) { + void prep() { mpMiddle = (_Node*) new unsigned char[sizeof(_Node)]; mpMiddle->setPrev(mpMiddle); mpMiddle->setNext(mpMiddle); From bdbe6024a543bd740b0c194db9c12e4150c55c59 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Tue, 28 Apr 2009 03:17:50 -0700 Subject: [PATCH 19/83] make use of the perfectly fine List.h instead of our own reimplementation of a linked list. --- libs/surfaceflinger/MessageQueue.cpp | 57 +++++++--- libs/surfaceflinger/MessageQueue.h | 142 ++++--------------------- libs/surfaceflinger/SurfaceFlinger.cpp | 2 +- 3 files changed, 65 insertions(+), 136 deletions(-) diff --git a/libs/surfaceflinger/MessageQueue.cpp b/libs/surfaceflinger/MessageQueue.cpp index 907938300ff13..52d4db8063888 100644 --- a/libs/surfaceflinger/MessageQueue.cpp +++ b/libs/surfaceflinger/MessageQueue.cpp @@ -29,6 +29,27 @@ namespace android { // --------------------------------------------------------------------------- +void MessageList::insert(const sp& node) +{ + LIST::iterator cur(mList.begin()); + LIST::iterator end(mList.end()); + while (cur != end) { + if (*node < **cur) { + mList.insert(cur, node); + return; + } + ++cur; + } + mList.insert(++end, node); +} + +void MessageList::remove(MessageList::LIST::iterator pos) +{ + mList.erase(pos); +} + +// --------------------------------------------------------------------------- + MessageQueue::MessageQueue() { mInvalidateMessage = new MessageBase(INVALIDATE); @@ -38,9 +59,10 @@ MessageQueue::~MessageQueue() { } -MessageList::NODE_PTR MessageQueue::waitMessage(nsecs_t timeout) +MessageList::value_type MessageQueue::waitMessage(nsecs_t timeout) { - MessageList::NODE_PTR result; + MessageList::value_type result; + bool again; do { const nsecs_t timeoutTime = systemTime() + timeout; @@ -57,13 +79,15 @@ MessageList::NODE_PTR MessageQueue::waitMessage(nsecs_t timeout) break; } - result = mMessages.head(); - + LIST::iterator cur(mMessages.begin()); + if (cur != mMessages.end()) { + result = *cur; + } + if (result != 0) { if (result->when <= now) { // there is a message to deliver - mMessages.remove(result); - result->detach(); + mMessages.remove(cur); break; } if (timeout>=0 && timeoutTime < now) { @@ -108,11 +132,12 @@ MessageList::NODE_PTR MessageQueue::waitMessage(nsecs_t timeout) } } while (again); + return result; } status_t MessageQueue::postMessage( - const MessageList::NODE_PTR& message, nsecs_t relTime, uint32_t flags) + const MessageList::value_type& message, nsecs_t relTime, uint32_t flags) { return queueMessage(message, relTime, flags); } @@ -125,7 +150,7 @@ status_t MessageQueue::invalidate() { } status_t MessageQueue::queueMessage( - const MessageList::NODE_PTR& message, nsecs_t relTime, uint32_t flags) + const MessageList::value_type& message, nsecs_t relTime, uint32_t flags) { Mutex::Autolock _l(mLock); message->when = systemTime() + relTime; @@ -138,20 +163,22 @@ status_t MessageQueue::queueMessage( return NO_ERROR; } -void MessageQueue::dump(const MessageList::NODE_PTR& message) +void MessageQueue::dump(const MessageList::value_type& message) { Mutex::Autolock _l(mLock); dumpLocked(message); } -void MessageQueue::dumpLocked(const MessageList::NODE_PTR& message) +void MessageQueue::dumpLocked(const MessageList::value_type& message) { - MessageList::NODE_PTR l(mMessages.head()); + LIST::const_iterator cur(mMessages.begin()); + LIST::const_iterator end(mMessages.end()); int c = 0; - while (l != 0) { - const char tick = (l == message) ? '>' : ' '; - LOGD("%c %d: msg{.what=%08x, when=%lld}", tick, c, l->what, l->when); - l = l->getNext(); + while (cur != end) { + const char tick = (*cur == message) ? '>' : ' '; + LOGD("%c %d: msg{.what=%08x, when=%lld}", + tick, c, (*cur)->what, (*cur)->when); + ++cur; c++; } } diff --git a/libs/surfaceflinger/MessageQueue.h b/libs/surfaceflinger/MessageQueue.h index c118897dd699e..dc8138d1667d4 100644 --- a/libs/surfaceflinger/MessageQueue.h +++ b/libs/surfaceflinger/MessageQueue.h @@ -23,125 +23,34 @@ #include #include +#include namespace android { // --------------------------------------------------------------------------- -template -class DoublyLinkedList +class MessageBase; + +class MessageList { -protected: - typedef NODE_PTR_TYPE NODE_PTR; - - NODE_PTR mFirst; - NODE_PTR mLast; - + List< sp > mList; + typedef List< sp > LIST; public: - class Node { - friend class DoublyLinkedList; - mutable NODE_PTR next; - mutable NODE_PTR prev; - public: - typedef NODE_PTR PTR; - inline NODE_PTR getNext() const { return next; } - inline NODE_PTR getPrev() const { return prev; } - void detach() { - prev = 0; - next = 0; - } - }; - - DoublyLinkedList() : mFirst(0), mLast(0) { } - ~DoublyLinkedList() { } - - bool isEmpty() const { return mFirst == 0; } - const NODE_PTR& head() const { return mFirst; } - const NODE_PTR& tail() const { return mLast; } - const NODE_PTR& head() { return mFirst; } - const NODE_PTR& tail() { return mLast; } - - void insertAfter(const NODE_PTR& node, const NODE_PTR& newNode) { - newNode->prev = node; - newNode->next = node->next; - if (node->next == 0) mLast = newNode; - else node->next->prev = newNode; - node->next = newNode; - } - - void insertBefore(const NODE_PTR& node, const NODE_PTR& newNode) { - newNode->prev = node->prev; - newNode->next = node; - if (node->prev == 0) mFirst = newNode; - else node->prev->next = newNode; - node->prev = newNode; - } - - void insertHead(const NODE_PTR& newNode) { - if (mFirst == 0) { - mFirst = mLast = newNode; - newNode->prev = newNode->next = 0; - } else { - newNode->prev = 0; - newNode->next = mFirst; - mFirst->prev = newNode; - mFirst = newNode; - } - } - - void insertTail(const NODE_PTR& newNode) { - if (mLast == 0) { - insertHead(newNode); - } else { - newNode->prev = mLast; - newNode->next = 0; - mLast->next = newNode; - mLast = newNode; - } - } - - NODE_PTR remove(const NODE_PTR& node) { - if (node->prev == 0) mFirst = node->next; - else node->prev->next = node->next; - if (node->next == 0) mLast = node->prev; - else node->next->prev = node->prev; - return node; - } -}; - -// --------------------------------------------------------------------------- - -template -class SortedList : protected DoublyLinkedList< NODE_PTR_TYPE > -{ - typedef DoublyLinkedList< NODE_PTR_TYPE > forward; -public: - typedef NODE_PTR_TYPE NODE_PTR; - inline bool isEmpty() const { return forward::isEmpty(); } - inline const NODE_PTR& head() const { return forward::head(); } - inline const NODE_PTR& tail() const { return forward::tail(); } - inline const NODE_PTR& head() { return forward::head(); } - inline const NODE_PTR& tail() { return forward::tail(); } - inline NODE_PTR remove(const NODE_PTR& node) { return forward::remove(node); } - void insert(const NODE_PTR& node) { - NODE_PTR l(head()); - while (l != 0) { - if (*node < *l) { - insertBefore(l, node); - return; - } - l = l->getNext(); - } - insertTail(node); - } + typedef sp value_type; + inline LIST::iterator begin() { return mList.begin(); } + inline LIST::const_iterator begin() const { return mList.begin(); } + inline LIST::iterator end() { return mList.end(); } + inline LIST::const_iterator end() const { return mList.end(); } + inline bool isEmpty() const { return mList.empty(); } + void insert(const sp& node); + void remove(LIST::iterator pos); }; // ============================================================================ class MessageBase : - public LightRefBase, - public DoublyLinkedList< sp >::Node + public LightRefBase { public: nsecs_t when; @@ -168,16 +77,9 @@ inline bool operator < (const MessageBase& lhs, const MessageBase& rhs) { // --------------------------------------------------------------------------- -/* - * MessageList is a sorted list of sp - */ - -typedef SortedList< MessageBase::Node::PTR > MessageList; - -// --------------------------------------------------------------------------- - class MessageQueue { + typedef List< sp > LIST; public: // this is a work-around the multichar constant warning. A macro would @@ -197,25 +99,25 @@ public: INVALIDATE = WHAT<'_','p','d','t'>::Value }; - MessageList::NODE_PTR waitMessage(nsecs_t timeout = -1); + MessageList::value_type waitMessage(nsecs_t timeout = -1); - status_t postMessage(const MessageList::NODE_PTR& message, + status_t postMessage(const MessageList::value_type& message, nsecs_t reltime=0, uint32_t flags = 0); status_t invalidate(); - void dump(const MessageList::NODE_PTR& message); + void dump(const MessageList::value_type& message); private: - status_t queueMessage(const MessageList::NODE_PTR& message, + status_t queueMessage(const MessageList::value_type& message, nsecs_t reltime, uint32_t flags); - void dumpLocked(const MessageList::NODE_PTR& message); + void dumpLocked(const MessageList::value_type& message); Mutex mLock; Condition mCondition; MessageList mMessages; bool mInvalidate; - MessageList::NODE_PTR mInvalidateMessage; + MessageList::value_type mInvalidateMessage; }; // --------------------------------------------------------------------------- diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp index be91cddfdd09a..6b421588e19c5 100644 --- a/libs/surfaceflinger/SurfaceFlinger.cpp +++ b/libs/surfaceflinger/SurfaceFlinger.cpp @@ -429,7 +429,7 @@ void SurfaceFlinger::waitForEvent() timeout = waitTime>0 ? waitTime : 0; } - MessageList::NODE_PTR msg = mEventQueue.waitMessage(timeout); + MessageList::value_type msg = mEventQueue.waitMessage(timeout); if (msg != 0) { mFreezeDisplayTime = 0; switch (msg->what) { From dff8e58d47ede6e748c0b02e128ca33b42a4f362 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Mon, 4 May 2009 14:17:04 -0700 Subject: [PATCH 20/83] update surfaceflinger, libui and libagl to the new gralloc api - Currently the lock/unlock path is naive and is done for each drawing operation (glDrawElements and glDrawArrays). this should be improved eventually. - factor all the lock/unlock code in SurfaceBuffer. - fixed "showupdate" so it works even when we don't have preserving eglSwapBuffers(). - improved the situation with the dirty-region and fixed a problem that caused GL apps to not update. - make use of LightRefBase() where needed, instead of duplicating its implementation - add LightRefBase::getStrongCount() - renamed EGLNativeWindowSurface.cpp to FramebufferNativeWindow.cpp - disabled copybits test, since it clashes with the new gralloc api - Camera/Video will be fixed later when we rework the overlay apis --- include/ui/BufferMapper.h | 23 +- include/ui/EGLDisplaySurface.h | 86 ------- ...dowSurface.h => FramebufferNativeWindow.h} | 24 +- include/ui/Region.h | 1 + include/ui/Surface.h | 39 +-- include/utils/RefBase.h | 4 + libs/surfaceflinger/Android.mk | 3 - libs/surfaceflinger/BootAnimation.cpp | 2 +- libs/surfaceflinger/BufferAllocator.cpp | 56 +---- libs/surfaceflinger/BufferAllocator.h | 4 - .../DisplayHardware/DisplayHardware.cpp | 5 +- libs/surfaceflinger/Layer.cpp | 15 +- libs/surfaceflinger/LayerBase.cpp | 24 +- libs/surfaceflinger/LayerBase.h | 3 +- libs/surfaceflinger/LayerBitmap.cpp | 43 ++-- libs/surfaceflinger/LayerBitmap.h | 5 +- libs/surfaceflinger/LayerBuffer.cpp | 38 +-- libs/surfaceflinger/SurfaceFlinger.cpp | 41 ++-- libs/surfaceflinger/SurfaceFlinger.h | 4 - .../{ => purgatory}/LayerOrientationAnim.cpp | 0 .../{ => purgatory}/LayerOrientationAnim.h | 0 .../LayerOrientationAnimRotate.cpp | 0 .../LayerOrientationAnimRotate.h | 0 .../{ => purgatory}/OrientationAnimation.cpp | 0 .../{ => purgatory}/OrientationAnimation.h | 0 libs/ui/Android.mk | 2 +- libs/ui/BufferMapper.cpp | 100 +------- ...urface.cpp => FramebufferNativeWindow.cpp} | 42 +--- libs/ui/Region.cpp | 7 + libs/ui/Surface.cpp | 225 +++++++++--------- opengl/include/EGL/android_natives.h | 26 +- opengl/libagl/TextureObjectManager.cpp | 20 +- opengl/libagl/TextureObjectManager.h | 50 +--- opengl/libagl/array.cpp | 19 +- opengl/libagl/egl.cpp | 71 +++--- opengl/libagl/texture.cpp | 88 +++++-- opengl/libagl/texture.h | 10 +- opengl/tests/copybits/Android.mk | 2 +- 38 files changed, 432 insertions(+), 650 deletions(-) delete mode 100644 include/ui/EGLDisplaySurface.h rename include/ui/{EGLNativeWindowSurface.h => FramebufferNativeWindow.h} (83%) rename libs/surfaceflinger/{ => purgatory}/LayerOrientationAnim.cpp (100%) rename libs/surfaceflinger/{ => purgatory}/LayerOrientationAnim.h (100%) rename libs/surfaceflinger/{ => purgatory}/LayerOrientationAnimRotate.cpp (100%) rename libs/surfaceflinger/{ => purgatory}/LayerOrientationAnimRotate.h (100%) rename libs/surfaceflinger/{ => purgatory}/OrientationAnimation.cpp (100%) rename libs/surfaceflinger/{ => purgatory}/OrientationAnimation.h (100%) rename libs/ui/{EGLNativeWindowSurface.cpp => FramebufferNativeWindow.cpp} (81%) diff --git a/include/ui/BufferMapper.h b/include/ui/BufferMapper.h index ff90033002963..5f084becf9436 100644 --- a/include/ui/BufferMapper.h +++ b/include/ui/BufferMapper.h @@ -20,10 +20,7 @@ #include #include -#include -#include #include -#include #include @@ -40,9 +37,14 @@ class BufferMapper : public Singleton { public: static inline BufferMapper& get() { return getInstance(); } - status_t map(buffer_handle_t handle, void** addr, const void* id); - status_t unmap(buffer_handle_t handle, const void* id); - status_t lock(buffer_handle_t handle, int usage, const Rect& bounds); + + status_t registerBuffer(buffer_handle_t handle); + + status_t unregisterBuffer(buffer_handle_t handle); + + status_t lock(buffer_handle_t handle, + int usage, const Rect& bounds, void** vaddr); + status_t unlock(buffer_handle_t handle); // dumps information about the mapping of this handle @@ -51,16 +53,7 @@ public: private: friend class Singleton; BufferMapper(); - mutable Mutex mLock; gralloc_module_t const *mAllocMod; - - void logMapLocked(buffer_handle_t handle, const void* id); - void logUnmapLocked(buffer_handle_t handle, const void* id); - struct map_info_t { - const void* id; - CallStack stack; - }; - KeyedVector > mMapInfo; }; // --------------------------------------------------------------------------- diff --git a/include/ui/EGLDisplaySurface.h b/include/ui/EGLDisplaySurface.h deleted file mode 100644 index a8b58539d192d..0000000000000 --- a/include/ui/EGLDisplaySurface.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2007 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. - */ - -#ifndef ANDROID_EGL_DISPLAY_SURFACE_H -#define ANDROID_EGL_DISPLAY_SURFACE_H - -#include -#include - -#include - -#include - -#include -#include - -#include - -struct copybit_device_t; -struct copybit_image_t; - -// --------------------------------------------------------------------------- -namespace android { -// --------------------------------------------------------------------------- - -class Region; -class Rect; - -class EGLDisplaySurface : public EGLNativeSurface -{ -public: - EGLDisplaySurface(); - ~EGLDisplaySurface(); - - int32_t getPageFlipCount() const; - void copyFrontToBack(const Region& copyback); - void copyFrontToImage(const copybit_image_t& dst); - void copyBackToImage(const copybit_image_t& dst); - - void setSwapRectangle(int l, int t, int w, int h); - -private: - static void hook_incRef(NativeWindowType window); - static void hook_decRef(NativeWindowType window); - static uint32_t hook_swapBuffers(NativeWindowType window); - - uint32_t swapBuffers(); - - status_t mapFrameBuffer(); - - enum { - PAGE_FLIP = 0x00000001 - }; - GGLSurface mFb[2]; - int mIndex; - uint32_t mFlags; - size_t mSize; - fb_var_screeninfo mInfo; - fb_fix_screeninfo mFinfo; - int32_t mPageFlipCount; - nsecs_t mTime; - int32_t mSwapCount; - nsecs_t mSleep; - uint32_t mFeatureFlags; - copybit_device_t* mBlitEngine; -}; - -// --------------------------------------------------------------------------- -}; // namespace android -// --------------------------------------------------------------------------- - -#endif // ANDROID_EGL_DISPLAY_SURFACE_H - diff --git a/include/ui/EGLNativeWindowSurface.h b/include/ui/FramebufferNativeWindow.h similarity index 83% rename from include/ui/EGLNativeWindowSurface.h rename to include/ui/FramebufferNativeWindow.h index 4b25655cf332b..1d49cca401ae4 100644 --- a/include/ui/EGLNativeWindowSurface.h +++ b/include/ui/FramebufferNativeWindow.h @@ -14,8 +14,8 @@ * limitations under the License. */ -#ifndef ANDROID_EGL_NATIVE_WINDOW_SURFACE_H -#define ANDROID_EGL_NATIVE_WINDOW_SURFACE_H +#ifndef ANDROID_FRAMEBUFFER_NATIVE_WINDOW_H +#define ANDROID_FRAMEBUFFER_NATIVE_WINDOW_H #include #include @@ -76,32 +76,18 @@ public: framebuffer_device_t const * getDevice() const { return fbDev; } + void setSwapRectangle(const Rect& dirty); + private: friend class LightRefBase; ~FramebufferNativeWindow(); // this class cannot be overloaded static void connect(android_native_window_t* window); static void disconnect(android_native_window_t* window); static int setSwapInterval(android_native_window_t* window, int interval); - static int setSwapRectangle(android_native_window_t* window, - int l, int t, int w, int h); static int dequeueBuffer(android_native_window_t* window, android_native_buffer_t** buffer); static int lockBuffer(android_native_window_t* window, android_native_buffer_t* buffer); static int queueBuffer(android_native_window_t* window, android_native_buffer_t* buffer); - - static inline FramebufferNativeWindow* getSelf( - android_native_window_t* window) { - FramebufferNativeWindow* self = - static_cast(window); - return self; - } - - static inline FramebufferNativeWindow* getSelf( - android_native_base_t* window) { - return getSelf(reinterpret_cast(window)); - } - - framebuffer_device_t* fbDev; alloc_device_t* grDev; @@ -121,5 +107,5 @@ private: }; // namespace android // --------------------------------------------------------------------------- -#endif // ANDROID_EGL_NATIVE_WINDOW_SURFACE_H +#endif // ANDROID_FRAMEBUFFER_NATIVE_WINDOW_H diff --git a/include/ui/Region.h b/include/ui/Region.h index 76896737f293d..5efeff7d32adb 100644 --- a/include/ui/Region.h +++ b/include/ui/Region.h @@ -57,6 +57,7 @@ public: void clear(); void set(const Rect& r); + void set(uint32_t w, uint32_t h); Region& orSelf(const Rect& rhs); Region& andSelf(const Rect& rhs); diff --git a/include/ui/Surface.h b/include/ui/Surface.h index 16d2edb8e223a..6eb06ae65f356 100644 --- a/include/ui/Surface.h +++ b/include/ui/Surface.h @@ -34,7 +34,9 @@ namespace android { // --------------------------------------------------------------------------- +class BufferMapper; class Rect; +class Surface; class SurfaceComposerClient; struct per_client_cblk_t; struct layer_cblk_t; @@ -52,6 +54,10 @@ public: return handle; } + status_t lock(uint32_t usage); + status_t lock(uint32_t usage, const Rect& rect); + status_t unlock(); + protected: SurfaceBuffer(); SurfaceBuffer(const Parcel& reply); @@ -59,7 +65,11 @@ protected: buffer_handle_t handle; bool mOwner; + inline const BufferMapper& getBufferMapper() const { return mBufferMapper; } + inline BufferMapper& getBufferMapper() { return mBufferMapper; } + private: + friend class Surface; friend class BpSurface; friend class BnSurface; friend class LightRefBase; @@ -72,6 +82,8 @@ private: static int getHandle(android_native_buffer_t const * base, buffer_handle_t* handle); + + BufferMapper& mBufferMapper; }; // --------------------------------------------------------------------------- @@ -191,9 +203,8 @@ public: status_t lock(SurfaceInfo* info, Region* dirty, bool blocking = true); status_t unlockAndPost(); - // setSwapRectangle() is mainly used by EGL + // setSwapRectangle() is intended to be used by GL ES clients void setSwapRectangle(const Rect& r); - const Rect& swapRectangle() const; private: // can't be copied @@ -216,22 +227,14 @@ private: const sp& getISurface() const { return mSurface; } status_t getBufferLocked(int index); - - - - Region dirtyRegion() const; - void setDirtyRegion(const Region& region) const; - status_t validate(per_client_cblk_t const* cblk) const; static void _send_dirty_region(layer_cblk_t* lcblk, const Region& dirty); + inline const BufferMapper& getBufferMapper() const { return mBufferMapper; } + inline BufferMapper& getBufferMapper() { return mBufferMapper; } - static void connect(android_native_window_t* window); - static void disconnect(android_native_window_t* window); static int setSwapInterval(android_native_window_t* window, int interval); - static int setSwapRectangle(android_native_window_t* window, - int l, int t, int w, int h); static int dequeueBuffer(android_native_window_t* window, android_native_buffer_t** buffer); static int lockBuffer(android_native_window_t* window, android_native_buffer_t* buffer); static int queueBuffer(android_native_window_t* window, android_native_buffer_t* buffer); @@ -239,21 +242,27 @@ private: int dequeueBuffer(android_native_buffer_t** buffer); int lockBuffer(android_native_buffer_t* buffer); int queueBuffer(android_native_buffer_t* buffer); - + + status_t dequeueBuffer(sp* buffer); + status_t lockBuffer(const sp& buffer); + status_t queueBuffer(const sp& buffer); + alloc_device_t* mAllocDevice; sp mClient; sp mSurface; sp mBuffers[2]; - android_native_buffer_t* mLockedBuffer; + sp mLockedBuffer; SurfaceID mToken; uint32_t mIdentity; PixelFormat mFormat; uint32_t mFlags; mutable Region mDirtyRegion; - mutable Rect mSwapRectangle; + mutable Region mOldDirtyRegion; mutable uint8_t mBackbufferIndex; mutable Mutex mSurfaceLock; + Rect mSwapRectangle; + BufferMapper& mBufferMapper; }; }; // namespace android diff --git a/include/utils/RefBase.h b/include/utils/RefBase.h index cbda0fd80db63..bd7f28cae3a17 100644 --- a/include/utils/RefBase.h +++ b/include/utils/RefBase.h @@ -156,6 +156,10 @@ public: delete static_cast(this); } } + //! DEBUGGING ONLY: Get current strong ref count. + inline int32_t getStrongCount() const { + return mCount; + } protected: inline ~LightRefBase() { } diff --git a/libs/surfaceflinger/Android.mk b/libs/surfaceflinger/Android.mk index 2b360d620595b..639a82eaeb970 100644 --- a/libs/surfaceflinger/Android.mk +++ b/libs/surfaceflinger/Android.mk @@ -14,10 +14,7 @@ LOCAL_SRC_FILES:= \ LayerBlur.cpp \ LayerBitmap.cpp \ LayerDim.cpp \ - LayerOrientationAnim.cpp \ - LayerOrientationAnimRotate.cpp \ MessageQueue.cpp \ - OrientationAnimation.cpp \ SurfaceFlinger.cpp \ Tokenizer.cpp \ Transform.cpp diff --git a/libs/surfaceflinger/BootAnimation.cpp b/libs/surfaceflinger/BootAnimation.cpp index ee36b6703a390..b45fe3489a9ea 100644 --- a/libs/surfaceflinger/BootAnimation.cpp +++ b/libs/surfaceflinger/BootAnimation.cpp @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include diff --git a/libs/surfaceflinger/BufferAllocator.cpp b/libs/surfaceflinger/BufferAllocator.cpp index fec7c8770584f..cee8b643dde61 100644 --- a/libs/surfaceflinger/BufferAllocator.cpp +++ b/libs/surfaceflinger/BufferAllocator.cpp @@ -16,20 +16,14 @@ */ #include -#include #include #include #include #include -#include - #include "BufferAllocator.h" -// FIXME: ANDROID_GRALLOC_DEBUG must only be used with *our* gralloc -#define ANDROID_GRALLOC_DEBUG 1 - namespace android { // --------------------------------------------------------------------------- @@ -67,8 +61,8 @@ void BufferAllocator::dump(String8& result) const const size_t c = list.size(); for (size_t i=0 ; idata[2]); -#endif - status_t err = mAllocDev->free(mAllocDev, handle); LOGW_IF(err, "free(...) failed %d (%s)", err, strerror(-err)); -#if ANDROID_GRALLOC_DEBUG - if (base) { - LOGD("freeing mapped handle %p from:", handle); - CallStack s; - s.update(); - s.dump(""); - BufferMapper::get().dump(handle); - } -#endif - if (err == NO_ERROR) { Mutex::Autolock _l(sLock); KeyedVector& list(sAllocList); @@ -134,37 +114,5 @@ status_t BufferAllocator::free(buffer_handle_t handle) return err; } -status_t BufferAllocator::map(buffer_handle_t handle, void** addr) -{ - Mutex::Autolock _l(mLock); - status_t err = BufferMapper::get().map(handle, addr, this); - if (err == NO_ERROR) { - Mutex::Autolock _l(sLock); - KeyedVector& list(sAllocList); - ssize_t idx = list.indexOfKey(handle); - if (idx >= 0) - list.editValueAt(idx).vaddr = addr; - } - - return err; -} - -status_t BufferAllocator::unmap(buffer_handle_t handle) -{ - Mutex::Autolock _l(mLock); - gralloc_module_t* mod = (gralloc_module_t*)mAllocDev->common.module; - status_t err = BufferMapper::get().unmap(handle, this); - if (err == NO_ERROR) { - Mutex::Autolock _l(sLock); - KeyedVector& list(sAllocList); - ssize_t idx = list.indexOfKey(handle); - if (idx >= 0) - list.editValueAt(idx).vaddr = 0; - } - - return err; -} - - // --------------------------------------------------------------------------- }; // namespace android diff --git a/libs/surfaceflinger/BufferAllocator.h b/libs/surfaceflinger/BufferAllocator.h index 0b69b8ecd46f7..a279deda941c4 100644 --- a/libs/surfaceflinger/BufferAllocator.h +++ b/libs/surfaceflinger/BufferAllocator.h @@ -67,10 +67,6 @@ public: status_t free(buffer_handle_t handle); - status_t map(buffer_handle_t handle, void** addr); - - status_t unmap(buffer_handle_t handle); - void dump(String8& res) const; private: diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp index 1f7211cc13ca2..83ebd7a617d35 100644 --- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp +++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include @@ -313,8 +313,7 @@ void DisplayHardware::flip(const Region& dirty) const } const Rect& b(newDirty.bounds()); - mNativeWindow->android_native_window_t::setSwapRectangle( - mNativeWindow.get(), b.left, b.top, b.width(), b.height()); + mNativeWindow->setSwapRectangle(b); mPageFlipCount++; eglSwapBuffers(dpy, surface); diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp index 8a7d46784f55f..76259317482fa 100644 --- a/libs/surfaceflinger/Layer.cpp +++ b/libs/surfaceflinger/Layer.cpp @@ -69,8 +69,6 @@ void Layer::destroy() { for (int i=0 ; i& buffer(frontBuffer().getBuffer()); - if (LIKELY(mFlags & DisplayHardware::DIRECT_TEXTURE)) { + const sp& buffer(frontBuffer().getBuffer()); + if (LIKELY(mFlags & DisplayHardware::DIRECT_TEXTURE)) { int index = mFrontBufferIndex; if (LIKELY(!mTextures[index].dirty)) { glBindTexture(GL_TEXTURE_2D, mTextures[index].name); @@ -197,12 +195,16 @@ void Layer::reloadTexture(const Region& dirty) } } else { GGLSurface t; - if (LIKELY(buffer->getBitmapSurface(&t) == NO_ERROR)) { + status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_RARELY); + LOGE_IF(res, "error %d (%s) locking buffer %p", + res, strerror(res), buffer.get()); + if (res == NO_ERROR) { if (UNLIKELY(mTextures[0].name == -1U)) { mTextures[0].name = createTexture(); } loadTexture(dirty, mTextures[0].name, t, mTextures[0].width, mTextures[0].height); + buffer->unlock(); } } } @@ -225,8 +227,7 @@ void Layer::onDraw(const Region& clip) const GGLSurface t; sp buffer(frontBuffer().getBuffer()); - buffer->getBitmapSurface(&t); - drawWithOpenGL(clip, textureName, t); + drawWithOpenGL(clip, textureName, buffer); } sp Layer::peekBuffer() diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp index ef5a9598d69e4..cc9c586b421ab 100644 --- a/libs/surfaceflinger/LayerBase.cpp +++ b/libs/surfaceflinger/LayerBase.cpp @@ -377,12 +377,14 @@ void LayerBase::clearWithOpenGL(const Region& clip) const } void LayerBase::drawWithOpenGL(const Region& clip, - GLint textureName, const GGLSurface& t, int transform) const + GLint textureName, const sp& buffer, int transform) const { const DisplayHardware& hw(graphicPlane(0).displayHardware()); const uint32_t fbHeight = hw.getHeight(); const State& s(drawingState()); - + const uint32_t width = buffer->width; + const uint32_t height = buffer->height; + // bind our texture validateTexture(textureName); glEnable(GL_TEXTURE_2D); @@ -457,14 +459,14 @@ void LayerBase::drawWithOpenGL(const Region& clip, if (!(mFlags & DisplayHardware::NPOT_EXTENSION)) { // find the smallest power-of-two that will accommodate our surface - GLuint tw = 1 << (31 - clz(t.width)); - GLuint th = 1 << (31 - clz(t.height)); - if (tw < t.width) tw <<= 1; - if (th < t.height) th <<= 1; + GLuint tw = 1 << (31 - clz(width)); + GLuint th = 1 << (31 - clz(height)); + if (tw < width) tw <<= 1; + if (th < height) th <<= 1; // this divide should be relatively fast because it's // a power-of-two (optimized path in libgcc) - GLfloat ws = GLfloat(t.width) /tw; - GLfloat hs = GLfloat(t.height)/th; + GLfloat ws = GLfloat(width) /tw; + GLfloat hs = GLfloat(height)/th; glScalef(ws, hs, 1.0f); } @@ -489,15 +491,15 @@ void LayerBase::drawWithOpenGL(const Region& clip, Region::iterator iterator(clip); if (iterator) { Rect r; - GLint crop[4] = { 0, t.height, t.width, -t.height }; + GLint crop[4] = { 0, height, width, -height }; glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop); int x = tx(); int y = ty(); - y = fbHeight - (y + t.height); + y = fbHeight - (y + height); while (iterator.iterate(&r)) { const GLint sy = fbHeight - (r.top + r.height()); glScissor(r.left, sy, r.width(), r.height()); - glDrawTexiOES(x, y, 0, t.width, t.height); + glDrawTexiOES(x, y, 0, width, height); } } } diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h index c177c2a4faf2c..509dedd743f17 100644 --- a/libs/surfaceflinger/LayerBase.h +++ b/libs/surfaceflinger/LayerBase.h @@ -40,6 +40,7 @@ class DisplayHardware; class GraphicPlane; class Client; class SurfaceBuffer; +class Buffer; // --------------------------------------------------------------------------- @@ -239,7 +240,7 @@ protected: void drawWithOpenGL(const Region& clip, GLint textureName, - const GGLSurface& surface, + const sp& buffer, int transform = 0) const; void clearWithOpenGL(const Region& clip) const; diff --git a/libs/surfaceflinger/LayerBitmap.cpp b/libs/surfaceflinger/LayerBitmap.cpp index d633a2d52bf45..38d4bcf02f7d7 100644 --- a/libs/surfaceflinger/LayerBitmap.cpp +++ b/libs/surfaceflinger/LayerBitmap.cpp @@ -52,10 +52,7 @@ Buffer::Buffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) Buffer::~Buffer() { if (handle) { - BufferAllocator& allocator = BufferAllocator::get(); - if (usage & BufferAllocator::USAGE_SW_READ_MASK) { - allocator.unmap(handle); - } + BufferAllocator& allocator(BufferAllocator::get()); allocator.free(handle); } } @@ -107,9 +104,6 @@ status_t Buffer::initSize(uint32_t w, uint32_t h) err = allocator.alloc(w, h, format, usage, &handle, &stride); if (err == NO_ERROR) { - if (usage & BufferAllocator::USAGE_SW_READ_MASK) { - err = allocator.map(handle, &bits); - } if (err == NO_ERROR) { width = w; height = h; @@ -120,31 +114,22 @@ status_t Buffer::initSize(uint32_t w, uint32_t h) return err; } -status_t Buffer::getBitmapSurface(copybit_image_t* img) const +status_t Buffer::lock(GGLSurface* sur, uint32_t usage) { - img->w = stride ?: width; - img->h = mVStride ?: height; - img->format = format; - - // FIXME: this should use a native_handle - img->offset = 0; - img->base = bits; - img->fd = getHandle()->data[0]; - - return NO_ERROR; + status_t res = SurfaceBuffer::lock(usage); + if (res == NO_ERROR && sur) { + sur->version = sizeof(GGLSurface); + sur->width = width; + sur->height = height; + sur->stride = stride; + sur->format = format; + sur->vstride = mVStride; + sur->data = static_cast(bits); + } + return res; } -status_t Buffer::getBitmapSurface(GGLSurface* sur) const -{ - sur->version = sizeof(GGLSurface); - sur->width = width; - sur->height = height; - sur->stride = stride; - sur->format = format; - sur->vstride = mVStride; - sur->data = static_cast(bits); - return NO_ERROR; -} + // =========================================================================== // LayerBitmap diff --git a/libs/surfaceflinger/LayerBitmap.h b/libs/surfaceflinger/LayerBitmap.h index e6737550f2812..6e136a2ae7649 100644 --- a/libs/surfaceflinger/LayerBitmap.h +++ b/libs/surfaceflinger/LayerBitmap.h @@ -73,9 +73,8 @@ public: PixelFormat getPixelFormat() const { return format; } Rect getBounds() const { return Rect(width, height); } - status_t getBitmapSurface(copybit_image_t* img) const; - status_t getBitmapSurface(GGLSurface* surface) const; - + status_t lock(GGLSurface* surface, uint32_t usage); + android_native_buffer_t* getNativeBuffer() const; private: diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp index 9339b8758cc1e..8be91c9febf19 100644 --- a/libs/surfaceflinger/LayerBuffer.cpp +++ b/libs/surfaceflinger/LayerBuffer.cpp @@ -380,37 +380,37 @@ bool LayerBuffer::BufferSource::transformed() const void LayerBuffer::BufferSource::onDraw(const Region& clip) const { - sp buffer(getBuffer()); + // FIXME: we should get a native buffer here + /* + sp ourBbuffer(getBuffer()); if (UNLIKELY(buffer == 0)) { // nothing to do, we don't have a buffer mLayer.clearWithOpenGL(clip); return; } - status_t err = NO_ERROR; - NativeBuffer src(buffer->getBuffer()); - const Rect& transformedBounds = mLayer.getTransformedBounds(); - // FIXME: We should model this after the overlay stuff - if (UNLIKELY(mTextureName == -1LU)) { mTextureName = mLayer.createTexture(); } - GLuint w = 0; - GLuint h = 0; - GGLSurface t; - t.version = sizeof(GGLSurface); - t.width = src.crop.r; - t.height = src.crop.b; - t.stride = src.img.w; - t.vstride= src.img.h; - t.format = src.img.format; - t.data = (GGLubyte*)(intptr_t(src.img.base) + src.img.offset); - const Region dirty(Rect(t.width, t.height)); // FIXME: Use EGLImage extension for this - mLayer.loadTexture(dirty, mTextureName, t, w, h); - mLayer.drawWithOpenGL(clip, mTextureName, t, mBufferHeap.transform); + + + + GGLSurface t; + status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_RARELY); + if (res == NO_ERROR) { + GLuint w = 0; + GLuint h = 0; + const Region dirty(Rect(buffer->width, buffer->height)); + mLayer.loadTexture(dirty, mTextureName, t, w, h); + buffer->unlock(); + } + if (res == NO_ERROR) { + mLayer.drawWithOpenGL(clip, mTextureName, buffer, mBufferHeap.transform); + } + */ } diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp index 6b421588e19c5..5fd979e0614ba 100644 --- a/libs/surfaceflinger/SurfaceFlinger.cpp +++ b/libs/surfaceflinger/SurfaceFlinger.cpp @@ -50,8 +50,6 @@ #include "LayerBuffer.h" #include "LayerDim.h" #include "LayerBitmap.h" -#include "LayerOrientationAnim.h" -#include "OrientationAnimation.h" #include "SurfaceFlinger.h" #include "DisplayHardware/DisplayHardware.h" @@ -206,7 +204,6 @@ void SurfaceFlinger::init() SurfaceFlinger::~SurfaceFlinger() { glDeleteTextures(1, &mWormholeTexName); - delete mOrientationAnimation; } overlay_control_device_t* SurfaceFlinger::getOverlayEngine() const @@ -399,8 +396,6 @@ status_t SurfaceFlinger::readyToRun() * We're now ready to accept clients... */ - mOrientationAnimation = new OrientationAnimation(this); - // the boot animation! if (mDebugNoBootAnimation == false) mBootAnimation = new BootAnimation(this); @@ -513,16 +508,17 @@ bool SurfaceFlinger::threadLoop() void SurfaceFlinger::postFramebuffer() { - const bool skip = mOrientationAnimation->run(); - if (UNLIKELY(skip)) { + if (isFrozen()) { + // we are not allowed to draw, but pause a bit to make sure + // apps don't end up using the whole CPU, if they depend on + // surfaceflinger for synchronization. + usleep(8333); // 8.3ms ~ 120fps return; } if (!mInvalidRegion.isEmpty()) { const DisplayHardware& hw(graphicPlane(0).displayHardware()); - hw.flip(mInvalidRegion); - mInvalidRegion.clear(); } } @@ -616,7 +612,6 @@ void SurfaceFlinger::handleTransaction(uint32_t transactionFlags) mVisibleRegionsDirty = true; mDirtyRegion.set(hw.bounds()); mFreezeDisplayTime = 0; - mOrientationAnimation->onOrientationChanged(type); } if (mCurrentState.freezeDisplay != mDrawingState.freezeDisplay) { @@ -893,19 +888,26 @@ void SurfaceFlinger::executeScheduledBroadcasts() void SurfaceFlinger::debugFlashRegions() { - if (UNLIKELY(!mDirtyRegion.isRect())) { - // TODO: do this only if we don't have preserving - // swapBuffer. If we don't have update-on-demand, - // redraw everything. - composeSurfaces(Region(mDirtyRegion.bounds())); - } - + const DisplayHardware& hw(graphicPlane(0).displayHardware()); + const uint32_t flags = hw.getFlags(); + if (!(flags & DisplayHardware::BUFFER_PRESERVED)) { + const Region repaint((flags & DisplayHardware::UPDATE_ON_DEMAND) ? + mDirtyRegion.bounds() : hw.bounds()); + composeSurfaces(repaint); + } + glDisable(GL_TEXTURE_2D); glDisable(GL_BLEND); glDisable(GL_DITHER); glDisable(GL_SCISSOR_TEST); - glColor4x(0x10000, 0, 0x10000, 0x10000); + static int toggle = 0; + toggle = 1 - toggle; + if (toggle) { + glColor4x(0x10000, 0, 0x10000, 0x10000); + } else { + glColor4x(0x10000, 0x10000, 0, 0x10000); + } Rect r; Region::iterator iterator(mDirtyRegion); @@ -919,8 +921,7 @@ void SurfaceFlinger::debugFlashRegions() glVertexPointer(2, GL_FLOAT, 0, vertices); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } - - const DisplayHardware& hw(graphicPlane(0).displayHardware()); + hw.flip(mDirtyRegion.merge(mInvalidRegion)); mInvalidRegion.clear(); diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h index 319f80e9e926f..d5e525273c77a 100644 --- a/libs/surfaceflinger/SurfaceFlinger.h +++ b/libs/surfaceflinger/SurfaceFlinger.h @@ -55,8 +55,6 @@ class DisplayHardware; class FreezeLock; class Layer; class LayerBuffer; -class LayerOrientationAnim; -class OrientationAnimation; typedef int32_t ClientID; @@ -335,8 +333,6 @@ private: bool mFreezeDisplay; int32_t mFreezeCount; nsecs_t mFreezeDisplayTime; - friend class OrientationAnimation; - OrientationAnimation* mOrientationAnimation; // don't use a lock for these, we don't care int mDebugRegion; diff --git a/libs/surfaceflinger/LayerOrientationAnim.cpp b/libs/surfaceflinger/purgatory/LayerOrientationAnim.cpp similarity index 100% rename from libs/surfaceflinger/LayerOrientationAnim.cpp rename to libs/surfaceflinger/purgatory/LayerOrientationAnim.cpp diff --git a/libs/surfaceflinger/LayerOrientationAnim.h b/libs/surfaceflinger/purgatory/LayerOrientationAnim.h similarity index 100% rename from libs/surfaceflinger/LayerOrientationAnim.h rename to libs/surfaceflinger/purgatory/LayerOrientationAnim.h diff --git a/libs/surfaceflinger/LayerOrientationAnimRotate.cpp b/libs/surfaceflinger/purgatory/LayerOrientationAnimRotate.cpp similarity index 100% rename from libs/surfaceflinger/LayerOrientationAnimRotate.cpp rename to libs/surfaceflinger/purgatory/LayerOrientationAnimRotate.cpp diff --git a/libs/surfaceflinger/LayerOrientationAnimRotate.h b/libs/surfaceflinger/purgatory/LayerOrientationAnimRotate.h similarity index 100% rename from libs/surfaceflinger/LayerOrientationAnimRotate.h rename to libs/surfaceflinger/purgatory/LayerOrientationAnimRotate.h diff --git a/libs/surfaceflinger/OrientationAnimation.cpp b/libs/surfaceflinger/purgatory/OrientationAnimation.cpp similarity index 100% rename from libs/surfaceflinger/OrientationAnimation.cpp rename to libs/surfaceflinger/purgatory/OrientationAnimation.cpp diff --git a/libs/surfaceflinger/OrientationAnimation.h b/libs/surfaceflinger/purgatory/OrientationAnimation.h similarity index 100% rename from libs/surfaceflinger/OrientationAnimation.h rename to libs/surfaceflinger/purgatory/OrientationAnimation.h diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk index 577dd4bf79044..d44d2f965be41 100644 --- a/libs/ui/Android.mk +++ b/libs/ui/Android.mk @@ -5,9 +5,9 @@ LOCAL_SRC_FILES:= \ BufferMapper.cpp \ Camera.cpp \ CameraParameters.cpp \ - EGLNativeWindowSurface.cpp \ EventHub.cpp \ EventRecurrence.cpp \ + FramebufferNativeWindow.cpp \ KeyLayoutMap.cpp \ KeyCharacterMap.cpp \ ICamera.cpp \ diff --git a/libs/ui/BufferMapper.cpp b/libs/ui/BufferMapper.cpp index 85a029bcc0d28..1a75c5d9acdfa 100644 --- a/libs/ui/BufferMapper.cpp +++ b/libs/ui/BufferMapper.cpp @@ -17,14 +17,9 @@ #define LOG_TAG "BufferMapper" #include -#include -#include #include -#include -#include #include -#include #include #include @@ -34,12 +29,6 @@ #include -// --------------------------------------------------------------------------- -// enable mapping debugging -#define DEBUG_MAPPINGS 0 -// never remove mappings from the list -#define DEBUG_MAPPINGS_KEEP_ALL 0 -// --------------------------------------------------------------------------- namespace android { // --------------------------------------------------------------------------- @@ -57,34 +46,27 @@ BufferMapper::BufferMapper() } } -status_t BufferMapper::map(buffer_handle_t handle, void** addr, const void* id) +status_t BufferMapper::registerBuffer(buffer_handle_t handle) { - Mutex::Autolock _l(mLock); - status_t err = mAllocMod->map(mAllocMod, handle, addr); - LOGW_IF(err, "map(...) failed %d (%s)", err, strerror(-err)); -#if DEBUG_MAPPINGS - if (err == NO_ERROR) - logMapLocked(handle, id); -#endif + status_t err = mAllocMod->registerBuffer(mAllocMod, handle); + LOGW_IF(err, "registerBuffer(%p) failed %d (%s)", + handle, err, strerror(-err)); return err; } -status_t BufferMapper::unmap(buffer_handle_t handle, const void* id) +status_t BufferMapper::unregisterBuffer(buffer_handle_t handle) { - Mutex::Autolock _l(mLock); - status_t err = mAllocMod->unmap(mAllocMod, handle); - LOGW_IF(err, "unmap(...) failed %d (%s)", err, strerror(-err)); -#if DEBUG_MAPPINGS - if (err == NO_ERROR) - logUnmapLocked(handle, id); -#endif + status_t err = mAllocMod->unregisterBuffer(mAllocMod, handle); + LOGW_IF(err, "unregisterBuffer(%p) failed %d (%s)", + handle, err, strerror(-err)); return err; } -status_t BufferMapper::lock(buffer_handle_t handle, int usage, const Rect& bounds) +status_t BufferMapper::lock(buffer_handle_t handle, + int usage, const Rect& bounds, void** vaddr) { status_t err = mAllocMod->lock(mAllocMod, handle, usage, - bounds.left, bounds.top, bounds.width(), bounds.height()); + bounds.left, bounds.top, bounds.width(), bounds.height(), vaddr); LOGW_IF(err, "unlock(...) failed %d (%s)", err, strerror(-err)); return err; } @@ -96,65 +78,5 @@ status_t BufferMapper::unlock(buffer_handle_t handle) return err; } -void BufferMapper::logMapLocked(buffer_handle_t handle, const void* id) -{ - CallStack stack; - stack.update(2); - - map_info_t info; - info.id = id; - info.stack = stack; - - ssize_t index = mMapInfo.indexOfKey(handle); - if (index >= 0) { - Vector& infos = mMapInfo.editValueAt(index); - infos.add(info); - } else { - Vector infos; - infos.add(info); - mMapInfo.add(handle, infos); - } -} - -void BufferMapper::logUnmapLocked(buffer_handle_t handle, const void* id) -{ - ssize_t index = mMapInfo.indexOfKey(handle); - if (index < 0) { - LOGE("unmapping %p which doesn't exist in our map!", handle); - return; - } - - Vector& infos = mMapInfo.editValueAt(index); - ssize_t count = infos.size(); - for (int i=0 ; i& infos = mMapInfo.valueAt(index); - ssize_t count = infos.size(); - for (int i=0 ; i #include @@ -28,7 +28,7 @@ #include #include -#include +#include #include @@ -87,13 +87,6 @@ FramebufferNativeWindow::FramebufferNativeWindow() LOGE_IF(err, "fb buffer 1 allocation failed w=%d, h=%d, err=%s", fbDev->width, fbDev->height, strerror(-err)); - - gralloc_module_t* m = - reinterpret_cast(grDev->common.module); - - // FIXME: do we actually need to map the framebuffer? - m->map(m, buffers[0]->handle, &buffers[0]->bits); - m->map(m, buffers[1]->handle, &buffers[1]->bits); } uint32_t flags = fbDev->flags & SURFACE_FLAG_MAPPED; @@ -125,10 +118,7 @@ FramebufferNativeWindow::FramebufferNativeWindow() const_cast(android_native_window_t::maxSwapInterval) = fbDev->maxSwapInterval; - android_native_window_t::connect = connect; - android_native_window_t::disconnect = disconnect; android_native_window_t::setSwapInterval = setSwapInterval; - android_native_window_t::setSwapRectangle = setSwapRectangle; android_native_window_t::dequeueBuffer = dequeueBuffer; android_native_window_t::lockBuffer = lockBuffer; android_native_window_t::queueBuffer = queueBuffer; @@ -137,10 +127,6 @@ FramebufferNativeWindow::FramebufferNativeWindow() FramebufferNativeWindow::~FramebufferNativeWindow() { grDev->free(grDev, buffers[0]->handle); grDev->free(grDev, buffers[1]->handle); - gralloc_module_t* m = - reinterpret_cast(grDev->common.module); - m->unmap(m, buffers[0]->handle); - m->unmap(m, buffers[1]->handle); gralloc_close(grDev); framebuffer_close(fbDev); } @@ -160,13 +146,10 @@ int FramebufferNativeWindow::setSwapInterval( return fb->setSwapInterval(fb, interval); } -int FramebufferNativeWindow::setSwapRectangle(android_native_window_t* window, - int l, int t, int w, int h) +void FramebufferNativeWindow::setSwapRectangle(const Rect& dirty) { - FramebufferNativeWindow* self = getSelf(window); - Mutex::Autolock _l(self->mutex); - self->mDirty = Rect(l, t, l+w, t+h); - return 0; + Mutex::Autolock _l(mutex); + mDirty = dirty; } int FramebufferNativeWindow::dequeueBuffer(android_native_window_t* window, @@ -201,16 +184,8 @@ int FramebufferNativeWindow::lockBuffer(android_native_window_t* window, while (self->front == buffer) { self->mCondition.wait(self->mutex); } - - gralloc_module_t* m = - reinterpret_cast(self->grDev->common.module); - const Rect& dirty(self->mDirty); - buffer_handle_t handle = static_cast(buffer)->handle; - int res = m->lock(m, handle, GRALLOC_USAGE_HW_FB, - dirty.left, dirty.right, dirty.width(), dirty.height()); - - return res; + return NO_ERROR; } int FramebufferNativeWindow::queueBuffer(android_native_window_t* window, @@ -219,13 +194,8 @@ int FramebufferNativeWindow::queueBuffer(android_native_window_t* window, FramebufferNativeWindow* self = getSelf(window); Mutex::Autolock _l(self->mutex); framebuffer_device_t* fb = self->fbDev; - gralloc_module_t* m = - reinterpret_cast(self->grDev->common.module); - buffer_handle_t handle = static_cast(buffer)->handle; - m->unlock(m, handle); int res = fb->post(fb, handle); - self->front = static_cast(buffer); self->mNumFreeBuffers++; self->mCondition.broadcast(); diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp index 26e694a70ad59..30da911fc72cd 100644 --- a/libs/ui/Region.cpp +++ b/libs/ui/Region.cpp @@ -88,6 +88,13 @@ void Region::set(const Rect& r) mRegion.setRect(ir); } +void Region::set(uint32_t w, uint32_t h) +{ + SkIRect ir; + ir.set(0, 0, w, h); + mRegion.setRect(ir); +} + // ---------------------------------------------------------------------------- Region& Region::orSelf(const Rect& r) diff --git a/libs/ui/Surface.cpp b/libs/ui/Surface.cpp index fb105b346c7e7..68fd9632cc124 100644 --- a/libs/ui/Surface.cpp +++ b/libs/ui/Surface.cpp @@ -31,7 +31,6 @@ #include #include -#include #include #include #include @@ -53,7 +52,7 @@ namespace android { ANDROID_SINGLETON_STATIC_INSTANCE( SurfaceBuffer ) SurfaceBuffer::SurfaceBuffer() - : BASE(), handle(0), mOwner(false) + : BASE(), handle(0), mOwner(false), mBufferMapper(BufferMapper::get()) { width = height = @@ -64,7 +63,7 @@ SurfaceBuffer::SurfaceBuffer() } SurfaceBuffer::SurfaceBuffer(const Parcel& data) - : BASE(), handle(0), mOwner(true) + : BASE(), handle(0), mOwner(true), mBufferMapper(BufferMapper::get()) { // we own the handle in this case width = data.readInt32(); @@ -91,6 +90,26 @@ int SurfaceBuffer::getHandle(android_native_buffer_t const * base, return 0; } +status_t SurfaceBuffer::lock(uint32_t usage) +{ + const Rect lockBounds(width, height); + status_t res = lock(usage, lockBounds); + return res; +} + +status_t SurfaceBuffer::lock(uint32_t usage, const Rect& rect) +{ + status_t res = getBufferMapper().lock(handle, usage, rect, &bits); + return res; +} + +status_t SurfaceBuffer::unlock() +{ + status_t res = getBufferMapper().unlock(handle); + bits = NULL; + return res; +} + status_t SurfaceBuffer::writeToParcel(Parcel* reply, android_native_buffer_t const* buffer) { @@ -110,9 +129,17 @@ status_t SurfaceBuffer::writeToParcel(Parcel* reply, // ---------------------------------------------------------------------- -static void copyBlt(const android_native_buffer_t* dst, - const android_native_buffer_t* src, const Region& reg) +static void copyBlt( + const sp& dst, + const sp& src, + const Region& reg) { + src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds()); + uint8_t const * const src_bits = (uint8_t const *)src->bits; + + dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds()); + uint8_t* const dst_bits = (uint8_t*)dst->bits; + Region::iterator iterator(reg); if (iterator) { // NOTE: dst and src must be the same format @@ -120,29 +147,29 @@ static void copyBlt(const android_native_buffer_t* dst, const size_t bpp = bytesPerPixel(src->format); const size_t dbpr = dst->stride * bpp; const size_t sbpr = src->stride * bpp; + while (iterator.iterate(&r)) { - ssize_t h = r.bottom - r.top; - if (h) { - size_t size = (r.right - r.left) * bpp; - uint8_t* s = (GGLubyte*)src->bits + - (r.left + src->stride * r.top) * bpp; - uint8_t* d = (GGLubyte*)dst->bits + - (r.left + dst->stride * r.top) * bpp; - if (dbpr==sbpr && size==sbpr) { - size *= h; - h = 1; - } - do { - memcpy(d, s, size); - d += dbpr; - s += sbpr; - } while (--h > 0); + ssize_t h = r.height(); + if (h <= 0) continue; + size_t size = r.width() * bpp; + uint8_t const * s = src_bits + (r.left + src->stride * r.top) * bpp; + uint8_t * d = dst_bits + (r.left + dst->stride * r.top) * bpp; + if (dbpr==sbpr && size==sbpr) { + size *= h; + h = 1; } + do { + memcpy(d, s, size); + d += dbpr; + s += sbpr; + } while (--h > 0); } } + + src->unlock(); + dst->unlock(); } - // ============================================================================ // SurfaceControl // ============================================================================ @@ -347,12 +374,14 @@ sp SurfaceControl::getSurface() const Surface::Surface(const sp& surface) : mClient(surface->mClient), mSurface(surface->mSurface), mToken(surface->mToken), mIdentity(surface->mIdentity), - mFormat(surface->mFormat), mFlags(surface->mFlags) + mFormat(surface->mFormat), mFlags(surface->mFlags), + mBufferMapper(BufferMapper::get()) { init(); } Surface::Surface(const Parcel& parcel) + : mBufferMapper(BufferMapper::get()) { sp clientBinder = parcel.readStrongBinder(); mSurface = interface_cast(parcel.readStrongBinder()); @@ -369,16 +398,11 @@ Surface::Surface(const Parcel& parcel) void Surface::init() { - android_native_window_t::connect = connect; - android_native_window_t::disconnect = disconnect; android_native_window_t::setSwapInterval = setSwapInterval; - android_native_window_t::setSwapRectangle = setSwapRectangle; android_native_window_t::dequeueBuffer = dequeueBuffer; android_native_window_t::lockBuffer = lockBuffer; android_native_window_t::queueBuffer = queueBuffer; - mSwapRectangle.makeInvalid(); - DisplayInfo dinfo; SurfaceComposerClient::getDisplayInfo(0, &dinfo); const_cast(android_native_window_t::xdpi) = dinfo.xdpi; @@ -396,7 +420,7 @@ Surface::~Surface() // its buffers in this process. for (int i=0 ; i<2 ; i++) { if (mBuffers[i] != 0) { - BufferMapper::get().unmap(mBuffers[i]->getHandle(), this); + getBufferMapper().unregisterBuffer(mBuffers[i]->getHandle()); } } @@ -443,22 +467,6 @@ bool Surface::isSameSurface( // ---------------------------------------------------------------------------- -int Surface::setSwapRectangle(android_native_window_t* window, - int l, int t, int w, int h) -{ - Surface* self = getSelf(window); - self->setSwapRectangle(Rect(l, t, l+w, t+h)); - return 0; -} - -void Surface::connect(android_native_window_t* window) -{ -} - -void Surface::disconnect(android_native_window_t* window) -{ -} - int Surface::setSwapInterval(android_native_window_t* window, int interval) { return 0; @@ -487,6 +495,26 @@ int Surface::queueBuffer(android_native_window_t* window, // ---------------------------------------------------------------------------- +status_t Surface::dequeueBuffer(sp* buffer) +{ + android_native_buffer_t* out; + status_t err = dequeueBuffer(&out); + *buffer = SurfaceBuffer::getSelf(out); + return err; +} + +status_t Surface::lockBuffer(const sp& buffer) +{ + return lockBuffer(buffer.get()); +} + +status_t Surface::queueBuffer(const sp& buffer) +{ + return queueBuffer(buffer.get()); +} + +// ---------------------------------------------------------------------------- + int Surface::dequeueBuffer(android_native_buffer_t** buffer) { // FIXME: dequeueBuffer() needs proper implementation @@ -515,8 +543,9 @@ int Surface::dequeueBuffer(android_native_buffer_t** buffer) } const sp& backBuffer(mBuffers[backIdx]); + mDirtyRegion.set(backBuffer->width, backBuffer->height); *buffer = backBuffer.get(); - + return NO_ERROR; } @@ -542,11 +571,14 @@ int Surface::queueBuffer(android_native_buffer_t* buffer) if (err != NO_ERROR) return err; + if (mSwapRectangle.isValid()) { + mDirtyRegion.set(mSwapRectangle); + } + // transmit the dirty region - const Region dirty(swapRectangle()); SurfaceID index(mToken); layer_cblk_t* const lcblk = &(cblk->layers[index]); - _send_dirty_region(lcblk, dirty); + _send_dirty_region(lcblk, mDirtyRegion); uint32_t newstate = cblk->unlock_layer_and_post(size_t(index)); if (!(newstate & eNextFlipPending)) @@ -561,27 +593,20 @@ status_t Surface::lock(SurfaceInfo* info, bool blocking) { return Surface::lock(info, NULL, blocking); } -status_t Surface::lock(SurfaceInfo* other, Region* dirty, bool blocking) +status_t Surface::lock(SurfaceInfo* other, Region* dirtyIn, bool blocking) { // FIXME: needs some locking here - android_native_buffer_t* backBuffer; + + sp backBuffer; status_t err = dequeueBuffer(&backBuffer); if (err == NO_ERROR) { err = lockBuffer(backBuffer); if (err == NO_ERROR) { - backBuffer->common.incRef(&backBuffer->common); - mLockedBuffer = backBuffer; - other->w = backBuffer->width; - other->h = backBuffer->height; - other->s = backBuffer->stride; - other->usage = backBuffer->usage; - other->format = backBuffer->format; - other->bits = backBuffer->bits; - // we handle copy-back here... const Rect bounds(backBuffer->width, backBuffer->height); - Region newDirtyRegion; + Region scratch(bounds); + Region& newDirtyRegion(dirtyIn ? *dirtyIn : scratch); per_client_cblk_t* const cblk = mClient->mControl; layer_cblk_t* const lcblk = &(cblk->layers[SurfaceID(mToken)]); @@ -590,43 +615,34 @@ status_t Surface::lock(SurfaceInfo* other, Region* dirty, bool blocking) // content is meaningless in this case and the whole surface // needs to be redrawn. newDirtyRegion.set(bounds); - if (dirty) { - *dirty = newDirtyRegion; - } - } else - { - if (dirty) { - dirty->andSelf(Region(bounds)); - newDirtyRegion = *dirty; - } else { - newDirtyRegion.set(bounds); - } - Region copyback; + } else { + newDirtyRegion.andSelf(bounds); if (!(lcblk->flags & eNoCopyBack)) { - const Region previousDirtyRegion(dirtyRegion()); - copyback = previousDirtyRegion.subtract(newDirtyRegion); - } - const sp& frontBuffer(mBuffers[1-mBackbufferIndex]); - if (!copyback.isEmpty() && frontBuffer!=0) { - // copy front to back - copyBlt(backBuffer, frontBuffer.get(), copyback); + const sp& frontBuffer(mBuffers[1-mBackbufferIndex]); + const Region copyback(mOldDirtyRegion.subtract(newDirtyRegion)); + if (!copyback.isEmpty() && frontBuffer!=0) { + // copy front to back + copyBlt(backBuffer, frontBuffer, copyback); + } } } - setDirtyRegion(newDirtyRegion); + mDirtyRegion = newDirtyRegion; + mOldDirtyRegion = newDirtyRegion; - - Rect lockBounds(backBuffer->width, backBuffer->height); - if (dirty) { - lockBounds = dirty->bounds(); - } - buffer_handle_t handle; - backBuffer->getHandle(backBuffer, &handle); - status_t res = BufferMapper::get().lock(handle, - GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, - lockBounds); + status_t res = backBuffer->lock( + GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, + newDirtyRegion.bounds()); + LOGW_IF(res, "failed locking buffer %d (%p)", - mBackbufferIndex, handle); - setSwapRectangle(lockBounds); + mBackbufferIndex, backBuffer->handle); + + mLockedBuffer = backBuffer; + other->w = backBuffer->width; + other->h = backBuffer->height; + other->s = backBuffer->stride; + other->usage = backBuffer->usage; + other->format = backBuffer->format; + other->bits = backBuffer->bits; } } return err; @@ -639,16 +655,12 @@ status_t Surface::unlockAndPost() if (mLockedBuffer == 0) return BAD_VALUE; - buffer_handle_t handle; - mLockedBuffer->getHandle(mLockedBuffer, &handle); - status_t res = BufferMapper::get().unlock(handle); + status_t res = mLockedBuffer->unlock(); LOGW_IF(res, "failed unlocking buffer %d (%p)", - mBackbufferIndex, handle); - - const Rect dirty(dirtyRegion().bounds()); - setSwapRectangle(dirty); + mBackbufferIndex, mLockedBuffer->handle); + status_t err = queueBuffer(mLockedBuffer); - mLockedBuffer->common.decRef(&mLockedBuffer->common); + mLockedBuffer->bits = NULL; mLockedBuffer = 0; return err; } @@ -666,15 +678,6 @@ void Surface::_send_dirty_region( } } -Region Surface::dirtyRegion() const { - return mDirtyRegion; -} -void Surface::setDirtyRegion(const Region& region) const { - mDirtyRegion = region; -} -const Rect& Surface::swapRectangle() const { - return mSwapRectangle; -} void Surface::setSwapRectangle(const Rect& r) { mSwapRectangle = r; } @@ -687,10 +690,10 @@ status_t Surface::getBufferLocked(int index) if (buffer != 0) { sp& currentBuffer(mBuffers[index]); if (currentBuffer != 0) { - BufferMapper::get().unmap(currentBuffer->getHandle(), this); + getBufferMapper().unregisterBuffer(currentBuffer->getHandle()); currentBuffer.clear(); } - err = BufferMapper::get().map(buffer->getHandle(), &buffer->bits, this); + err = getBufferMapper().registerBuffer(buffer->getHandle()); LOGW_IF(err, "map(...) failed %d (%s)", err, strerror(-err)); if (err == NO_ERROR) { currentBuffer = buffer; diff --git a/opengl/include/EGL/android_natives.h b/opengl/include/EGL/android_natives.h index e3c3b86e49f40..329705b65a8c6 100644 --- a/opengl/include/EGL/android_natives.h +++ b/opengl/include/EGL/android_natives.h @@ -96,18 +96,6 @@ struct android_native_window_t /* Some storage reserved for the OEM's driver. */ intptr_t oem[4]; - /* - * hook called by EGL when the native surface is made current - * (eglMakeCurrent()). This hook can be NULL. - */ - void (*connect)(struct android_native_window_t* window); - - /* - * hook called by EGL when the native surface in not current any-longer. - * This hook can be NULL. - */ - void (*disconnect)(struct android_native_window_t* window); - /* * Set the swap interval for this surface. @@ -117,20 +105,10 @@ struct android_native_window_t int (*setSwapInterval)(struct android_native_window_t* window, int interval); - - /* - * FIXME: needs documentation for setSwapRectangle - * tentative: rect used during queueBuffer to indicate which part of - * the screen needs updating. - */ - int (*setSwapRectangle)(struct android_native_window_t* window, - int left, int top, int width, int height); - - /* * hook called by EGL to acquire a buffer. After this call, the buffer * is not locked, so its content cannot be modified. - * this call may block if no buffers are availlable. + * this call may block if no buffers are available. * * Returns 0 on success or -errno on error. */ @@ -179,7 +157,7 @@ struct android_native_buffer_t int stride; int format; int usage; - void* bits; // non-zero if buffer is mmaped + void* bits; // non-zero if buffer is locked for sw usage void* reserved[2]; diff --git a/opengl/libagl/TextureObjectManager.cpp b/opengl/libagl/TextureObjectManager.cpp index f927de95ecae1..9eb99f0bc2319 100644 --- a/opengl/libagl/TextureObjectManager.cpp +++ b/opengl/libagl/TextureObjectManager.cpp @@ -23,7 +23,7 @@ namespace android { // ---------------------------------------------------------------------------- EGLTextureObject::EGLTextureObject() - : mCount(0), mSize(0) + : mSize(0) { init(); } @@ -56,6 +56,7 @@ void EGLTextureObject::init() #ifdef LIBAGL_USE_GRALLOC_COPYBITS copybits_fd = -1; #endif // LIBAGL_USE_GRALLOC_COPYBITS + buffer = 0; } void EGLTextureObject::copyParameters(const sp& old) @@ -126,6 +127,7 @@ status_t EGLTextureObject::setSurface(GGLSurface const* s) } surface = *s; internalformat = 0; + buffer = 0; // we should keep the crop_rect, but it's delicate because // the new size of the surface could make it invalid. @@ -144,6 +146,20 @@ status_t EGLTextureObject::setSurface(GGLSurface const* s) return NO_ERROR; } +status_t EGLTextureObject::setImage(android_native_buffer_t* native_buffer) +{ + GGLSurface sur; + sur.version = sizeof(GGLSurface); + sur.width = native_buffer->width; + sur.height= native_buffer->height; + sur.stride= native_buffer->stride; + sur.format= native_buffer->format; + sur.data = 0; + setSurface(&sur); + buffer = native_buffer; + return NO_ERROR; +} + status_t EGLTextureObject::reallocate( GLint level, int w, int h, int s, int format, int compressedFormat, int bpr) @@ -227,7 +243,7 @@ status_t EGLTextureObject::reallocate( // ---------------------------------------------------------------------------- EGLSurfaceManager::EGLSurfaceManager() - : TokenManager(), mCount(0) + : TokenManager() { } diff --git a/opengl/libagl/TextureObjectManager.h b/opengl/libagl/TextureObjectManager.h index 497528c76b0e9..29d50370eb41d 100644 --- a/opengl/libagl/TextureObjectManager.h +++ b/opengl/libagl/TextureObjectManager.h @@ -30,6 +30,7 @@ #include #include +#include #include "Tokenizer.h" #include "TokenManager.h" @@ -39,22 +40,20 @@ namespace android { // ---------------------------------------------------------------------------- -class EGLTextureObject +class EGLTextureObject : public LightRefBase { public: EGLTextureObject(); ~EGLTextureObject(); - // protocol for sp<> - inline void incStrong(const void* id) const; - inline void decStrong(const void* id) const; - inline uint32_t getStrongCount() const; + status_t setSurface(GGLSurface const* s); + status_t setImage(android_native_buffer_t* buffer); + void setImageBits(void* vaddr) { surface.data = (GGLubyte*)vaddr; } - status_t setSurface(GGLSurface const* s); status_t reallocate(GLint level, int w, int h, int s, int format, int compressedFormat, int bpr); - inline size_t size() const; + inline size_t size() const { return mSize; } const GGLSurface& mip(int lod) const; GGLSurface& editMip(int lod); bool hasMipmaps() const { return mMipmaps!=0; } @@ -65,7 +64,6 @@ private: status_t allocateMipmaps(); void freeMipmaps(); void init(); - mutable int32_t mCount; size_t mSize; GGLSurface *mMipmaps; int mNumExtraLod; @@ -84,36 +82,19 @@ public: #ifdef LIBAGL_USE_GRALLOC_COPYBITS int copybits_fd; #endif // LIBAGL_USE_GRALLOC_COPYBITS + android_native_buffer_t* buffer; }; -void EGLTextureObject::incStrong(const void* id) const { - android_atomic_inc(&mCount); -} -void EGLTextureObject::decStrong(const void* id) const { - if (android_atomic_dec(&mCount) == 1) { - delete this; - } -} -uint32_t EGLTextureObject::getStrongCount() const { - return mCount; -} -size_t EGLTextureObject::size() const { - return mSize; -} - // ---------------------------------------------------------------------------- -class EGLSurfaceManager : public TokenManager +class EGLSurfaceManager : + public LightRefBase, + public TokenManager { public: EGLSurfaceManager(); ~EGLSurfaceManager(); - // protocol for sp<> - inline void incStrong(const void* id) const; - inline void decStrong(const void* id) const; - typedef void weakref_type; - sp createTexture(GLuint name); sp removeTexture(GLuint name); sp replaceTexture(GLuint name); @@ -121,21 +102,10 @@ public: sp texture(GLuint name); private: - mutable int32_t mCount; mutable Mutex mLock; KeyedVector< GLuint, sp > mTextures; }; -void EGLSurfaceManager::incStrong(const void* id) const { - android_atomic_inc(&mCount); -} -void EGLSurfaceManager::decStrong(const void* id) const { - if (android_atomic_dec(&mCount) == 1) { - delete this; - } -} - - // ---------------------------------------------------------------------------- }; // namespace android diff --git a/opengl/libagl/array.cpp b/opengl/libagl/array.cpp index eefe614c2fb75..6d2cc9111c84f 100644 --- a/opengl/libagl/array.cpp +++ b/opengl/libagl/array.cpp @@ -1371,9 +1371,18 @@ void glDrawArrays(GLenum mode, GLint first, GLsizei count) if ((c->cull.enable) && (c->cull.cullFace == GL_FRONT_AND_BACK)) return; // all triangles are culled + validate_arrays(c, mode); + + const uint32_t enables = c->rasterizer.state.enables; + if (enables & GGL_ENABLE_TMUS) + ogles_lock_textures(c); + drawArraysPrims[mode](c, first, count); + if (enables & GGL_ENABLE_TMUS) + ogles_unlock_textures(c); + #if VC_CACHE_STATISTICS c->vc.total = count; c->vc.dump_stats(mode); @@ -1425,8 +1434,16 @@ void glDrawElements( indices = c->arrays.element_array_buffer->data + uintptr_t(indices); } - drawElementsPrims[mode](c, count, indices); + const uint32_t enables = c->rasterizer.state.enables; + if (enables & GGL_ENABLE_TMUS) + ogles_lock_textures(c); + drawElementsPrims[mode](c, count, indices); + + if (enables & GGL_ENABLE_TMUS) + ogles_unlock_textures(c); + + #if VC_CACHE_STATISTICS c->vc.total = count; c->vc.dump_stats(mode); diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp index 9384e18dad1d2..04ca431778c25 100644 --- a/opengl/libagl/egl.cpp +++ b/opengl/libagl/egl.cpp @@ -212,8 +212,11 @@ struct egl_window_surface_v2_t : public egl_surface_t virtual EGLint getRefreshRate() const; virtual EGLint getSwapBehavior() const; private: + status_t lock(android_native_buffer_t* buf, int usage); + status_t unlock(android_native_buffer_t* buf); android_native_window_t* nativeWindow; android_native_buffer_t* buffer; + gralloc_module_t const* module; int width; int height; }; @@ -222,8 +225,13 @@ egl_window_surface_v2_t::egl_window_surface_v2_t(EGLDisplay dpy, EGLConfig config, int32_t depthFormat, android_native_window_t* window) - : egl_surface_t(dpy, config, depthFormat), nativeWindow(window), buffer(0) + : egl_surface_t(dpy, config, depthFormat), + nativeWindow(window), buffer(0), module(0) { + hw_module_t const* pModule; + hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule); + module = reinterpret_cast(pModule); + nativeWindow->common.incRef(&nativeWindow->common); nativeWindow->dequeueBuffer(nativeWindow, &buffer); @@ -246,13 +254,44 @@ egl_window_surface_v2_t::egl_window_surface_v2_t(EGLDisplay dpy, buffer->common.incRef(&buffer->common); nativeWindow->lockBuffer(nativeWindow, buffer); - // FIXME: we need to gralloc lock the buffer + // Lock the buffer + lock(buffer, GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN); + // FIXME: we need to handle the copy-back if needed, but // for now we're a "non preserving" implementation. } +status_t egl_window_surface_v2_t::lock( + android_native_buffer_t* buf, int usage) +{ + int err; + buffer_handle_t bufferHandle; + err = buf->getHandle(buf, &bufferHandle); + if (err < 0) + return err; + + err = module->lock(module, bufferHandle, + usage, 0, 0, buf->width, buf->height, &buf->bits); + return err; +} + +status_t egl_window_surface_v2_t::unlock(android_native_buffer_t* buf) +{ + int err; + buffer_handle_t bufferHandle; + err = buf->getHandle(buf, &bufferHandle); + if (err < 0) + return err; + + err = module->unlock(module, bufferHandle); + buf->bits = NULL; + return err; +} + + egl_window_surface_v2_t::~egl_window_surface_v2_t() { if (buffer) { + unlock(buffer); buffer->common.decRef(&buffer->common); } nativeWindow->common.decRef(&nativeWindow->common); @@ -269,6 +308,7 @@ EGLBoolean egl_window_surface_v2_t::swapBuffers() //mDisplaySurface->copyFrontToBack(copyback); + unlock(buffer); nativeWindow->queueBuffer(nativeWindow, buffer); buffer->common.decRef(&buffer->common); buffer = 0; @@ -278,6 +318,7 @@ EGLBoolean egl_window_surface_v2_t::swapBuffers() // TODO: lockBuffer should rather be executed when the very first // direct rendering occurs. nativeWindow->lockBuffer(nativeWindow, buffer); + lock(buffer, GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN); if ((width != buffer->width) || (height != buffer->height)) { @@ -1690,20 +1731,6 @@ EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, if (native_buffer->common.version != sizeof(android_native_buffer_t)) return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); - - hw_module_t const* pModule; - if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule)) - return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); - buffer_handle_t bufferHandle; - gralloc_module_t const* module = - reinterpret_cast(pModule); - if (native_buffer->getHandle(native_buffer, &bufferHandle) < 0) - return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); - int err = module->map(module, bufferHandle, &native_buffer->bits); - if (err < 0) { - LOGW_IF(err, "map(...) failed %d (%s)", err, strerror(-err)); - return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); - } native_buffer->common.incRef(&native_buffer->common); return (EGLImageKHR)native_buffer; @@ -1723,18 +1750,6 @@ EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img) if (native_buffer->common.version != sizeof(android_native_buffer_t)) return setError(EGL_BAD_PARAMETER, EGL_FALSE); - hw_module_t const* pModule; - if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule) == 0) { - buffer_handle_t bufferHandle; - gralloc_module_t const* module = - reinterpret_cast(pModule); - int err = native_buffer->getHandle(native_buffer, &bufferHandle); - if (err == 0) { - int err = module->unmap(module, bufferHandle); - LOGW_IF(err, "unmap(...) failed %d (%s)", err, strerror(-err)); - } - } - native_buffer->common.decRef(&native_buffer->common); return EGL_TRUE; diff --git a/opengl/libagl/texture.cpp b/opengl/libagl/texture.cpp index 9dca1338c2fb1..f2d8da3ca259f 100644 --- a/opengl/libagl/texture.cpp +++ b/opengl/libagl/texture.cpp @@ -103,7 +103,7 @@ void validate_tmu(ogles_context_t* c, int i) } } -void ogles_validate_texture_impl(ogles_context_t* c) +void ogles_validate_texture(ogles_context_t* c) { for (int i=0 ; irasterizer.state.texture[i].enable) @@ -117,6 +117,67 @@ void invalidate_texture(ogles_context_t* c, int tmu, uint8_t flags = 0xFF) { c->textures.tmu[tmu].dirty = flags; } +/* + * If the active textures are EGLImage, they need to be locked before + * they can be used. + * + * FIXME: code below is far from being optimal + * + */ + +void ogles_lock_textures(ogles_context_t* c) +{ + for (int i=0 ; irasterizer.state.texture[i].enable) { + texture_unit_t& u(c->textures.tmu[i]); + android_native_buffer_t* native_buffer = u.texture->buffer; + if (native_buffer) { + c->rasterizer.procs.activeTexture(c, i); + hw_module_t const* pModule; + if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule)) + continue; + + gralloc_module_t const* module = + reinterpret_cast(pModule); + buffer_handle_t bufferHandle; + native_buffer->getHandle(native_buffer, &bufferHandle); + int err = module->lock(module, bufferHandle, + GRALLOC_USAGE_SW_READ_OFTEN, + 0, 0, native_buffer->width, native_buffer->height, + &native_buffer->bits); + + u.texture->setImageBits(native_buffer->bits); + c->rasterizer.procs.bindTexture(c, &(u.texture->surface)); + } + } + } +} + +void ogles_unlock_textures(ogles_context_t* c) +{ + for (int i=0 ; irasterizer.state.texture[i].enable) { + texture_unit_t& u(c->textures.tmu[i]); + android_native_buffer_t* native_buffer = u.texture->buffer; + if (native_buffer) { + c->rasterizer.procs.activeTexture(c, i); + hw_module_t const* pModule; + if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule)) + continue; + + gralloc_module_t const* module = + reinterpret_cast(pModule); + buffer_handle_t bufferHandle; + native_buffer->getHandle(native_buffer, &bufferHandle); + module->unlock(module, bufferHandle); + u.texture->setImageBits(NULL); + c->rasterizer.procs.bindTexture(c, &(u.texture->surface)); + } + } + } + c->rasterizer.procs.activeTexture(c, c->textures.active); +} + // ---------------------------------------------------------------------------- #if 0 #pragma mark - @@ -592,6 +653,8 @@ invalid_enum: static void drawTexxOESImp(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h, ogles_context_t* c) { + ogles_lock_textures(c); + const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s; y = gglIntToFixed(cbSurface.height) - (y + h); w >>= FIXED_BITS; @@ -650,6 +713,8 @@ static void drawTexxOESImp(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h gglFixedToIntRound(y), gglFixedToIntRound(x)+w, gglFixedToIntRound(y)+h); + + ogles_unlock_textures(c); } static void drawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h, @@ -724,6 +789,8 @@ static void drawTexiOES(GLint x, GLint y, GLint z, GLint w, GLint h, ogles_conte goto slow_case; } + ogles_lock_textures(c); + c->rasterizer.procs.texCoord2i(c, s0, t0); const uint32_t enables = c->rasterizer.state.enables; if (ggl_unlikely(enables & (GGL_ENABLE_DEPTH_TEST|GGL_ENABLE_FOG))) @@ -734,6 +801,9 @@ static void drawTexiOES(GLint x, GLint y, GLint z, GLint w, GLint h, ogles_conte c->rasterizer.procs.disable(c, GGL_AA); c->rasterizer.procs.shadeModel(c, GL_FLAT); c->rasterizer.procs.recti(c, x, y, x+w, y+h); + + ogles_unlock_textures(c); + return; } } @@ -1460,23 +1530,9 @@ void glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image) return; } - if (native_buffer->bits == NULL) { - // this buffer cannot be used with this implementation - ogles_error(c, GL_INVALID_VALUE); - return; - } - - GGLSurface sur; - sur.version = sizeof(GGLSurface); - sur.width = native_buffer->width; - sur.height= native_buffer->height; - sur.stride= native_buffer->stride; - sur.format= native_buffer->format; - sur.data = (GGLubyte*)native_buffer->bits; - // bind it to the texture unit sp tex = getAndBindActiveTextureObject(c); - tex->setSurface(&sur); + tex->setImage(native_buffer); /* * Here an implementation can retrieve the buffer_handle_t of this buffer diff --git a/opengl/libagl/texture.h b/opengl/libagl/texture.h index 5c57948c92d59..98f75509db22c 100644 --- a/opengl/libagl/texture.h +++ b/opengl/libagl/texture.h @@ -32,13 +32,9 @@ namespace android { void ogles_init_texture(ogles_context_t* c); void ogles_uninit_texture(ogles_context_t* c); -void ogles_validate_texture_impl(ogles_context_t* c); - -inline void ogles_validate_texture(ogles_context_t* c) { - if (c->rasterizer.state.enables & GGL_ENABLE_TMUS) - ogles_validate_texture_impl(c); -} - +void ogles_validate_texture(ogles_context_t* c); +void ogles_lock_textures(ogles_context_t* c); +void ogles_unlock_textures(ogles_context_t* c); }; // namespace android diff --git a/opengl/tests/copybits/Android.mk b/opengl/tests/copybits/Android.mk index d5ded42b5fb18..2876a1eec4424 100644 --- a/opengl/tests/copybits/Android.mk +++ b/opengl/tests/copybits/Android.mk @@ -14,5 +14,5 @@ LOCAL_MODULE:= test-opengl-copybits LOCAL_MODULE_TAGS := tests -include $(BUILD_EXECUTABLE) +##include $(BUILD_EXECUTABLE) From 6279619e4279daf77feff0c76e089b26ad66124f Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Mon, 4 May 2009 19:38:43 -0700 Subject: [PATCH 21/83] minor clean-up in FramebufferNativeWindow --- include/ui/FramebufferNativeWindow.h | 6 ------ .../DisplayHardware/DisplayHardware.cpp | 11 ++++------- .../DisplayHardware/DisplayHardware.h | 1 - libs/ui/FramebufferNativeWindow.cpp | 14 -------------- 4 files changed, 4 insertions(+), 28 deletions(-) diff --git a/include/ui/FramebufferNativeWindow.h b/include/ui/FramebufferNativeWindow.h index 1d49cca401ae4..4b281db844334 100644 --- a/include/ui/FramebufferNativeWindow.h +++ b/include/ui/FramebufferNativeWindow.h @@ -76,13 +76,9 @@ public: framebuffer_device_t const * getDevice() const { return fbDev; } - void setSwapRectangle(const Rect& dirty); - private: friend class LightRefBase; ~FramebufferNativeWindow(); // this class cannot be overloaded - static void connect(android_native_window_t* window); - static void disconnect(android_native_window_t* window); static int setSwapInterval(android_native_window_t* window, int interval); static int dequeueBuffer(android_native_window_t* window, android_native_buffer_t** buffer); static int lockBuffer(android_native_window_t* window, android_native_buffer_t* buffer); @@ -94,8 +90,6 @@ private: sp buffers[2]; sp front; - Rect mDirty; - mutable Mutex mutex; Condition mCondition; int32_t mNumBuffers; diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp index 83ebd7a617d35..ca96e140ff7fb 100644 --- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp +++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp @@ -305,16 +305,13 @@ void DisplayHardware::flip(const Region& dirty) const EGLDisplay dpy = mDisplay; EGLSurface surface = mSurface; - Region newDirty(dirty); - newDirty.andSelf(Rect(mWidth, mHeight)); - if (mFlags & BUFFER_PRESERVED) { - mDirty = newDirty; + Region newDirty(dirty); + newDirty.andSelf(Rect(mWidth, mHeight)); + const Rect& b(newDirty.bounds()); + //mNativeWindow->setSwapRectangle(b); } - const Rect& b(newDirty.bounds()); - mNativeWindow->setSwapRectangle(b); - mPageFlipCount++; eglSwapBuffers(dpy, surface); checkEGLErrors("eglSwapBuffers"); diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h index 97a68a53b424e..c9c75e27744bd 100644 --- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h +++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h @@ -102,7 +102,6 @@ private: int mHeight; PixelFormat mFormat; uint32_t mFlags; - mutable Region mDirty; mutable uint32_t mPageFlipCount; sp mNativeWindow; diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp index 407d6f4f2b19e..f235cb44a5466 100644 --- a/libs/ui/FramebufferNativeWindow.cpp +++ b/libs/ui/FramebufferNativeWindow.cpp @@ -131,14 +131,6 @@ FramebufferNativeWindow::~FramebufferNativeWindow() { framebuffer_close(fbDev); } -void FramebufferNativeWindow::connect(android_native_window_t* window) -{ -} - -void FramebufferNativeWindow::disconnect(android_native_window_t* window) -{ -} - int FramebufferNativeWindow::setSwapInterval( android_native_window_t* window, int interval) { @@ -146,12 +138,6 @@ int FramebufferNativeWindow::setSwapInterval( return fb->setSwapInterval(fb, interval); } -void FramebufferNativeWindow::setSwapRectangle(const Rect& dirty) -{ - Mutex::Autolock _l(mutex); - mDirty = dirty; -} - int FramebufferNativeWindow::dequeueBuffer(android_native_window_t* window, android_native_buffer_t** buffer) { From 430f2ed5c03312700131a70c858b98e1cc6bc161 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Tue, 5 May 2009 00:37:46 -0700 Subject: [PATCH 22/83] removed the "bits" attribute from android_native_buffer_t. "bits" can never be trusted now that we need to call lock() on the handle to get the virtual address of the buffer. --- include/ui/Surface.h | 4 +- libs/surfaceflinger/LayerBitmap.cpp | 5 +- libs/ui/Surface.cpp | 23 ++++---- opengl/include/EGL/android_natives.h | 3 +- opengl/libagl/egl.cpp | 83 ++++++++++++++++++---------- opengl/libagl/texture.cpp | 5 +- 6 files changed, 73 insertions(+), 50 deletions(-) diff --git a/include/ui/Surface.h b/include/ui/Surface.h index 6eb06ae65f356..ce507195a733c 100644 --- a/include/ui/Surface.h +++ b/include/ui/Surface.h @@ -54,8 +54,8 @@ public: return handle; } - status_t lock(uint32_t usage); - status_t lock(uint32_t usage, const Rect& rect); + status_t lock(uint32_t usage, void** vaddr); + status_t lock(uint32_t usage, const Rect& rect, void** vaddr); status_t unlock(); protected: diff --git a/libs/surfaceflinger/LayerBitmap.cpp b/libs/surfaceflinger/LayerBitmap.cpp index 38d4bcf02f7d7..765d90b82ef50 100644 --- a/libs/surfaceflinger/LayerBitmap.cpp +++ b/libs/surfaceflinger/LayerBitmap.cpp @@ -116,7 +116,8 @@ status_t Buffer::initSize(uint32_t w, uint32_t h) status_t Buffer::lock(GGLSurface* sur, uint32_t usage) { - status_t res = SurfaceBuffer::lock(usage); + void* vaddr; + status_t res = SurfaceBuffer::lock(usage, &vaddr); if (res == NO_ERROR && sur) { sur->version = sizeof(GGLSurface); sur->width = width; @@ -124,7 +125,7 @@ status_t Buffer::lock(GGLSurface* sur, uint32_t usage) sur->stride = stride; sur->format = format; sur->vstride = mVStride; - sur->data = static_cast(bits); + sur->data = static_cast(vaddr); } return res; } diff --git a/libs/ui/Surface.cpp b/libs/ui/Surface.cpp index 68fd9632cc124..5f2138e8d6ca8 100644 --- a/libs/ui/Surface.cpp +++ b/libs/ui/Surface.cpp @@ -90,23 +90,22 @@ int SurfaceBuffer::getHandle(android_native_buffer_t const * base, return 0; } -status_t SurfaceBuffer::lock(uint32_t usage) +status_t SurfaceBuffer::lock(uint32_t usage, void** vaddr) { const Rect lockBounds(width, height); - status_t res = lock(usage, lockBounds); + status_t res = lock(usage, lockBounds, vaddr); return res; } -status_t SurfaceBuffer::lock(uint32_t usage, const Rect& rect) +status_t SurfaceBuffer::lock(uint32_t usage, const Rect& rect, void** vaddr) { - status_t res = getBufferMapper().lock(handle, usage, rect, &bits); + status_t res = getBufferMapper().lock(handle, usage, rect, vaddr); return res; } status_t SurfaceBuffer::unlock() { status_t res = getBufferMapper().unlock(handle); - bits = NULL; return res; } @@ -134,11 +133,11 @@ static void copyBlt( const sp& src, const Region& reg) { - src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds()); - uint8_t const * const src_bits = (uint8_t const *)src->bits; + uint8_t const * src_bits; + src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(), (void**)&src_bits); - dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds()); - uint8_t* const dst_bits = (uint8_t*)dst->bits; + uint8_t* dst_bits; + dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(), (void**)&dst_bits); Region::iterator iterator(reg); if (iterator) { @@ -629,9 +628,10 @@ status_t Surface::lock(SurfaceInfo* other, Region* dirtyIn, bool blocking) mDirtyRegion = newDirtyRegion; mOldDirtyRegion = newDirtyRegion; + void* vaddr; status_t res = backBuffer->lock( GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, - newDirtyRegion.bounds()); + newDirtyRegion.bounds(), &vaddr); LOGW_IF(res, "failed locking buffer %d (%p)", mBackbufferIndex, backBuffer->handle); @@ -642,7 +642,7 @@ status_t Surface::lock(SurfaceInfo* other, Region* dirtyIn, bool blocking) other->s = backBuffer->stride; other->usage = backBuffer->usage; other->format = backBuffer->format; - other->bits = backBuffer->bits; + other->bits = vaddr; } } return err; @@ -660,7 +660,6 @@ status_t Surface::unlockAndPost() mBackbufferIndex, mLockedBuffer->handle); status_t err = queueBuffer(mLockedBuffer); - mLockedBuffer->bits = NULL; mLockedBuffer = 0; return err; } diff --git a/opengl/include/EGL/android_natives.h b/opengl/include/EGL/android_natives.h index 329705b65a8c6..8db2bb3f1cd6a 100644 --- a/opengl/include/EGL/android_natives.h +++ b/opengl/include/EGL/android_natives.h @@ -157,9 +157,8 @@ struct android_native_buffer_t int stride; int format; int usage; - void* bits; // non-zero if buffer is locked for sw usage - void* reserved[2]; + void* reserved[3]; int (*getHandle)(struct android_native_buffer_t const * base, buffer_handle_t* handle); diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp index 04ca431778c25..67dfd3eada651 100644 --- a/opengl/libagl/egl.cpp +++ b/opengl/libagl/egl.cpp @@ -146,9 +146,10 @@ struct egl_surface_t virtual EGLBoolean bindDrawSurface(ogles_context_t* gl) = 0; virtual EGLBoolean bindReadSurface(ogles_context_t* gl) = 0; + virtual void connect() {} + virtual void disconnect() {} virtual EGLint getWidth() const = 0; virtual EGLint getHeight() const = 0; - virtual void* getBits() const = 0; virtual EGLint getHorizontalResolution() const; virtual EGLint getVerticalResolution() const; @@ -204,21 +205,24 @@ struct egl_window_surface_v2_t : public egl_surface_t virtual EGLBoolean swapBuffers(); virtual EGLBoolean bindDrawSurface(ogles_context_t* gl); virtual EGLBoolean bindReadSurface(ogles_context_t* gl); + virtual void connect(); + virtual void disconnect(); virtual EGLint getWidth() const { return buffer->width; } virtual EGLint getHeight() const { return buffer->height; } - virtual void* getBits() const; virtual EGLint getHorizontalResolution() const; virtual EGLint getVerticalResolution() const; virtual EGLint getRefreshRate() const; virtual EGLint getSwapBehavior() const; + private: - status_t lock(android_native_buffer_t* buf, int usage); + status_t lock(android_native_buffer_t* buf, int usage, void** vaddr); status_t unlock(android_native_buffer_t* buf); android_native_window_t* nativeWindow; android_native_buffer_t* buffer; gralloc_module_t const* module; int width; int height; + void* bits; }; egl_window_surface_v2_t::egl_window_surface_v2_t(EGLDisplay dpy, @@ -226,7 +230,7 @@ egl_window_surface_v2_t::egl_window_surface_v2_t(EGLDisplay dpy, int32_t depthFormat, android_native_window_t* window) : egl_surface_t(dpy, config, depthFormat), - nativeWindow(window), buffer(0), module(0) + nativeWindow(window), buffer(0), module(0), bits(NULL) { hw_module_t const* pModule; hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule); @@ -249,20 +253,26 @@ egl_window_surface_v2_t::egl_window_surface_v2_t(EGLDisplay dpy, } } - // TODO: lockBuffer should rather be executed when the very first - // direct rendering occurs. buffer->common.incRef(&buffer->common); - nativeWindow->lockBuffer(nativeWindow, buffer); +} +void egl_window_surface_v2_t::connect() +{ // Lock the buffer - lock(buffer, GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN); - - // FIXME: we need to handle the copy-back if needed, but - // for now we're a "non preserving" implementation. + nativeWindow->lockBuffer(nativeWindow, buffer); + lock(buffer, GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, &bits); +} + +void egl_window_surface_v2_t::disconnect() +{ + if (buffer) { + bits = NULL; + unlock(buffer); + } } status_t egl_window_surface_v2_t::lock( - android_native_buffer_t* buf, int usage) + android_native_buffer_t* buf, int usage, void** vaddr) { int err; buffer_handle_t bufferHandle; @@ -271,7 +281,7 @@ status_t egl_window_surface_v2_t::lock( return err; err = module->lock(module, bufferHandle, - usage, 0, 0, buf->width, buf->height, &buf->bits); + usage, 0, 0, buf->width, buf->height, vaddr); return err; } @@ -284,14 +294,12 @@ status_t egl_window_surface_v2_t::unlock(android_native_buffer_t* buf) return err; err = module->unlock(module, bufferHandle); - buf->bits = NULL; return err; } egl_window_surface_v2_t::~egl_window_surface_v2_t() { if (buffer) { - unlock(buffer); buffer->common.decRef(&buffer->common); } nativeWindow->common.decRef(&nativeWindow->common); @@ -317,9 +325,9 @@ EGLBoolean egl_window_surface_v2_t::swapBuffers() // TODO: lockBuffer should rather be executed when the very first // direct rendering occurs. + void* vaddr; nativeWindow->lockBuffer(nativeWindow, buffer); - lock(buffer, GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN); - + lock(buffer, GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, &bits); if ((width != buffer->width) || (height != buffer->height)) { // TODO: we probably should reset the swap rect here @@ -363,7 +371,7 @@ EGLBoolean egl_window_surface_v2_t::bindDrawSurface(ogles_context_t* gl) buffer.width = this->buffer->width; buffer.height = this->buffer->height; buffer.stride = this->buffer->stride; - buffer.data = (GGLubyte*)this->buffer->bits; + buffer.data = (GGLubyte*)bits; buffer.format = this->buffer->format; gl->rasterizer.procs.colorBuffer(gl, &buffer); if (depth.data != gl->rasterizer.state.buffers.depth.data) @@ -392,14 +400,11 @@ EGLBoolean egl_window_surface_v2_t::bindReadSurface(ogles_context_t* gl) buffer.width = this->buffer->width; buffer.height = this->buffer->height; buffer.stride = this->buffer->stride; - buffer.data = (GGLubyte*)this->buffer->bits; + buffer.data = (GGLubyte*)bits; // FIXME: hopefully is is LOCKED!!! buffer.format = this->buffer->format; gl->rasterizer.procs.readBuffer(gl, &buffer); return EGL_TRUE; } -void* egl_window_surface_v2_t::getBits() const { - return (GGLubyte*)buffer->bits; -} EGLint egl_window_surface_v2_t::getHorizontalResolution() const { return (nativeWindow->xdpi * EGL_DISPLAY_SCALING) * (1.0f / 25.4f); } @@ -434,7 +439,6 @@ struct egl_pixmap_surface_t : public egl_surface_t virtual EGLBoolean bindReadSurface(ogles_context_t* gl); virtual EGLint getWidth() const { return nativePixmap.width; } virtual EGLint getHeight() const { return nativePixmap.height; } - virtual void* getBits() const { return nativePixmap.data; } private: egl_native_pixmap_t nativePixmap; }; @@ -499,7 +503,6 @@ struct egl_pbuffer_surface_t : public egl_surface_t virtual EGLBoolean bindReadSurface(ogles_context_t* gl); virtual EGLint getWidth() const { return pbuffer.width; } virtual EGLint getHeight() const { return pbuffer.height; } - virtual void* getBits() const { return pbuffer.data; } private: GGLSurface pbuffer; }; @@ -1311,6 +1314,11 @@ EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface eglSurface) return setError(EGL_BAD_SURFACE, EGL_FALSE); if (surface->dpy != dpy) return setError(EGL_BAD_DISPLAY, EGL_FALSE); + if (surface->ctx) { + // FIXME: this surface is current check what the spec says + surface->disconnect(); + surface->ctx = 0; + } delete surface; } return EGL_TRUE; @@ -1436,21 +1444,28 @@ EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw, egl_surface_t* r = (egl_surface_t*)read; if ((d && d->ctx && d->ctx != ctx) || (r && r->ctx && r->ctx != ctx)) { - // once of the surface is bound to a context in another thread + // one of the surface is bound to a context in another thread return setError(EGL_BAD_ACCESS, EGL_FALSE); } } - // TODO: call connect / disconnect on the surface - ogles_context_t* gl = (ogles_context_t*)ctx; if (makeCurrent(gl) == 0) { if (ctx) { egl_context_t* c = egl_context_t::context(ctx); egl_surface_t* d = (egl_surface_t*)draw; egl_surface_t* r = (egl_surface_t*)read; - c->read = read; + + if (c->draw) { + reinterpret_cast(c->draw)->disconnect(); + } + if (c->read) { + // FIXME: unlock/disconnect the read surface too + } + c->draw = draw; + c->read = read; + if (c->flags & egl_context_t::NEVER_CURRENT) { c->flags &= ~egl_context_t::NEVER_CURRENT; GLint w = 0; @@ -1464,10 +1479,12 @@ EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw, ogles_scissor(gl, 0, 0, w, h); } if (d) { + d->connect(); d->ctx = ctx; d->bindDrawSurface(gl); } if (r) { + // FIXME: lock/connect the read surface too r->ctx = ctx; r->bindReadSurface(gl); } @@ -1478,8 +1495,14 @@ EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw, egl_context_t* c = egl_context_t::context(current_ctx); egl_surface_t* d = (egl_surface_t*)c->draw; egl_surface_t* r = (egl_surface_t*)c->read; - if (d) d->ctx = EGL_NO_CONTEXT; - if (r) r->ctx = EGL_NO_CONTEXT; + if (d) { + d->ctx = EGL_NO_CONTEXT; + d->disconnect(); + } + if (r) { + r->ctx = EGL_NO_CONTEXT; + // FIXME: unlock/disconnect the read surface too + } } } return EGL_TRUE; diff --git a/opengl/libagl/texture.cpp b/opengl/libagl/texture.cpp index f2d8da3ca259f..9bcbfdd244011 100644 --- a/opengl/libagl/texture.cpp +++ b/opengl/libagl/texture.cpp @@ -141,12 +141,13 @@ void ogles_lock_textures(ogles_context_t* c) reinterpret_cast(pModule); buffer_handle_t bufferHandle; native_buffer->getHandle(native_buffer, &bufferHandle); + void* vaddr; int err = module->lock(module, bufferHandle, GRALLOC_USAGE_SW_READ_OFTEN, 0, 0, native_buffer->width, native_buffer->height, - &native_buffer->bits); + &vaddr); - u.texture->setImageBits(native_buffer->bits); + u.texture->setImageBits(vaddr); c->rasterizer.procs.bindTexture(c, &(u.texture->surface)); } } From e633f9339a2556771c79c784b0b23a9aade30485 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Tue, 5 May 2009 00:59:23 -0700 Subject: [PATCH 23/83] get rid of android_native_buffer_t::getHandle() and replace it with an handle field this abstraction was not necessary. things are easier now. --- include/ui/FramebufferNativeWindow.h | 7 ------- include/ui/Surface.h | 8 -------- libs/ui/Surface.cpp | 27 +++++++-------------------- opengl/include/EGL/android_natives.h | 9 ++++----- opengl/libagl/egl.cpp | 19 +++---------------- opengl/libagl/texture.cpp | 21 ++++++++------------- 6 files changed, 22 insertions(+), 69 deletions(-) diff --git a/include/ui/FramebufferNativeWindow.h b/include/ui/FramebufferNativeWindow.h index 4b281db844334..0db245af44dd5 100644 --- a/include/ui/FramebufferNativeWindow.h +++ b/include/ui/FramebufferNativeWindow.h @@ -50,17 +50,10 @@ public: android_native_buffer_t::height = h; android_native_buffer_t::format = f; android_native_buffer_t::usage = u; - android_native_buffer_t::getHandle = getHandle; } -public: - buffer_handle_t handle; private: friend class LightRefBase; ~NativeBuffer() { }; // this class cannot be overloaded - static int getHandle(android_native_buffer_t const * base, buffer_handle_t* handle) { - *handle = getSelf(base)->handle; - return 0; - } }; // --------------------------------------------------------------------------- diff --git a/include/ui/Surface.h b/include/ui/Surface.h index ce507195a733c..e9bb1b3f473d5 100644 --- a/include/ui/Surface.h +++ b/include/ui/Surface.h @@ -50,10 +50,6 @@ class SurfaceBuffer LightRefBase > { public: - buffer_handle_t getHandle() const { - return handle; - } - status_t lock(uint32_t usage, void** vaddr); status_t lock(uint32_t usage, const Rect& rect, void** vaddr); status_t unlock(); @@ -62,7 +58,6 @@ protected: SurfaceBuffer(); SurfaceBuffer(const Parcel& reply); virtual ~SurfaceBuffer(); - buffer_handle_t handle; bool mOwner; inline const BufferMapper& getBufferMapper() const { return mBufferMapper; } @@ -80,9 +75,6 @@ private: static status_t writeToParcel(Parcel* reply, android_native_buffer_t const* buffer); - static int getHandle(android_native_buffer_t const * base, - buffer_handle_t* handle); - BufferMapper& mBufferMapper; }; diff --git a/libs/ui/Surface.cpp b/libs/ui/Surface.cpp index 5f2138e8d6ca8..782eac46beb85 100644 --- a/libs/ui/Surface.cpp +++ b/libs/ui/Surface.cpp @@ -52,18 +52,18 @@ namespace android { ANDROID_SINGLETON_STATIC_INSTANCE( SurfaceBuffer ) SurfaceBuffer::SurfaceBuffer() - : BASE(), handle(0), mOwner(false), mBufferMapper(BufferMapper::get()) + : BASE(), mOwner(false), mBufferMapper(BufferMapper::get()) { width = height = stride = format = usage = 0; - android_native_buffer_t::getHandle = getHandle; + handle = NULL; } SurfaceBuffer::SurfaceBuffer(const Parcel& data) - : BASE(), handle(0), mOwner(true), mBufferMapper(BufferMapper::get()) + : BASE(), mOwner(true), mBufferMapper(BufferMapper::get()) { // we own the handle in this case width = data.readInt32(); @@ -72,7 +72,6 @@ SurfaceBuffer::SurfaceBuffer(const Parcel& data) format = data.readInt32(); usage = data.readInt32(); handle = data.readNativeHandle(); - android_native_buffer_t::getHandle = getHandle; } SurfaceBuffer::~SurfaceBuffer() @@ -83,13 +82,6 @@ SurfaceBuffer::~SurfaceBuffer() } } -int SurfaceBuffer::getHandle(android_native_buffer_t const * base, - buffer_handle_t* handle) -{ - *handle = getSelf(base)->handle; - return 0; -} - status_t SurfaceBuffer::lock(uint32_t usage, void** vaddr) { const Rect lockBounds(width, height); @@ -112,17 +104,12 @@ status_t SurfaceBuffer::unlock() status_t SurfaceBuffer::writeToParcel(Parcel* reply, android_native_buffer_t const* buffer) { - buffer_handle_t handle; - status_t err = buffer->getHandle(buffer, &handle); - if (err < 0) { - return err; - } reply->writeInt32(buffer->width); reply->writeInt32(buffer->height); reply->writeInt32(buffer->stride); reply->writeInt32(buffer->format); reply->writeInt32(buffer->usage); - reply->writeNativeHandle(handle); + reply->writeNativeHandle(buffer->handle); return NO_ERROR; } @@ -419,7 +406,7 @@ Surface::~Surface() // its buffers in this process. for (int i=0 ; i<2 ; i++) { if (mBuffers[i] != 0) { - getBufferMapper().unregisterBuffer(mBuffers[i]->getHandle()); + getBufferMapper().unregisterBuffer(mBuffers[i]->handle); } } @@ -689,10 +676,10 @@ status_t Surface::getBufferLocked(int index) if (buffer != 0) { sp& currentBuffer(mBuffers[index]); if (currentBuffer != 0) { - getBufferMapper().unregisterBuffer(currentBuffer->getHandle()); + getBufferMapper().unregisterBuffer(currentBuffer->handle); currentBuffer.clear(); } - err = getBufferMapper().registerBuffer(buffer->getHandle()); + err = getBufferMapper().registerBuffer(buffer->handle); LOGW_IF(err, "map(...) failed %d (%s)", err, strerror(-err)); if (err == NO_ERROR) { currentBuffer = buffer; diff --git a/opengl/include/EGL/android_natives.h b/opengl/include/EGL/android_natives.h index 8db2bb3f1cd6a..b8465d580228e 100644 --- a/opengl/include/EGL/android_natives.h +++ b/opengl/include/EGL/android_natives.h @@ -157,13 +157,12 @@ struct android_native_buffer_t int stride; int format; int usage; + + void* reserved[2]; - void* reserved[3]; + buffer_handle_t handle; - int (*getHandle)(struct android_native_buffer_t const * base, - buffer_handle_t* handle); - - void* reserved_proc[7]; + void* reserved_proc[8]; }; diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp index 67dfd3eada651..720ba0bdaff34 100644 --- a/opengl/libagl/egl.cpp +++ b/opengl/libagl/egl.cpp @@ -274,26 +274,14 @@ void egl_window_surface_v2_t::disconnect() status_t egl_window_surface_v2_t::lock( android_native_buffer_t* buf, int usage, void** vaddr) { - int err; - buffer_handle_t bufferHandle; - err = buf->getHandle(buf, &bufferHandle); - if (err < 0) - return err; - - err = module->lock(module, bufferHandle, + int err = module->lock(module, buf->handle, usage, 0, 0, buf->width, buf->height, vaddr); return err; } status_t egl_window_surface_v2_t::unlock(android_native_buffer_t* buf) { - int err; - buffer_handle_t bufferHandle; - err = buf->getHandle(buf, &bufferHandle); - if (err < 0) - return err; - - err = module->unlock(module, bufferHandle); + int err = module->unlock(module, buf->handle); return err; } @@ -379,8 +367,7 @@ EGLBoolean egl_window_surface_v2_t::bindDrawSurface(ogles_context_t* gl) #ifdef LIBAGL_USE_GRALLOC_COPYBITS gl->copybits.drawSurfaceFd = -1; if (supportedCopybitsDestinationFormat(buffer.format)) { - buffer_handle_t handle; - this->buffer->getHandle(this->buffer, &handle); + buffer_handle_t handle = this->buffer->handle; if (handle != NULL) { private_handle_t* hand = private_handle_t::dynamicCast(handle); if (hand != NULL) { diff --git a/opengl/libagl/texture.cpp b/opengl/libagl/texture.cpp index 9bcbfdd244011..118964340f482 100644 --- a/opengl/libagl/texture.cpp +++ b/opengl/libagl/texture.cpp @@ -139,10 +139,9 @@ void ogles_lock_textures(ogles_context_t* c) gralloc_module_t const* module = reinterpret_cast(pModule); - buffer_handle_t bufferHandle; - native_buffer->getHandle(native_buffer, &bufferHandle); + void* vaddr; - int err = module->lock(module, bufferHandle, + int err = module->lock(module, native_buffer->handle, GRALLOC_USAGE_SW_READ_OFTEN, 0, 0, native_buffer->width, native_buffer->height, &vaddr); @@ -168,9 +167,8 @@ void ogles_unlock_textures(ogles_context_t* c) gralloc_module_t const* module = reinterpret_cast(pModule); - buffer_handle_t bufferHandle; - native_buffer->getHandle(native_buffer, &bufferHandle); - module->unlock(module, bufferHandle); + + module->unlock(module, native_buffer->handle); u.texture->setImageBits(NULL); c->rasterizer.procs.bindTexture(c, &(u.texture->surface)); } @@ -1547,13 +1545,10 @@ void glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image) */ #ifdef LIBAGL_USE_GRALLOC_COPYBITS tex->copybits_fd = -1; - buffer_handle_t handle; - if (native_buffer->getHandle(native_buffer, &handle) == 0) { - private_handle_t* hand; - if ((hand = private_handle_t::dynamicCast(handle)) != NULL) { - if (hand->usesPhysicallyContiguousMemory()) { - tex->copybits_fd = hand->fd; - } + private_handle_t* hand; + if ((hand = private_handle_t::dynamicCast(native_buffer->handle)) != NULL) { + if (hand->usesPhysicallyContiguousMemory()) { + tex->copybits_fd = hand->fd; } } #endif // LIBAGL_USE_GRALLOC_COPYBITS From ac2523b161df2bb507cc88906bb070878266770d Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Tue, 5 May 2009 18:11:11 -0700 Subject: [PATCH 24/83] move opengl/include/EGL/android_natives.h to include/ui/egl/android_natives.h and don't include it from egl.h the android_native_ types are just forward declared in egl.h --- include/private/ui/SurfaceBuffer.h | 76 +++++++++++++++++++ include/ui/FramebufferNativeWindow.h | 23 +----- include/ui/ISurface.h | 2 - include/ui/Surface.h | 40 +--------- .../EGL => include/ui/egl}/android_natives.h | 1 - .../DisplayHardware/DisplayHardware.cpp | 1 - libs/surfaceflinger/LayerBitmap.h | 4 +- libs/ui/BufferMapper.cpp | 2 - libs/ui/FramebufferNativeWindow.cpp | 19 +++++ libs/ui/ISurface.cpp | 1 + libs/ui/Surface.cpp | 5 +- opengl/include/EGL/eglplatform.h | 4 +- opengl/libagl/TextureObjectManager.cpp | 2 + opengl/libagl/TextureObjectManager.h | 2 +- opengl/libagl/egl.cpp | 3 +- opengl/libagl/texture.cpp | 2 +- 16 files changed, 112 insertions(+), 75 deletions(-) create mode 100644 include/private/ui/SurfaceBuffer.h rename {opengl/include/EGL => include/ui/egl}/android_natives.h (99%) diff --git a/include/private/ui/SurfaceBuffer.h b/include/private/ui/SurfaceBuffer.h new file mode 100644 index 0000000000000..a6db50f4cf696 --- /dev/null +++ b/include/private/ui/SurfaceBuffer.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2007 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. + */ + +#ifndef ANDROID_UI_PRIVATE_SURFACE_BUFFER_H +#define ANDROID_UI_PRIVATE_SURFACE_BUFFER_H + +#include +#include + +#include + +#include + +namespace android { + +// --------------------------------------------------------------------------- + +class BufferMapper; +class Rect; +class Surface; +class SurfaceBuffer; + +// --------------------------------------------------------------------------- + +class SurfaceBuffer + : public EGLNativeBase< + android_native_buffer_t, + SurfaceBuffer, + LightRefBase > +{ +public: + status_t lock(uint32_t usage, void** vaddr); + status_t lock(uint32_t usage, const Rect& rect, void** vaddr); + status_t unlock(); + +protected: + SurfaceBuffer(); + SurfaceBuffer(const Parcel& reply); + virtual ~SurfaceBuffer(); + bool mOwner; + + inline const BufferMapper& getBufferMapper() const { return mBufferMapper; } + inline BufferMapper& getBufferMapper() { return mBufferMapper; } + +private: + friend class Surface; + friend class BpSurface; + friend class BnSurface; + friend class LightRefBase; + + SurfaceBuffer& operator = (const SurfaceBuffer& rhs); + const SurfaceBuffer& operator = (const SurfaceBuffer& rhs) const; + + static status_t writeToParcel(Parcel* reply, + android_native_buffer_t const* buffer); + + BufferMapper& mBufferMapper; +}; + +}; // namespace android + +#endif // ANDROID_UI_PRIVATE_SURFACE_BUFFER_H + diff --git a/include/ui/FramebufferNativeWindow.h b/include/ui/FramebufferNativeWindow.h index 0db245af44dd5..aad39a2a6b8b6 100644 --- a/include/ui/FramebufferNativeWindow.h +++ b/include/ui/FramebufferNativeWindow.h @@ -21,13 +21,14 @@ #include #include -#include #include #include #include +#include + extern "C" EGLNativeWindowType android_createDisplaySurface(void); @@ -36,25 +37,7 @@ namespace android { // --------------------------------------------------------------------------- class Surface; - - -class NativeBuffer - : public EGLNativeBase< - android_native_buffer_t, - NativeBuffer, - LightRefBase > -{ -public: - NativeBuffer(int w, int h, int f, int u) : BASE() { - android_native_buffer_t::width = w; - android_native_buffer_t::height = h; - android_native_buffer_t::format = f; - android_native_buffer_t::usage = u; - } -private: - friend class LightRefBase; - ~NativeBuffer() { }; // this class cannot be overloaded -}; +class NativeBuffer; // --------------------------------------------------------------------------- diff --git a/include/ui/ISurface.h b/include/ui/ISurface.h index 1a788720dbcd4..e47b753627756 100644 --- a/include/ui/ISurface.h +++ b/include/ui/ISurface.h @@ -20,8 +20,6 @@ #include #include -#include - #include #include #include diff --git a/include/ui/Surface.h b/include/ui/Surface.h index e9bb1b3f473d5..8c4f63ddfec09 100644 --- a/include/ui/Surface.h +++ b/include/ui/Surface.h @@ -28,7 +28,7 @@ #include #include -#include +#include namespace android { @@ -43,44 +43,6 @@ struct layer_cblk_t; // --------------------------------------------------------------------------- -class SurfaceBuffer - : public EGLNativeBase< - android_native_buffer_t, - SurfaceBuffer, - LightRefBase > -{ -public: - status_t lock(uint32_t usage, void** vaddr); - status_t lock(uint32_t usage, const Rect& rect, void** vaddr); - status_t unlock(); - -protected: - SurfaceBuffer(); - SurfaceBuffer(const Parcel& reply); - virtual ~SurfaceBuffer(); - bool mOwner; - - inline const BufferMapper& getBufferMapper() const { return mBufferMapper; } - inline BufferMapper& getBufferMapper() { return mBufferMapper; } - -private: - friend class Surface; - friend class BpSurface; - friend class BnSurface; - friend class LightRefBase; - - SurfaceBuffer& operator = (const SurfaceBuffer& rhs); - const SurfaceBuffer& operator = (const SurfaceBuffer& rhs) const; - - static status_t writeToParcel(Parcel* reply, - android_native_buffer_t const* buffer); - - BufferMapper& mBufferMapper; -}; - -// --------------------------------------------------------------------------- -class Surface; - class SurfaceControl : public RefBase { public: diff --git a/opengl/include/EGL/android_natives.h b/include/ui/egl/android_natives.h similarity index 99% rename from opengl/include/EGL/android_natives.h rename to include/ui/egl/android_natives.h index b8465d580228e..5842ee72ce7fe 100644 --- a/opengl/include/EGL/android_natives.h +++ b/include/ui/egl/android_natives.h @@ -47,7 +47,6 @@ enum { SURFACE_FLAG_MAPPED = FRAMEBUFFER_FLAG_MAPPED, }; - // --------------------------------------------------------------------------- struct android_native_base_t diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp index ca96e140ff7fb..374f2e2c8b659 100644 --- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp +++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp @@ -30,7 +30,6 @@ #include #include #include -#include #include diff --git a/libs/surfaceflinger/LayerBitmap.h b/libs/surfaceflinger/LayerBitmap.h index 6e136a2ae7649..824e0f2b311b8 100644 --- a/libs/surfaceflinger/LayerBitmap.h +++ b/libs/surfaceflinger/LayerBitmap.h @@ -28,12 +28,10 @@ #include #include -#include - #include #include - +#include class copybit_image_t; struct android_native_buffer_t; diff --git a/libs/ui/BufferMapper.cpp b/libs/ui/BufferMapper.cpp index 1a75c5d9acdfa..92a9a86bb0f29 100644 --- a/libs/ui/BufferMapper.cpp +++ b/libs/ui/BufferMapper.cpp @@ -25,8 +25,6 @@ #include #include -#include - #include diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp index f235cb44a5466..5e69cff985c71 100644 --- a/libs/ui/FramebufferNativeWindow.cpp +++ b/libs/ui/FramebufferNativeWindow.cpp @@ -42,6 +42,25 @@ namespace android { // ---------------------------------------------------------------------------- +class NativeBuffer + : public EGLNativeBase< + android_native_buffer_t, + NativeBuffer, + LightRefBase > +{ +public: + NativeBuffer(int w, int h, int f, int u) : BASE() { + android_native_buffer_t::width = w; + android_native_buffer_t::height = h; + android_native_buffer_t::format = f; + android_native_buffer_t::usage = u; + } +private: + friend class LightRefBase; + ~NativeBuffer() { }; // this class cannot be overloaded +}; + + /* * This implements the (main) framebuffer management. This class is used * mostly by SurfaceFlinger, but also by command line GL application. diff --git a/libs/ui/ISurface.cpp b/libs/ui/ISurface.cpp index fcea8ec70121b..ec922d0cf1b2a 100644 --- a/libs/ui/ISurface.cpp +++ b/libs/ui/ISurface.cpp @@ -27,6 +27,7 @@ #include #include +#include namespace android { diff --git a/libs/ui/Surface.cpp b/libs/ui/Surface.cpp index 782eac46beb85..6437619b20e26 100644 --- a/libs/ui/Surface.cpp +++ b/libs/ui/Surface.cpp @@ -36,12 +36,11 @@ #include #include -#include +#include #include #include - -#include +#include namespace android { diff --git a/opengl/include/EGL/eglplatform.h b/opengl/include/EGL/eglplatform.h index d42808704dd67..956149091d817 100644 --- a/opengl/include/EGL/eglplatform.h +++ b/opengl/include/EGL/eglplatform.h @@ -89,7 +89,8 @@ typedef Window EGLNativeWindowType; #elif defined(ANDROID) -#include +struct android_native_window_t; +struct egl_native_pixmap_t; typedef struct android_native_window_t* EGLNativeWindowType; typedef struct egl_native_pixmap_t* EGLNativePixmapType; @@ -97,6 +98,7 @@ typedef void* EGLNativeDisplayType; #ifndef EGL_ANDROID_image_native_buffer #define EGL_ANDROID_image_native_buffer 1 +struct android_native_buffer_t; #define EGL_NATIVE_BUFFER_ANDROID 0x6000 /* eglCreateImageKHR target */ #endif diff --git a/opengl/libagl/TextureObjectManager.cpp b/opengl/libagl/TextureObjectManager.cpp index 9eb99f0bc2319..e5d4ed2b6f970 100644 --- a/opengl/libagl/TextureObjectManager.cpp +++ b/opengl/libagl/TextureObjectManager.cpp @@ -19,6 +19,8 @@ #include "context.h" #include "TextureObjectManager.h" +#include + namespace android { // ---------------------------------------------------------------------------- diff --git a/opengl/libagl/TextureObjectManager.h b/opengl/libagl/TextureObjectManager.h index 29d50370eb41d..e0eadf147959c 100644 --- a/opengl/libagl/TextureObjectManager.h +++ b/opengl/libagl/TextureObjectManager.h @@ -30,7 +30,7 @@ #include #include -#include +#include #include "Tokenizer.h" #include "TokenManager.h" diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp index 720ba0bdaff34..0950f3ea26666 100644 --- a/opengl/libagl/egl.cpp +++ b/opengl/libagl/egl.cpp @@ -33,13 +33,14 @@ #include #include -#include #include #include #include #include +#include + #include "context.h" #include "state.h" #include "texture.h" diff --git a/opengl/libagl/texture.cpp b/opengl/libagl/texture.cpp index 118964340f482..0211208e2f4a2 100644 --- a/opengl/libagl/texture.cpp +++ b/opengl/libagl/texture.cpp @@ -23,7 +23,7 @@ #include "texture.h" #include "TextureObjectManager.h" -#include +#include #ifdef LIBAGL_USE_GRALLOC_COPYBITS #include "copybit.h" From b51e18d59b6f8e44a5d3516fc3359c54fa913331 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Tue, 5 May 2009 18:21:32 -0700 Subject: [PATCH 25/83] move android_native_buffer_t declaration into its own private/ui/android_native_priv.h header, since user code should never have access to it. --- include/private/ui/SurfaceBuffer.h | 2 +- include/private/ui/android_natives_priv.h | 62 +++++++++++++++++++++++ include/ui/egl/android_natives.h | 26 ---------- libs/ui/FramebufferNativeWindow.cpp | 2 + opengl/libagl/TextureObjectManager.cpp | 2 +- opengl/libagl/egl.cpp | 2 +- opengl/libagl/texture.cpp | 2 +- 7 files changed, 68 insertions(+), 30 deletions(-) create mode 100644 include/private/ui/android_natives_priv.h diff --git a/include/private/ui/SurfaceBuffer.h b/include/private/ui/SurfaceBuffer.h index a6db50f4cf696..c45abeb73c250 100644 --- a/include/private/ui/SurfaceBuffer.h +++ b/include/private/ui/SurfaceBuffer.h @@ -22,7 +22,7 @@ #include -#include +#include namespace android { diff --git a/include/private/ui/android_natives_priv.h b/include/private/ui/android_natives_priv.h new file mode 100644 index 0000000000000..ee843e928100a --- /dev/null +++ b/include/private/ui/android_natives_priv.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2009 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. + */ + +#ifndef ANDROID_ANDROID_NATIVES_PRIV_H +#define ANDROID_ANDROID_NATIVES_PRIV_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*****************************************************************************/ + +struct android_native_buffer_t +{ +#ifdef __cplusplus + android_native_buffer_t() { + common.magic = ANDROID_NATIVE_BUFFER_MAGIC; + common.version = sizeof(android_native_buffer_t); + memset(common.reserved, 0, sizeof(common.reserved)); + } +#endif + + struct android_native_base_t common; + + int width; + int height; + int stride; + int format; + int usage; + + void* reserved[2]; + + buffer_handle_t handle; + + void* reserved_proc[8]; +}; + + +/*****************************************************************************/ + +#ifdef __cplusplus +} +#endif + +/*****************************************************************************/ + +#endif /* ANDROID_ANDROID_NATIVES_PRIV_H */ diff --git a/include/ui/egl/android_natives.h b/include/ui/egl/android_natives.h index 5842ee72ce7fe..fa3b7a0dc78d8 100644 --- a/include/ui/egl/android_natives.h +++ b/include/ui/egl/android_natives.h @@ -139,32 +139,6 @@ struct android_native_window_t }; -struct android_native_buffer_t -{ -#ifdef __cplusplus - android_native_buffer_t() { - common.magic = ANDROID_NATIVE_BUFFER_MAGIC; - common.version = sizeof(android_native_buffer_t); - memset(common.reserved, 0, sizeof(common.reserved)); - } -#endif - - struct android_native_base_t common; - - int width; - int height; - int stride; - int format; - int usage; - - void* reserved[2]; - - buffer_handle_t handle; - - void* reserved_proc[8]; -}; - - /* FIXME: this is legacy for pixmaps */ struct egl_native_pixmap_t { diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp index 5e69cff985c71..4e692e2c27a19 100644 --- a/libs/ui/FramebufferNativeWindow.cpp +++ b/libs/ui/FramebufferNativeWindow.cpp @@ -38,6 +38,8 @@ #include #include +#include + // ---------------------------------------------------------------------------- namespace android { // ---------------------------------------------------------------------------- diff --git a/opengl/libagl/TextureObjectManager.cpp b/opengl/libagl/TextureObjectManager.cpp index e5d4ed2b6f970..9deb2cf9eea41 100644 --- a/opengl/libagl/TextureObjectManager.cpp +++ b/opengl/libagl/TextureObjectManager.cpp @@ -19,7 +19,7 @@ #include "context.h" #include "TextureObjectManager.h" -#include +#include namespace android { // ---------------------------------------------------------------------------- diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp index 0950f3ea26666..1a774f59db223 100644 --- a/opengl/libagl/egl.cpp +++ b/opengl/libagl/egl.cpp @@ -39,7 +39,7 @@ #include #include -#include +#include #include "context.h" #include "state.h" diff --git a/opengl/libagl/texture.cpp b/opengl/libagl/texture.cpp index 0211208e2f4a2..d675107ca0b12 100644 --- a/opengl/libagl/texture.cpp +++ b/opengl/libagl/texture.cpp @@ -23,7 +23,7 @@ #include "texture.h" #include "TextureObjectManager.h" -#include +#include #ifdef LIBAGL_USE_GRALLOC_COPYBITS #include "copybit.h" From 9bd5da4db97fec7cdbe6e07870411c1fcaff4365 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Tue, 5 May 2009 18:29:35 -0700 Subject: [PATCH 26/83] get rid off unneeded flags --- include/ui/egl/android_natives.h | 8 ++------ libs/ui/FramebufferNativeWindow.cpp | 23 +---------------------- 2 files changed, 3 insertions(+), 28 deletions(-) diff --git a/include/ui/egl/android_natives.h b/include/ui/egl/android_natives.h index fa3b7a0dc78d8..0398ea7eb7c17 100644 --- a/include/ui/egl/android_natives.h +++ b/include/ui/egl/android_natives.h @@ -41,12 +41,6 @@ extern "C" { struct android_native_buffer_t; -enum { - /* attributes of this surface or its updater */ - SURFACE_FLAG_PRESERVE_CONTENT = FRAMEBUFFER_RESERVED0, - SURFACE_FLAG_MAPPED = FRAMEBUFFER_FLAG_MAPPED, -}; - // --------------------------------------------------------------------------- struct android_native_base_t @@ -64,6 +58,7 @@ struct android_native_base_t void (*decRef)(struct android_native_base_t* base); }; +// --------------------------------------------------------------------------- struct android_native_window_t { @@ -138,6 +133,7 @@ struct android_native_window_t void* reserved_proc[5]; }; +// --------------------------------------------------------------------------- /* FIXME: this is legacy for pixmaps */ struct egl_native_pixmap_t diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp index 4e692e2c27a19..83b333f7e0e1e 100644 --- a/libs/ui/FramebufferNativeWindow.cpp +++ b/libs/ui/FramebufferNativeWindow.cpp @@ -110,28 +110,7 @@ FramebufferNativeWindow::FramebufferNativeWindow() fbDev->width, fbDev->height, strerror(-err)); } - uint32_t flags = fbDev->flags & SURFACE_FLAG_MAPPED; - - /* - * FIXME: SURFACE_FLAG_PRESERVE_CONTENT - * how to implement this, there is no concept of preserve content in - * the framebuffer, which just "posts" buffer. - * - * It looks like what we need is a way to know if the posted buffer can - * be reused. But if so, why allocating 2 buffers?... - * - * should the lock/unlock calls take care of the copy-back? - * - * - * In the end, the client wants to know if the backbuffer is preserved - * though... it's complicated. - * - */ - - //flags |= SURFACE_FLAG_PRESERVE_CONTENT; - - - const_cast(android_native_window_t::flags) = flags; + const_cast(android_native_window_t::flags) = fbDev->flags; const_cast(android_native_window_t::xdpi) = fbDev->xdpi; const_cast(android_native_window_t::ydpi) = fbDev->ydpi; const_cast(android_native_window_t::minSwapInterval) = From 2e20bffbab8084fedce39d14d7dd17b08f6e9ba2 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Mon, 4 May 2009 19:29:25 -0700 Subject: [PATCH 27/83] created an new EGL extension called ANDROID_swap_rectangle ANDROID_swap_rectangle allows to specify the rectangle affected by eglSwapBuffers(), anything outside of this rectangle is unchanged. in particular EGL_BUFFER_DESTROYED only applies to that rectangle. This extension as well as EGL_BUFFER_PRESERVED allow major optimizations on surfaceflinger, which can redraw only the dirty area during compositing. However, ANDROID_swap_rectangle allows further optimizations in EGL by reducing the amount of copy-back needed. ANDROID_swap_rectangle is particularily important for software implementations. --- .../DisplayHardware/DisplayHardware.cpp | 13 +- .../DisplayHardware/DisplayHardware.h | 1 + libs/surfaceflinger/SurfaceFlinger.cpp | 14 +- opengl/include/EGL/eglext.h | 12 + opengl/libagl/egl.cpp | 269 ++++++++++++++++-- opengl/libs/EGL/egl.cpp | 21 ++ opengl/libs/egl_entries.in | 4 + 7 files changed, 298 insertions(+), 36 deletions(-) diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp index 374f2e2c8b659..fc29d73b250a5 100644 --- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp +++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp @@ -195,17 +195,19 @@ void DisplayHardware::init(uint32_t dpy) * Create our main surface */ - surface = eglCreateWindowSurface(display, config, mNativeWindow.get(), NULL); checkEGLErrors("eglCreateDisplaySurfaceANDROID"); - if (eglQuerySurface(display, surface, EGL_SWAP_BEHAVIOR, &dummy) == EGL_TRUE) { if (dummy == EGL_BUFFER_PRESERVED) { mFlags |= BUFFER_PRESERVED; } } - + + if (strstr(egl_extensions, "ANDROID_swap_rectangle")) { + mFlags |= SWAP_RECTANGLE; + } + mDpiX = mNativeWindow->xdpi; mDpiX = mNativeWindow->ydpi; mRefreshRate = mNativeWindow->getDevice()->fps; @@ -304,11 +306,12 @@ void DisplayHardware::flip(const Region& dirty) const EGLDisplay dpy = mDisplay; EGLSurface surface = mSurface; - if (mFlags & BUFFER_PRESERVED) { + if (mFlags & SWAP_RECTANGLE) { Region newDirty(dirty); newDirty.andSelf(Rect(mWidth, mHeight)); const Rect& b(newDirty.bounds()); - //mNativeWindow->setSwapRectangle(b); + eglSetSwapRectangleANDROID(dpy, surface, + b.left, b.top, b.width(), b.height()); } mPageFlipCount++; diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h index c9c75e27744bd..c3dbff178f290 100644 --- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h +++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h @@ -50,6 +50,7 @@ public: BUFFER_PRESERVED = 0x00010000, UPDATE_ON_DEMAND = 0x00020000, // video driver feature SLOW_CONFIG = 0x00040000, // software + SWAP_RECTANGLE = 0x00080000, }; DisplayHardware( diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp index 5fd979e0614ba..b8c246cb92e71 100644 --- a/libs/surfaceflinger/SurfaceFlinger.cpp +++ b/libs/surfaceflinger/SurfaceFlinger.cpp @@ -803,12 +803,14 @@ void SurfaceFlinger::handleRepaint() mInvalidRegion.orSelf(mDirtyRegion); uint32_t flags = hw.getFlags(); - if (flags & DisplayHardware::BUFFER_PRESERVED) { - // here we assume DisplayHardware::flip()'s implementation - // performs the copy-back optimization. + if ((flags & DisplayHardware::SWAP_RECTANGLE) || + (flags & DisplayHardware::BUFFER_PRESERVED)) + { + // we can redraw only what's dirty } else { if (flags & DisplayHardware::UPDATE_ON_DEMAND) { - // we need to fully redraw the part that will be updated + // we need to redraw the rectangle that will be updated + // (pushed to the framebuffer). mDirtyRegion.set(mInvalidRegion.bounds()); } else { // we need to redraw everything @@ -890,7 +892,9 @@ void SurfaceFlinger::debugFlashRegions() { const DisplayHardware& hw(graphicPlane(0).displayHardware()); const uint32_t flags = hw.getFlags(); - if (!(flags & DisplayHardware::BUFFER_PRESERVED)) { + + if (!((flags & DisplayHardware::SWAP_RECTANGLE) || + (flags & DisplayHardware::BUFFER_PRESERVED))) { const Region repaint((flags & DisplayHardware::UPDATE_ON_DEMAND) ? mDirtyRegion.bounds() : hw.bounds()); composeSurfaces(repaint); diff --git a/opengl/include/EGL/eglext.h b/opengl/include/EGL/eglext.h index 25cfcb832fb29..335b0b03dabb9 100644 --- a/opengl/include/EGL/eglext.h +++ b/opengl/include/EGL/eglext.h @@ -131,6 +131,18 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGL /* Interfaces defined by EGL_KHR_image above */ #endif + +#ifndef EGL_ANDROID_swap_rectangle +#define EGL_ANDROID_swap_rectangle 1 +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglSetSwapRectangleANDROID (EGLDisplay dpy, EGLSurface draw, EGLint left, EGLint top, EGLint width, EGLint height); +#endif /* EGL_EGLEXT_PROTOTYPES */ +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSETSWAPRECTANGLEANDROIDPROC) (EGLDisplay dpy, EGLSurface draw, EGLint left, EGLint top, EGLint width, EGLint height); +#endif + + + + #ifdef __cplusplus } #endif diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp index 1a774f59db223..4cf0bf85def64 100644 --- a/opengl/libagl/egl.cpp +++ b/opengl/libagl/egl.cpp @@ -157,6 +157,7 @@ struct egl_surface_t virtual EGLint getRefreshRate() const; virtual EGLint getSwapBehavior() const; virtual EGLBoolean swapBuffers(); + virtual EGLBoolean setSwapRectangle(EGLint l, EGLint t, EGLint w, EGLint h); protected: GGLSurface depth; }; @@ -190,6 +191,11 @@ EGLint egl_surface_t::getRefreshRate() const { EGLint egl_surface_t::getSwapBehavior() const { return EGL_BUFFER_PRESERVED; } +EGLBoolean egl_surface_t::setSwapRectangle( + EGLint l, EGLint t, EGLint w, EGLint h) +{ + return EGL_FALSE; +} // ---------------------------------------------------------------------------- @@ -214,16 +220,104 @@ struct egl_window_surface_v2_t : public egl_surface_t virtual EGLint getVerticalResolution() const; virtual EGLint getRefreshRate() const; virtual EGLint getSwapBehavior() const; + virtual EGLBoolean setSwapRectangle(EGLint l, EGLint t, EGLint w, EGLint h); private: status_t lock(android_native_buffer_t* buf, int usage, void** vaddr); status_t unlock(android_native_buffer_t* buf); android_native_window_t* nativeWindow; android_native_buffer_t* buffer; + android_native_buffer_t* previousBuffer; gralloc_module_t const* module; int width; int height; void* bits; + GGLFormat const* pixelFormatTable; + + struct Rect { + inline Rect() { }; + inline Rect(int32_t w, int32_t h) + : left(0), top(0), right(w), bottom(h) { } + inline Rect(int32_t l, int32_t t, int32_t r, int32_t b) + : left(l), top(t), right(r), bottom(b) { } + Rect& andSelf(const Rect& r) { + left = max(left, r.left); + top = max(top, r.top); + right = min(right, r.right); + bottom = min(bottom, r.bottom); + return *this; + } + bool isEmpty() const { + return (left>=right || top>=bottom); + } + void dump(char const* what) { + LOGD("%s { %5d, %5d, w=%5d, h=%5d }", + what, left, top, right-left, bottom-top); + } + + int32_t left; + int32_t top; + int32_t right; + int32_t bottom; + }; + + struct Region { + inline Region() : count(0) { } + static Region subtract(const Rect& lhs, const Rect& rhs) { + Region reg; + Rect* storage = reg.storage; + if (!lhs.isEmpty()) { + if (lhs.top < rhs.top) { // top rect + storage->left = lhs.left; + storage->top = lhs.top; + storage->right = lhs.right; + storage->bottom = max(lhs.top, rhs.top); + storage++; + } + if (lhs.left < rhs.left) { // left-side rect + storage->left = lhs.left; + storage->top = max(lhs.top, rhs.top); + storage->right = max(lhs.left, rhs.left); + storage->bottom = min(lhs.bottom, rhs.bottom); + storage++; + } + if (lhs.right > rhs.right) { // right-side rect + storage->left = min(lhs.right, rhs.right); + storage->top = max(lhs.top, rhs.top); + storage->right = lhs.right; + storage->bottom = min(lhs.bottom, rhs.bottom); + storage++; + } + if (lhs.bottom > rhs.bottom) { // bottom rect + storage->left = lhs.left; + storage->top = min(lhs.bottom, rhs.bottom); + storage->right = lhs.right; + storage->bottom = lhs.bottom; + storage++; + } + reg.count = storage - reg.storage; + } + return reg; + } + bool isEmpty() const { + return count<=0; + } + ssize_t getRects(Rect const* * rects) const { + *rects = storage; + return count; + } + private: + Rect storage[4]; + ssize_t count; + }; + + void copyBlt( + android_native_buffer_t* dst, void* dst_vaddr, + android_native_buffer_t* src, void const* src_vaddr, + const Rect* reg, ssize_t count); + + Rect dirtyRegion; + Rect oldDirtyRegion; }; egl_window_surface_v2_t::egl_window_surface_v2_t(EGLDisplay dpy, @@ -231,16 +325,22 @@ egl_window_surface_v2_t::egl_window_surface_v2_t(EGLDisplay dpy, int32_t depthFormat, android_native_window_t* window) : egl_surface_t(dpy, config, depthFormat), - nativeWindow(window), buffer(0), module(0), bits(NULL) + nativeWindow(window), buffer(0), previousBuffer(0), module(0), + bits(NULL) { hw_module_t const* pModule; hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule); module = reinterpret_cast(pModule); + pixelFormatTable = gglGetPixelFormatTable(); + + // keep a reference on the window nativeWindow->common.incRef(&nativeWindow->common); + // dequeue a buffer nativeWindow->dequeueBuffer(nativeWindow, &buffer); - + + // allocate a corresponding depth-buffer width = buffer->width; height = buffer->height; if (depthFormat) { @@ -254,14 +354,32 @@ egl_window_surface_v2_t::egl_window_surface_v2_t(EGLDisplay dpy, } } + // keep a reference on the buffer buffer->common.incRef(&buffer->common); } +egl_window_surface_v2_t::~egl_window_surface_v2_t() { + if (buffer) { + buffer->common.decRef(&buffer->common); + } + if (previousBuffer) { + previousBuffer->common.decRef(&previousBuffer->common); + } + nativeWindow->common.decRef(&nativeWindow->common); +} + void egl_window_surface_v2_t::connect() { // Lock the buffer nativeWindow->lockBuffer(nativeWindow, buffer); - lock(buffer, GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, &bits); + // pin the buffer down + if (lock(buffer, GRALLOC_USAGE_SW_READ_OFTEN | + GRALLOC_USAGE_SW_WRITE_OFTEN, &bits) != NO_ERROR) { + LOGE("eglSwapBuffers() failed to lock buffer %p (%ux%u)", + buffer, buffer->width, buffer->height); + setError(EGL_BAD_ACCESS, EGL_NO_SURFACE); + // FIXME: we should make sure we're not accessing the buffer anymore + } } void egl_window_surface_v2_t::disconnect() @@ -286,38 +404,86 @@ status_t egl_window_surface_v2_t::unlock(android_native_buffer_t* buf) return err; } +void egl_window_surface_v2_t::copyBlt( + android_native_buffer_t* dst, void* dst_vaddr, + android_native_buffer_t* src, void const* src_vaddr, + const Rect* reg, ssize_t count) +{ + // FIXME: use copybit if possible + // NOTE: dst and src must be the same format + + Rect r; + const size_t bpp = pixelFormatTable[src->format].size; + const size_t dbpr = dst->stride * bpp; + const size_t sbpr = src->stride * bpp; -egl_window_surface_v2_t::~egl_window_surface_v2_t() { - if (buffer) { - buffer->common.decRef(&buffer->common); + uint8_t const * const src_bits = (uint8_t const *)src_vaddr; + uint8_t * const dst_bits = (uint8_t *)dst_vaddr; + + for (int i= 0 ; istride * r.top) * bpp; + uint8_t * d = dst_bits + (r.left + dst->stride * r.top) * bpp; + if (dbpr==sbpr && size==sbpr) { + size *= h; + h = 1; + } + do { + memcpy(d, s, size); + d += dbpr; + s += sbpr; + } while (--h > 0); } - nativeWindow->common.decRef(&nativeWindow->common); } EGLBoolean egl_window_surface_v2_t::swapBuffers() { - // TODO: this is roughly the code needed for preserving the back buffer - // efficiently. dirty is the area that has been modified. - //Region newDirty(dirty); - //newDirty.andSelf(Rect(nativeWindow->width, nativeWindow->height)); - //mDirty = newDirty; - //const Region copyback(mDirty.subtract(newDirty)); - //mDisplaySurface->copyFrontToBack(copyback); + /* + * Handle eglSetSwapRectangleANDROID() + * We copyback from the front buffer + */ + if (!dirtyRegion.isEmpty()) { + dirtyRegion.andSelf(Rect(buffer->width, buffer->height)); + if (previousBuffer) { + const Region copyBack(Region::subtract(oldDirtyRegion, dirtyRegion)); + if (!copyBack.isEmpty()) { + Rect const* list; + ssize_t count = copyBack.getRects(&list); + // copy from previousBuffer to buffer + void* prevBits; + if (lock(previousBuffer, + GRALLOC_USAGE_SW_READ_OFTEN, &prevBits) == NO_ERROR) + { + copyBlt(buffer, bits, previousBuffer, prevBits, list, count); + unlock(previousBuffer); + } + } + } + oldDirtyRegion = dirtyRegion; + } + if (previousBuffer) { + previousBuffer->common.decRef(&previousBuffer->common); + previousBuffer = 0; + } unlock(buffer); + previousBuffer = buffer; nativeWindow->queueBuffer(nativeWindow, buffer); - buffer->common.decRef(&buffer->common); buffer = 0; + buffer = 0; + // dequeue a new buffer nativeWindow->dequeueBuffer(nativeWindow, &buffer); - buffer->common.incRef(&buffer->common); - + // TODO: lockBuffer should rather be executed when the very first // direct rendering occurs. - void* vaddr; nativeWindow->lockBuffer(nativeWindow, buffer); - lock(buffer, GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, &bits); + // reallocate the depth-buffer if needed if ((width != buffer->width) || (height != buffer->height)) { // TODO: we probably should reset the swap rect here // if the window size has changed @@ -330,11 +496,31 @@ EGLBoolean egl_window_surface_v2_t::swapBuffers() depth.stride = buffer->stride; depth.data = (GGLubyte*)malloc(depth.stride*depth.height*2); if (depth.data == 0) { - setError(EGL_BAD_ALLOC, EGL_NO_SURFACE); + setError(EGL_BAD_ALLOC, EGL_FALSE); return EGL_FALSE; } } } + + // keep a reference on the buffer + buffer->common.incRef(&buffer->common); + + // finally pin the buffer down + if (lock(buffer, GRALLOC_USAGE_SW_READ_OFTEN | + GRALLOC_USAGE_SW_WRITE_OFTEN, &bits) != NO_ERROR) { + LOGE("eglSwapBuffers() failed to lock buffer %p (%ux%u)", + buffer, buffer->width, buffer->height); + setError(EGL_BAD_ACCESS, EGL_NO_SURFACE); + // FIXME: we should make sure we're not accessing the buffer anymore + } + + return EGL_TRUE; +} + +EGLBoolean egl_window_surface_v2_t::setSwapRectangle( + EGLint l, EGLint t, EGLint w, EGLint h) +{ + dirtyRegion = Rect(l, t, l+w, t+h); return EGL_TRUE; } @@ -402,12 +588,22 @@ EGLint egl_window_surface_v2_t::getVerticalResolution() const { EGLint egl_window_surface_v2_t::getRefreshRate() const { return (60 * EGL_DISPLAY_SCALING); // FIXME } -EGLint egl_window_surface_v2_t::getSwapBehavior() const { - //uint32_t flags = nativeWindow->flags; - //if (flags & SURFACE_FLAG_PRESERVE_CONTENT) - // return EGL_BUFFER_PRESERVED; - // This is now a feature of EGL, currently we don't preserve - // the content of the buffers. +EGLint egl_window_surface_v2_t::getSwapBehavior() const +{ + /* + * EGL_BUFFER_PRESERVED means that eglSwapBuffers() completely preserves + * the content of the swapped buffer. + * + * EGL_BUFFER_DESTROYED means that the content of the buffer is lost. + * + * However when ANDROID_swap_retcangle is supported, EGL_BUFFER_DESTROYED + * only applies to the area specified by eglSetSwapRectangleANDROID(), that + * is, everything outside of this area is preserved. + * + * This implementation of EGL assumes the later case. + * + */ + return EGL_BUFFER_DESTROYED; } @@ -581,6 +777,7 @@ static char const * const gExtensionsString = "KHR_image_base " // "KHR_image_pixmap " "EGL_ANDROID_image_native_buffer " + "EGL_ANDROID_swap_rectangle " ; // ---------------------------------------------------------------------------- @@ -1765,3 +1962,23 @@ EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img) return EGL_TRUE; } + +// ---------------------------------------------------------------------------- +// ANDROID extensions +// ---------------------------------------------------------------------------- + +EGLBoolean eglSetSwapRectangleANDROID(EGLDisplay dpy, EGLSurface draw, + EGLint left, EGLint top, EGLint width, EGLint height) +{ + if (egl_display_t::is_valid(dpy) == EGL_FALSE) + return setError(EGL_BAD_DISPLAY, EGL_FALSE); + + egl_surface_t* d = static_cast(draw); + if (d->dpy != dpy) + return setError(EGL_BAD_DISPLAY, EGL_FALSE); + + // post the surface + d->setSwapRectangle(left, top, width, height); + + return EGL_TRUE; +} diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp index 74aed2062055a..8c37f2e8b695f 100644 --- a/opengl/libs/EGL/egl.cpp +++ b/opengl/libs/EGL/egl.cpp @@ -60,6 +60,7 @@ static char const * const gExtensionString = "KHR_image_base " "KHR_image_pixmap " "EGL_ANDROID_image_native_buffer " + "EGL_ANDROID_swap_rectangle " ; // ---------------------------------------------------------------------------- @@ -1568,3 +1569,23 @@ EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img) return EGL_FALSE; } + + +// ---------------------------------------------------------------------------- +// ANDROID extensions +// ---------------------------------------------------------------------------- + +EGLBoolean eglSetSwapRectangleANDROID(EGLDisplay dpy, EGLSurface draw, + EGLint left, EGLint top, EGLint width, EGLint height) +{ + if (!validate_display_surface(dpy, draw)) + return EGL_FALSE; + egl_display_t const * const dp = get_display(dpy); + egl_surface_t const * const s = get_surface(draw); + if (s->cnx->hooks->egl.eglSetSwapRectangleANDROID) { + return s->cnx->hooks->egl.eglSetSwapRectangleANDROID(dp->dpys[s->impl], + s->surface, left, top, width, height); + } + return EGL_FALSE; +} + diff --git a/opengl/libs/egl_entries.in b/opengl/libs/egl_entries.in index 3b4551b639646..1fe2b5702d349 100644 --- a/opengl/libs/egl_entries.in +++ b/opengl/libs/egl_entries.in @@ -50,3 +50,7 @@ EGL_ENTRY(EGLBoolean, eglLockSurfaceKHR, EGLDisplay, EGLSurface, const EGLint EGL_ENTRY(EGLBoolean, eglUnlockSurfaceKHR, EGLDisplay, EGLSurface) EGL_ENTRY(EGLImageKHR, eglCreateImageKHR, EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, const EGLint *) EGL_ENTRY(EGLBoolean, eglDestroyImageKHR, EGLDisplay, EGLImageKHR) + +/* ANDROID extensions */ + +EGL_ENTRY(EGLBoolean, eglSetSwapRectangleANDROID, EGLDisplay, EGLSurface, EGLint, EGLint, EGLint, EGLint) From 927d37cb788670b91af0f1a7a93c68046a838d23 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Wed, 6 May 2009 23:47:08 -0700 Subject: [PATCH 28/83] fix EGL extension string names --- libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp | 4 ++-- opengl/libagl/egl.cpp | 2 +- opengl/libs/EGL/egl.cpp | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp index fc29d73b250a5..31db31f9abb58 100644 --- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp +++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp @@ -204,7 +204,7 @@ void DisplayHardware::init(uint32_t dpy) } } - if (strstr(egl_extensions, "ANDROID_swap_rectangle")) { + if (strstr(egl_extensions, "EGL_ANDROID_swap_rectangle")) { mFlags |= SWAP_RECTANGLE; } @@ -250,7 +250,7 @@ void DisplayHardware::init(uint32_t dpy) mFlags |= DRAW_TEXTURE_EXTENSION; } if (strstr( gl_extensions, "GL_OES_EGL_image") && - (strstr(egl_extensions, "KHR_image_base") || + (strstr(egl_extensions, "EGL_KHR_image_base") || strstr(egl_extensions, "EGL_KHR_image")) && strstr(egl_extensions, "EGL_ANDROID_image_native_buffer")) { mFlags |= DIRECT_TEXTURE; diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp index 4cf0bf85def64..f50257abb7e8e 100644 --- a/opengl/libagl/egl.cpp +++ b/opengl/libagl/egl.cpp @@ -774,7 +774,7 @@ static char const * const gVendorString = "Google Inc."; static char const * const gVersionString = "1.2 Android Driver"; static char const * const gClientApiString = "OpenGL ES"; static char const * const gExtensionsString = - "KHR_image_base " + "EGL_KHR_image_base " // "KHR_image_pixmap " "EGL_ANDROID_image_native_buffer " "EGL_ANDROID_swap_rectangle " diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp index 8c37f2e8b695f..6c805388ce8aa 100644 --- a/opengl/libs/EGL/egl.cpp +++ b/opengl/libs/EGL/egl.cpp @@ -57,8 +57,8 @@ static char const * const gVersionString = "1.31 Android META-EGL"; static char const * const gClientApiString = "OpenGL ES"; static char const * const gExtensionString = "EGL_KHR_image " - "KHR_image_base " - "KHR_image_pixmap " + "EGL_KHR_image_base " + "EGL_KHR_image_pixmap " "EGL_ANDROID_image_native_buffer " "EGL_ANDROID_swap_rectangle " ; From 97b8056c3182a973c67d3c1b196150d4b9e30f3a Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Thu, 7 May 2009 17:40:23 -0700 Subject: [PATCH 29/83] add support for update-on-demand in SurfaceFlinger --- include/ui/FramebufferNativeWindow.h | 4 ++++ .../DisplayHardware/DisplayHardware.cpp | 12 +++++++++--- libs/ui/FramebufferNativeWindow.cpp | 12 +++++++++++- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/include/ui/FramebufferNativeWindow.h b/include/ui/FramebufferNativeWindow.h index aad39a2a6b8b6..a7804728c4ea3 100644 --- a/include/ui/FramebufferNativeWindow.h +++ b/include/ui/FramebufferNativeWindow.h @@ -52,6 +52,9 @@ public: framebuffer_device_t const * getDevice() const { return fbDev; } + bool isUpdateOnDemand() const { return mUpdateOnDemand; } + status_t setUpdateRectangle(const Rect& updateRect); + private: friend class LightRefBase; ~FramebufferNativeWindow(); // this class cannot be overloaded @@ -71,6 +74,7 @@ private: int32_t mNumBuffers; int32_t mNumFreeBuffers; int32_t mBufferHead; + bool mUpdateOnDemand; }; // --------------------------------------------------------------------------- diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp index 31db31f9abb58..25e351c10f865 100644 --- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp +++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp @@ -183,9 +183,11 @@ void DisplayHardware::init(uint32_t dpy) LOGI("extensions: %s", egl_extensions); LOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported"); - // TODO: get the real "update_on_demand" behavior (probably should be HAL module) - // FIXME: mFlags |= UPDATE_ON_DEMAND; + if (mNativeWindow->isUpdateOnDemand()) { + mFlags |= UPDATE_ON_DEMAND; + } + if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) == EGL_TRUE) { if (dummy == EGL_SLOW_CONFIG) mFlags |= SLOW_CONFIG; @@ -210,7 +212,7 @@ void DisplayHardware::init(uint32_t dpy) mDpiX = mNativeWindow->xdpi; mDpiX = mNativeWindow->ydpi; - mRefreshRate = mNativeWindow->getDevice()->fps; + mRefreshRate = fbDev->fps; char property[PROPERTY_VALUE_MAX]; if (property_get("ro.sf.lcd_density", property, NULL) <= 0) { @@ -314,6 +316,10 @@ void DisplayHardware::flip(const Region& dirty) const b.left, b.top, b.width(), b.height()); } + if (mFlags & UPDATE_ON_DEMAND) { + mNativeWindow->setUpdateRectangle(dirty.bounds()); + } + mPageFlipCount++; eglSwapBuffers(dpy, surface); checkEGLErrors("eglSwapBuffers"); diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp index 83b333f7e0e1e..8c8fd6bb0f9dd 100644 --- a/libs/ui/FramebufferNativeWindow.cpp +++ b/libs/ui/FramebufferNativeWindow.cpp @@ -76,7 +76,7 @@ private: */ FramebufferNativeWindow::FramebufferNativeWindow() - : BASE(), fbDev(0), grDev(0) + : BASE(), fbDev(0), grDev(0), mUpdateOnDemand(false) { hw_module_t const* module; if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) { @@ -86,6 +86,8 @@ FramebufferNativeWindow::FramebufferNativeWindow() int err; + mUpdateOnDemand = (fbDev->setUpdateRect != 0); + // initialize the buffer FIFO mNumBuffers = 2; mNumFreeBuffers = 2; @@ -131,6 +133,14 @@ FramebufferNativeWindow::~FramebufferNativeWindow() { framebuffer_close(fbDev); } +status_t FramebufferNativeWindow::setUpdateRectangle(const Rect& r) +{ + if (!mUpdateOnDemand) { + return INVALID_OPERATION; + } + return fbDev->setUpdateRect(fbDev, r.left, r.top, r.width(), r.height()); +} + int FramebufferNativeWindow::setSwapInterval( android_native_window_t* window, int interval) { From 11be99de5f3901c32130ea4c5fd52e62e1845e73 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Sun, 17 May 2009 18:50:16 -0700 Subject: [PATCH 30/83] remove libEGL and libGLESv1_CM dependencies on libutils and libui --- opengl/libs/Android.mk | 4 +- opengl/libs/EGL/egl.cpp | 5 +- opengl/libs/EGL/gpu.cpp | 212 ---------------------------------------- 3 files changed, 3 insertions(+), 218 deletions(-) delete mode 100644 opengl/libs/EGL/gpu.cpp diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk index 538e9436c3c8e..c8e11f0a5f718 100644 --- a/opengl/libs/Android.mk +++ b/opengl/libs/Android.mk @@ -10,7 +10,7 @@ LOCAL_SRC_FILES:= \ EGL/egl.cpp \ # -LOCAL_SHARED_LIBRARIES += libcutils libutils libui +LOCAL_SHARED_LIBRARIES += libcutils LOCAL_LDLIBS := -lpthread -ldl LOCAL_MODULE:= libEGL @@ -40,7 +40,7 @@ LOCAL_SRC_FILES:= \ GLES_CM/gl.cpp.arm \ # -LOCAL_SHARED_LIBRARIES += libcutils libutils libui libEGL +LOCAL_SHARED_LIBRARIES += libcutils libEGL LOCAL_LDLIBS := -lpthread -ldl LOCAL_MODULE:= libGLESv1_CM diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp index 7cdf494185ca4..2493fc67ee226 100644 --- a/opengl/libs/EGL/egl.cpp +++ b/opengl/libs/EGL/egl.cpp @@ -15,6 +15,7 @@ */ #include +#include #include #include #include @@ -35,10 +36,6 @@ #include #include -#include -#include -#include - #include "hooks.h" #include "egl_impl.h" diff --git a/opengl/libs/EGL/gpu.cpp b/opengl/libs/EGL/gpu.cpp deleted file mode 100644 index f9dc5f17212e9..0000000000000 --- a/opengl/libs/EGL/gpu.cpp +++ /dev/null @@ -1,212 +0,0 @@ -/* - ** Copyright 2007, 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. - */ - -#define LOG_TAG "EGL" - -#include -#include -#include - -#include - -#if HAVE_ANDROID_OS -#include -#endif - -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -#include "hooks.h" -#include "egl_impl.h" - -// ---------------------------------------------------------------------------- -namespace android { -// ---------------------------------------------------------------------------- - -/* - * we provide our own allocators for the GPU regions, these - * allocators go through surfaceflinger - */ - -static Mutex gRegionsLock; -static request_gpu_t gRegions; -static sp gSurfaceManager; -GL_API ISurfaceComposer* GLES_localSurfaceManager = 0; - -extern egl_connection_t gEGLImpl[2]; - -const sp& getSurfaceFlinger() -{ - Mutex::Autolock _l(gRegionsLock); - - /* - * There is a little bit of voodoo magic here. We want to access - * surfaceflinger for allocating GPU regions, however, when we are - * running as part of surfaceflinger, we want to bypass the - * service manager because surfaceflinger might not be registered yet. - * SurfaceFlinger will populate "GLES_localSurfaceManager" with its - * own address, so we can just use that. - */ - if (gSurfaceManager == 0) { - if (GLES_localSurfaceManager) { - // we're running in SurfaceFlinger's context - gSurfaceManager = GLES_localSurfaceManager; - } else { - // we're a remote process or not part of surfaceflinger, - // go through the service manager - sp sm = defaultServiceManager(); - if (sm != NULL) { - sp binder = sm->getService(String16("SurfaceFlinger")); - gSurfaceManager = interface_cast(binder); - } - } - } - return gSurfaceManager; -} - -class GPURevokeRequester : public BnGPUCallback -{ -public: - virtual void gpuLost() { - LOGD("CONTEXT_LOST: Releasing GPU upon request from SurfaceFlinger."); - gEGLImpl[IMPL_HARDWARE].hooks = &gHooks[IMPL_CONTEXT_LOST]; - } -}; - -static sp gRevokerCallback; - - -request_gpu_t* gpu_acquire(void* user) -{ - sp server( getSurfaceFlinger() ); - - Mutex::Autolock _l(gRegionsLock); - if (server == NULL) { - return 0; - } - - ISurfaceComposer::gpu_info_t info; - - if (gRevokerCallback == 0) - gRevokerCallback = new GPURevokeRequester(); - - status_t err = server->requestGPU(gRevokerCallback, &info); - if (err != NO_ERROR) { - LOGD("requestGPU returned %d", err); - return 0; - } - - bool failed = false; - request_gpu_t* gpu = &gRegions; - memset(gpu, 0, sizeof(*gpu)); - - if (info.regs != 0) { - sp heap(info.regs->getMemory()); - if (heap != 0) { - int fd = heap->heapID(); - gpu->regs.fd = fd; - gpu->regs.base = info.regs->pointer(); - gpu->regs.size = info.regs->size(); - gpu->regs.user = info.regs.get(); -#if HAVE_ANDROID_OS - struct pmem_region region; - if (ioctl(fd, PMEM_GET_PHYS, ®ion) >= 0) - gpu->regs.phys = (void*)region.offset; -#endif - info.regs->incStrong(gpu); - } else { - LOGE("GPU register handle %p is invalid!", info.regs.get()); - failed = true; - } - } - - for (size_t i=0 ; i& region(info.regions[i].region); - if (region != 0) { - sp heap(region->getMemory()); - if (heap != 0) { - const int fd = heap->heapID(); - gpu->gpu[i].fd = fd; - gpu->gpu[i].base = region->pointer(); - gpu->gpu[i].size = region->size(); - gpu->gpu[i].user = region.get(); - gpu->gpu[i].offset = info.regions[i].reserved; -#if HAVE_ANDROID_OS - struct pmem_region reg; - if (ioctl(fd, PMEM_GET_PHYS, ®) >= 0) - gpu->gpu[i].phys = (void*)reg.offset; -#endif - region->incStrong(gpu); - } else { - LOGE("GPU region handle [%d, %p] is invalid!", i, region.get()); - failed = true; - } - } - } - - if (failed) { - // something went wrong, clean up everything! - if (gpu->regs.user) { - static_cast(gpu->regs.user)->decStrong(gpu); - for (size_t i=0 ; igpu[i].user) { - static_cast(gpu->gpu[i].user)->decStrong(gpu); - } - } - } - } - - gpu->count = info.count; - return gpu; -} - -int gpu_release(void*, request_gpu_t* gpu) -{ - sp regs; - - { // scope for lock - Mutex::Autolock _l(gRegionsLock); - regs = static_cast(gpu->regs.user); - gpu->regs.user = 0; - if (regs != 0) regs->decStrong(gpu); - - for (int i=0 ; icount ; i++) { - sp r(static_cast(gpu->gpu[i].user)); - gpu->gpu[i].user = 0; - if (r != 0) r->decStrong(gpu); - } - } - - // there is a special transaction to relinquish the GPU - // (it will happen automatically anyway if we don't do this) - Parcel data, reply; - // NOTE: this transaction does not require an interface token - regs->asBinder()->transact(1000, data, &reply); - return 1; -} - -// ---------------------------------------------------------------------------- -}; // namespace android -// ---------------------------------------------------------------------------- From 6158b1bf0364da1582468a98ec09d004ba99deec Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Mon, 11 May 2009 00:03:41 -0700 Subject: [PATCH 31/83] Region now has its own implementation instead of relying on SkRegion, which allows us to break libui's dependency on libcorecg. --- core/jni/android_view_Surface.cpp | 35 +- include/private/ui/RegionHelper.h | 279 +++++++++++ include/ui/Rect.h | 37 +- include/ui/Region.h | 99 ++-- libs/surfaceflinger/LayerBase.cpp | 36 +- libs/surfaceflinger/LayerBlur.cpp | 35 +- libs/surfaceflinger/LayerDim.cpp | 9 +- libs/surfaceflinger/SurfaceFlinger.cpp | 21 +- libs/surfaceflinger/Transform.cpp | 8 +- libs/ui/Android.mk | 1 - libs/ui/Region.cpp | 643 +++++++++++++++++++------ libs/ui/Surface.cpp | 10 +- libs/ui/tests/Android.mk | 16 + libs/ui/tests/region.cpp | 62 +++ 14 files changed, 1041 insertions(+), 250 deletions(-) create mode 100644 include/private/ui/RegionHelper.h create mode 100644 libs/ui/tests/Android.mk create mode 100644 libs/ui/tests/region.cpp diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp index 823fafd98feab..bd3c80506daad 100644 --- a/core/jni/android_view_Surface.cpp +++ b/core/jni/android_view_Surface.cpp @@ -24,6 +24,7 @@ #include #include +#include #include "jni.h" #include @@ -268,7 +269,7 @@ static jobject Surface_lockCanvas(JNIEnv* env, jobject clazz, jobject dirtyRect) dirty.top = env->GetIntField(dirtyRect, ro.t); dirty.right = env->GetIntField(dirtyRect, ro.r); dirty.bottom= env->GetIntField(dirtyRect, ro.b); - if (dirty.left < dirty.right && dirty.top < dirty.bottom) { + if (!dirty.isEmpty()) { dirtyRegion.set(dirty); } } else { @@ -300,13 +301,27 @@ static jobject Surface_lockCanvas(JNIEnv* env, jobject clazz, jobject dirtyRect) bitmap.setPixels(NULL); } nativeCanvas->setBitmapDevice(bitmap); - nativeCanvas->clipRegion(dirtyRegion.toSkRegion()); + + SkRegion clipReg; + if (dirtyRegion.isRect()) { // very common case + const Rect& b(dirtyRegion.getBounds()); + clipReg.setRect(b.left, b.top, b.right, b.bottom); + } else { + size_t count; + Rect const* r = dirtyRegion.getArray(&count); + while (count) { + clipReg.op(r->left, r->top, r->right, r->bottom, SkRegion::kUnion_Op); + r++, count--; + } + } + + nativeCanvas->clipRegion(clipReg); int saveCount = nativeCanvas->save(); env->SetIntField(clazz, so.saveCount, saveCount); if (dirtyRect) { - Rect bounds(dirtyRegion.bounds()); + const Rect& bounds(dirtyRegion.getBounds()); env->SetIntField(dirtyRect, ro.l, bounds.left); env->SetIntField(dirtyRect, ro.t, bounds.top); env->SetIntField(dirtyRect, ro.r, bounds.right); @@ -475,7 +490,19 @@ static void Surface_setTransparentRegion( const sp& surface(getSurfaceControl(env, clazz)); if (surface == 0) return; SkRegion* nativeRegion = (SkRegion*)env->GetIntField(argRegion, no.native_region); - status_t err = surface->setTransparentRegionHint(Region(*nativeRegion)); + + const SkIRect& b(nativeRegion->getBounds()); + Region reg(Rect(b.fLeft, b.fTop, b.fRight, b.fBottom)); + if (nativeRegion->isComplex()) { + SkRegion::Iterator it(*nativeRegion); + while (!it.done()) { + const SkIRect& r(it.rect()); + reg.addRectUnchecked(r.fLeft, r.fTop, r.fRight, r.fBottom); + it.next(); + } + } + + status_t err = surface->setTransparentRegionHint(reg); if (err<0 && err!=NO_INIT) doThrow(env, "java/lang/IllegalArgumentException", NULL); } diff --git a/include/private/ui/RegionHelper.h b/include/private/ui/RegionHelper.h new file mode 100644 index 0000000000000..6c847ff30b678 --- /dev/null +++ b/include/private/ui/RegionHelper.h @@ -0,0 +1,279 @@ +/* + * Copyright (C) 2009 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. + */ + +#ifndef ANDROID_UI_PRIVATE_REGION_HELPER_H +#define ANDROID_UI_PRIVATE_REGION_HELPER_H + +#include +#include + +namespace android { +// ---------------------------------------------------------------------------- + +template +class region_operator +{ + typedef typename RECT::value_type TYPE; + static const TYPE max_value = 0x7FFFFFF; + +public: + /* + * Common boolean operations: + * value is computed as 0b101 op 0b110 + * other boolean operation are possible, simply compute + * their corresponding value with the above formulae and use + * it when instantiating a region_operator. + */ + static const uint32_t LHS = 0x5; // 0b101 + static const uint32_t RHS = 0x6; // 0b110 + enum { + op_nand = LHS & ~RHS, + op_and = LHS & RHS, + op_or = LHS | RHS, + op_xor = LHS ^ RHS + }; + + struct region { + RECT const* rects; + size_t count; + TYPE dx; + TYPE dy; + inline region(const region& rhs) + : rects(rhs.rects), count(rhs.count), dx(rhs.dx), dy(rhs.dy) { } + inline region(RECT const* r, size_t c) + : rects(r), count(c), dx(), dy() { } + inline region(RECT const* r, size_t c, TYPE dx, TYPE dy) + : rects(r), count(c), dx(dx), dy(dy) { } + }; + + class region_rasterizer { + friend class region_operator; + virtual void operator()(const RECT& rect) = 0; + }; + + inline region_operator(int op, const region& lhs, const region& rhs) + : op_mask(op), spanner(lhs, rhs) + { + } + + void operator()(region_rasterizer& rasterizer) { + RECT current; + do { + SpannerInner spannerInner(spanner.lhs, spanner.rhs); + int inside = spanner.next(current.top, current.bottom); + spannerInner.prepare(inside); + do { + TYPE left, right; + int inside = spannerInner.next(current.left, current.right); + if ((op_mask >> inside) & 1) { + if (current.left < current.right && + current.top < current.bottom) { + rasterizer(current); + } + } + } while(!spannerInner.isDone()); + } while(!spanner.isDone()); + } + +private: + uint32_t op_mask; + + class SpannerBase + { + public: + enum { + lhs_before_rhs = 0, + lhs_after_rhs = 1, + lhs_coincide_rhs = 2 + }; + + protected: + TYPE lhs_head; + TYPE lhs_tail; + TYPE rhs_head; + TYPE rhs_tail; + + inline int next(TYPE& head, TYPE& tail, + bool& more_lhs, bool& more_rhs) + { + int inside; + more_lhs = false; + more_rhs = false; + if (lhs_head < rhs_head) { + inside = lhs_before_rhs; + head = lhs_head; + if (lhs_tail <= rhs_head) { + tail = lhs_tail; + more_lhs = true; + } else { + lhs_head = rhs_head; + tail = rhs_head; + } + } else if (rhs_head < lhs_head) { + inside = lhs_after_rhs; + head = rhs_head; + if (rhs_tail <= lhs_head) { + tail = rhs_tail; + more_rhs = true; + } else { + rhs_head = lhs_head; + tail = lhs_head; + } + } else { + inside = lhs_coincide_rhs; + head = lhs_head; + if (lhs_tail <= rhs_tail) { + tail = rhs_head = lhs_tail; + more_lhs = true; + } + if (rhs_tail <= lhs_tail) { + tail = lhs_head = rhs_tail; + more_rhs = true; + } + } + return inside; + } + }; + + class Spanner : protected SpannerBase + { + friend class region_operator; + region lhs; + region rhs; + + public: + inline Spanner(const region& lhs, const region& rhs) + : lhs(lhs), rhs(rhs) + { + SpannerBase::lhs_head = lhs.rects->top + lhs.dy; + SpannerBase::lhs_tail = lhs.rects->bottom + lhs.dy; + SpannerBase::rhs_head = rhs.rects->top + rhs.dy; + SpannerBase::rhs_tail = rhs.rects->bottom + rhs.dy; + } + + inline bool isDone() const { + return !rhs.count && !lhs.count; + } + + inline int next(TYPE& top, TYPE& bottom) + { + bool more_lhs = false; + bool more_rhs = false; + int inside = SpannerBase::next(top, bottom, more_lhs, more_rhs); + if (more_lhs) { + advance(lhs, SpannerBase::lhs_head, SpannerBase::lhs_tail); + } + if (more_rhs) { + advance(rhs, SpannerBase::rhs_head, SpannerBase::rhs_tail); + } + return inside; + } + + private: + static inline + void advance(region& reg, TYPE& aTop, TYPE& aBottom) { + // got to next span + size_t count = reg.count; + RECT const * rects = reg.rects; + RECT const * const end = rects + count; + const int top = rects->top; + while (rects != end && rects->top == top) { + rects++; + count--; + } + if (rects != end) { + aTop = rects->top + reg.dy; + aBottom = rects->bottom + reg.dy; + } else { + aTop = max_value; + aBottom = max_value; + } + reg.rects = rects; + reg.count = count; + } + }; + + class SpannerInner : protected SpannerBase + { + region lhs; + region rhs; + + public: + inline SpannerInner(const region& lhs, const region& rhs) + : lhs(lhs), rhs(rhs) + { + } + + inline void prepare(int inside) { + SpannerBase::lhs_head = lhs.rects->left + lhs.dx; + SpannerBase::lhs_tail = lhs.rects->right + lhs.dx; + SpannerBase::rhs_head = rhs.rects->left + rhs.dx; + SpannerBase::rhs_tail = rhs.rects->right + rhs.dx; + if (inside == SpannerBase::lhs_before_rhs) { + SpannerBase::rhs_head = max_value; + SpannerBase::rhs_tail = max_value; + } else if (inside == SpannerBase::lhs_after_rhs) { + SpannerBase::lhs_head = max_value; + SpannerBase::lhs_tail = max_value; + } else { + // use both spans + } + } + + inline bool isDone() const { + return SpannerBase::lhs_head == max_value && + SpannerBase::rhs_head == max_value; + } + + inline int next(TYPE& left, TYPE& right) + { + bool more_lhs = false; + bool more_rhs = false; + int inside = SpannerBase::next(left, right, more_lhs, more_rhs); + if (more_lhs) { + advance(lhs, SpannerBase::lhs_head, SpannerBase::lhs_tail); + } + if (more_rhs) { + advance(rhs, SpannerBase::rhs_head, SpannerBase::rhs_tail); + } + return inside; + } + + private: + static inline + void advance(region& reg, TYPE& left, TYPE& right) { + if (reg.rects && reg.count) { + const int cur_span_top = reg.rects->top; + reg.rects++; + reg.count--; + if (!reg.count || reg.rects->top != cur_span_top) { + left = max_value; + right = max_value; + } else { + left = reg.rects->left + reg.dx; + right = reg.rects->right + reg.dx; + } + } + } + }; + + Spanner spanner; +}; + +// ---------------------------------------------------------------------------- +}; + +#endif /* ANDROID_UI_PRIVATE_REGION_HELPER_H */ diff --git a/include/ui/Rect.h b/include/ui/Rect.h index d232847113ab7..902324d51198f 100644 --- a/include/ui/Rect.h +++ b/include/ui/Rect.h @@ -30,6 +30,8 @@ public: int right; int bottom; + typedef int value_type; + // we don't provide copy-ctor and operator= on purpose // because we want the compiler generated versions @@ -54,6 +56,10 @@ public: void makeInvalid(); + inline void clear() { + left = top = right = bottom = 0; + } + // a valid rectangle has a non negative width and height inline bool isValid() const { return (width()>=0) && (height()>=0); @@ -78,28 +84,29 @@ public: return bottom-top; } - // returns left-top Point non-const reference, can be assigned - inline Point& leftTop() { - return reinterpret_cast(left); - } - // returns right bottom non-const reference, can be assigned - inline Point& rightBottom() { - return reinterpret_cast(right); - } - // the following 4 functions return the 4 corners of the rect as Point - inline const Point& leftTop() const { - return reinterpret_cast(left); + inline Point leftTop() const { + return Point(left, top); } - inline const Point& rightBottom() const { - return reinterpret_cast(right); + inline Point rightBottom() const { + return Point(right, bottom); } - Point rightTop() const { + inline Point rightTop() const { return Point(right, top); } - Point leftBottom() const { + inline Point leftBottom() const { return Point(left, bottom); } + + inline void setLeftTop(const Point& p) { + left = p.x; + top = p.y; + } + + inline void setRightBottom(const Point& p) { + right = p.x; + bottom = p.y; + } // comparisons inline bool operator == (const Rect& rhs) const { diff --git a/include/ui/Region.h b/include/ui/Region.h index 5efeff7d32adb..849369d3b4d8c 100644 --- a/include/ui/Region.h +++ b/include/ui/Region.h @@ -27,8 +27,6 @@ #include -#include - namespace android { // --------------------------------------------------------------------------- @@ -40,7 +38,6 @@ class Region public: Region(); Region(const Region& rhs); - explicit Region(const SkRegion& rhs); explicit Region(const Rect& rhs); explicit Region(const Parcel& parcel); explicit Region(const void* buffer); @@ -48,12 +45,11 @@ public: Region& operator = (const Region& rhs); - inline bool isEmpty() const { return mRegion.isEmpty(); } - inline bool isRect() const { return mRegion.isRect(); } + inline bool isEmpty() const { return mBounds.isEmpty(); } + inline bool isRect() const { return mStorage.isEmpty(); } - Rect bounds() const; - - const SkRegion& toSkRegion() const; + inline const Rect& getBounds() const { return mBounds; } + inline const Rect& bounds() const { return getBounds(); } void clear(); void set(const Rect& r); @@ -61,23 +57,29 @@ public: Region& orSelf(const Rect& rhs); Region& andSelf(const Rect& rhs); + Region& subtractSelf(const Rect& rhs); // boolean operators, applied on this Region& orSelf(const Region& rhs); Region& andSelf(const Region& rhs); Region& subtractSelf(const Region& rhs); - // these translate rhs first - Region& translateSelf(int dx, int dy); - Region& orSelf(const Region& rhs, int dx, int dy); - Region& andSelf(const Region& rhs, int dx, int dy); - Region& subtractSelf(const Region& rhs, int dx, int dy); + // boolean operators + Region merge(const Rect& rhs) const; + Region intersect(const Rect& rhs) const; + Region subtract(const Rect& rhs) const; // boolean operators Region merge(const Region& rhs) const; Region intersect(const Region& rhs) const; Region subtract(const Region& rhs) const; + // these translate rhs first + Region& translateSelf(int dx, int dy); + Region& orSelf(const Region& rhs, int dx, int dy); + Region& andSelf(const Region& rhs, int dx, int dy); + Region& subtractSelf(const Region& rhs, int dx, int dy); + // these translate rhs first Region translate(int dx, int dy) const; Region merge(const Region& rhs, int dx, int dy) const; @@ -95,19 +97,23 @@ public: inline Region& operator -= (const Region& rhs); inline Region& operator += (const Point& pt); - class iterator { - SkRegion::Iterator mIt; - public: - iterator(const Region& r); - inline operator bool () const { return !done(); } - int iterate(Rect* rect); - private: - inline bool done() const { - return const_cast(mIt).done(); - } - }; + + /* various ways to access the rectangle list */ + + typedef Rect const* const_iterator; + + const_iterator begin() const; + const_iterator end() const; - size_t rects(Vector& rectList) const; + /* no user serviceable parts here... */ + + size_t getRects(Vector& rectList) const; + Rect const* getArray(size_t* count) const; + + + // add a rectangle to the internal list. This rectangle must + // be sorted in Y and X and must not make the region invalid. + void addRectUnchecked(int l, int t, int r, int b); // flatten/unflatten a region to/from a Parcel status_t write(Parcel& parcel) const; @@ -124,7 +130,33 @@ public: void dump(const char* what, uint32_t flags=0) const; private: - SkRegion mRegion; + class rasterizer; + friend class rasterizer; + + Region& operationSelf(const Rect& r, int op); + Region& operationSelf(const Region& r, int op); + Region& operationSelf(const Region& r, int dx, int dy, int op); + Region operation(const Rect& rhs, int op) const; + Region operation(const Region& rhs, int op) const; + Region operation(const Region& rhs, int dx, int dy, int op) const; + + static void boolean_operation(int op, Region& dst, + const Region& lhs, const Region& rhs, int dx, int dy); + static void boolean_operation(int op, Region& dst, + const Region& lhs, const Rect& rhs, int dx, int dy); + + static void boolean_operation(int op, Region& dst, + const Region& lhs, const Region& rhs); + static void boolean_operation(int op, Region& dst, + const Region& lhs, const Rect& rhs); + + static void translate(Region& reg, int dx, int dy); + static void translate(Region& dst, const Region& reg, int dx, int dy); + + static bool validate(const Region& reg, const char* name); + + Rect mBounds; + Vector mStorage; }; @@ -158,16 +190,23 @@ Region& Region::operator += (const Point& pt) { // --------------------------------------------------------------------------- struct region_iterator : public copybit_region_t { - region_iterator(const Region& region) : i(region) { + region_iterator(const Region& region) + : b(region.begin()), e(region.end()) { this->next = iterate; } private: static int iterate(copybit_region_t const * self, copybit_rect_t* rect) { - return static_cast(self) - ->i.iterate(reinterpret_cast(rect)); + region_iterator const* me = static_cast(self); + if (me->b != me->e) { + *reinterpret_cast(rect) = *me->b++; + return 1; + } + return 0; } - mutable Region::iterator i; + mutable Region::const_iterator b; + Region::const_iterator const e; }; + // --------------------------------------------------------------------------- }; // namespace android diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp index cc9c586b421ab..4547a8344f9e8 100644 --- a/libs/surfaceflinger/LayerBase.cpp +++ b/libs/surfaceflinger/LayerBase.cpp @@ -289,8 +289,9 @@ void LayerBase::invalidate() void LayerBase::drawRegion(const Region& reg) const { - Region::iterator iterator(reg); - if (iterator) { + Region::const_iterator it = reg.begin(); + Region::const_iterator const end = reg.end(); + if (it != end) { Rect r; const DisplayHardware& hw(graphicPlane(0).displayHardware()); const int32_t fbWidth = hw.getWidth(); @@ -298,7 +299,8 @@ void LayerBase::drawRegion(const Region& reg) const const GLshort vertices[][2] = { { 0, 0 }, { fbWidth, 0 }, { fbWidth, fbHeight }, { 0, fbHeight } }; glVertexPointer(2, GL_SHORT, 0, vertices); - while (iterator.iterate(&r)) { + while (it != end) { + const Rect& r = *it++; const GLint sy = fbHeight - (r.top + r.height()); glScissor(r.left, sy, r.width(), r.height()); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); @@ -363,12 +365,14 @@ void LayerBase::clearWithOpenGL(const Region& clip) const glDisable(GL_TEXTURE_2D); glDisable(GL_BLEND); glDisable(GL_DITHER); - Rect r; - Region::iterator iterator(clip); - if (iterator) { + + Region::const_iterator it = clip.begin(); + Region::const_iterator const end = clip.end(); + if (it != end) { glEnable(GL_SCISSOR_TEST); glVertexPointer(2, GL_FIXED, 0, mVertices); - while (iterator.iterate(&r)) { + while (it != end) { + const Rect& r = *it++; const GLint sy = fbHeight - (r.top + r.height()); glScissor(r.left, sy, r.width(), r.height()); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); @@ -434,8 +438,9 @@ void LayerBase::drawWithOpenGL(const Region& clip, || !(mFlags & DisplayHardware::DRAW_TEXTURE_EXTENSION) )) { //StopWatch watch("GL transformed"); - Region::iterator iterator(clip); - if (iterator) { + Region::const_iterator it = clip.begin(); + Region::const_iterator const end = clip.end(); + if (it != end) { // always use high-quality filtering with fast configurations bool fast = !(mFlags & DisplayHardware::SLOW_CONFIG); if (!fast && s.flags & ISurfaceComposer::eLayerFilter) { @@ -474,8 +479,8 @@ void LayerBase::drawWithOpenGL(const Region& clip, glVertexPointer(2, GL_FIXED, 0, mVertices); glTexCoordPointer(2, GL_FIXED, 0, texCoords); - Rect r; - while (iterator.iterate(&r)) { + while (it != end) { + const Rect& r = *it++; const GLint sy = fbHeight - (r.top + r.height()); glScissor(r.left, sy, r.width(), r.height()); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); @@ -488,15 +493,16 @@ void LayerBase::drawWithOpenGL(const Region& clip, glDisableClientState(GL_TEXTURE_COORD_ARRAY); } } else { - Region::iterator iterator(clip); - if (iterator) { - Rect r; + Region::const_iterator it = clip.begin(); + Region::const_iterator const end = clip.end(); + if (it != end) { GLint crop[4] = { 0, height, width, -height }; glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop); int x = tx(); int y = ty(); y = fbHeight - (y + height); - while (iterator.iterate(&r)) { + while (it != end) { + const Rect& r = *it++; const GLint sy = fbHeight - (r.top + r.height()); glScissor(r.left, sy, r.width(), r.height()); glDrawTexiOES(x, y, 0, width, height); diff --git a/libs/surfaceflinger/LayerBlur.cpp b/libs/surfaceflinger/LayerBlur.cpp index cac3cf10f0dfd..3d22e3ab278f0 100644 --- a/libs/surfaceflinger/LayerBlur.cpp +++ b/libs/surfaceflinger/LayerBlur.cpp @@ -136,8 +136,9 @@ void LayerBlur::onDraw(const Region& clip) const glGenTextures(1, &mTextureName); } - Region::iterator iterator(clip); - if (iterator) { + Region::const_iterator it = clip.begin(); + Region::const_iterator const end = clip.end(); + if (it != end) { glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, mTextureName); @@ -198,27 +199,25 @@ void LayerBlur::onDraw(const Region& clip) const glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(2, GL_FIXED, 0, mVertices); glTexCoordPointer(2, GL_FIXED, 0, mVertices); - Rect r; - while (iterator.iterate(&r)) { + while (it != end) { + const Rect& r = *it++; const GLint sy = fbHeight - (r.top + r.height()); glScissor(r.left, sy, r.width(), r.height()); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } } else { - Region::iterator iterator(clip); - if (iterator) { - // NOTE: this is marginally faster with the software gl, because - // glReadPixels() reads the fb bottom-to-top, however we'll - // skip all the jaccobian computations. - Rect r; - GLint crop[4] = { 0, 0, w, h }; - glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop); - y = fbHeight - (y + h); - while (iterator.iterate(&r)) { - const GLint sy = fbHeight - (r.top + r.height()); - glScissor(r.left, sy, r.width(), r.height()); - glDrawTexiOES(x, y, 0, w, h); - } + // NOTE: this is marginally faster with the software gl, because + // glReadPixels() reads the fb bottom-to-top, however we'll + // skip all the jaccobian computations. + Rect r; + GLint crop[4] = { 0, 0, w, h }; + glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop); + y = fbHeight - (y + h); + while (it != end) { + const Rect& r = *it++; + const GLint sy = fbHeight - (r.top + r.height()); + glScissor(r.left, sy, r.width(), r.height()); + glDrawTexiOES(x, y, 0, w, h); } } } diff --git a/libs/surfaceflinger/LayerDim.cpp b/libs/surfaceflinger/LayerDim.cpp index f2519c4e02801..c1e8ad63cdf94 100644 --- a/libs/surfaceflinger/LayerDim.cpp +++ b/libs/surfaceflinger/LayerDim.cpp @@ -52,8 +52,9 @@ void LayerDim::onDraw(const Region& clip) const // FIXME: on some h/w (like msm7K, it will be faster to use a texture) const State& s(drawingState()); - Region::iterator iterator(clip); - if (s.alpha>0 && iterator) { + Region::const_iterator it = clip.begin(); + Region::const_iterator const end = clip.end(); + if (s.alpha>0 && (it != end)) { const DisplayHardware& hw(graphicPlane(0).displayHardware()); const GGLfixed alpha = (s.alpha << 16)/255; const uint32_t fbHeight = hw.getHeight(); @@ -63,8 +64,8 @@ void LayerDim::onDraw(const Region& clip) const glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glColor4x(0, 0, 0, alpha); glVertexPointer(2, GL_FIXED, 0, mVertices); - Rect r; - while (iterator.iterate(&r)) { + while (it != end) { + const Rect& r = *it++; const GLint sy = fbHeight - (r.top + r.height()); glScissor(r.left, sy, r.width(), r.height()); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp index b8c246cb92e71..e0728ebda3353 100644 --- a/libs/surfaceflinger/SurfaceFlinger.cpp +++ b/libs/surfaceflinger/SurfaceFlinger.cpp @@ -913,9 +913,10 @@ void SurfaceFlinger::debugFlashRegions() glColor4x(0x10000, 0x10000, 0, 0x10000); } - Rect r; - Region::iterator iterator(mDirtyRegion); - while (iterator.iterate(&r)) { + Region::const_iterator it = mDirtyRegion.begin(); + Region::const_iterator const end = mDirtyRegion.end(); + while (it != end) { + const Rect& r = *it++; GLfloat vertices[][2] = { { r.left, r.top }, { r.left, r.bottom }, @@ -951,9 +952,10 @@ void SurfaceFlinger::drawWormhole() const if (LIKELY(!mDebugBackground)) { glClearColorx(0,0,0,0); - Rect r; - Region::iterator iterator(region); - while (iterator.iterate(&r)) { + Region::const_iterator it = region.begin(); + Region::const_iterator const end = region.end(); + while (it != end) { + const Rect& r = *it++; const GLint sy = height - (r.top + r.height()); glScissor(r.left, sy, r.width(), r.height()); glClear(GL_COLOR_BUFFER_BIT); @@ -971,9 +973,10 @@ void SurfaceFlinger::drawWormhole() const glMatrixMode(GL_TEXTURE); glLoadIdentity(); glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1); - Rect r; - Region::iterator iterator(region); - while (iterator.iterate(&r)) { + Region::const_iterator it = region.begin(); + Region::const_iterator const end = region.end(); + while (it != end) { + const Rect& r = *it++; const GLint sy = height - (r.top + r.height()); glScissor(r.left, sy, r.width(), r.height()); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); diff --git a/libs/surfaceflinger/Transform.cpp b/libs/surfaceflinger/Transform.cpp index e8b0f45f811b2..1501536f29032 100644 --- a/libs/surfaceflinger/Transform.cpp +++ b/libs/surfaceflinger/Transform.cpp @@ -177,10 +177,10 @@ Region Transform::transform(const Region& reg) const Region out; if (UNLIKELY(transformed())) { if (LIKELY(preserveRects())) { - Rect r; - Region::iterator iterator(reg); - while (iterator.iterate(&r)) { - out.orSelf(transform(r)); + Region::const_iterator it = reg.begin(); + Region::const_iterator const end = reg.end(); + while (it != end) { + out.orSelf(transform(*it++)); } } else { out.set(transform(reg.bounds())); diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk index d44d2f965be41..7c367efc61198 100644 --- a/libs/ui/Android.mk +++ b/libs/ui/Android.mk @@ -29,7 +29,6 @@ LOCAL_SRC_FILES:= \ Time.cpp LOCAL_SHARED_LIBRARIES := \ - libcorecg \ libcutils \ libutils \ libpixelflinger \ diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp index 30da911fc72cd..065ed5499f25b 100644 --- a/libs/ui/Region.cpp +++ b/libs/ui/Region.cpp @@ -16,302 +16,653 @@ #define LOG_TAG "Region" -#include -#include -#include +#include #include + +#include #include +#include + +#include + +// ---------------------------------------------------------------------------- +#define VALIDATE_REGIONS (false) +#define VALIDATE_WITH_CORECG (false) +// ---------------------------------------------------------------------------- + +#if VALIDATE_WITH_CORECG +#include +#endif namespace android { +// ---------------------------------------------------------------------------- + +enum { + op_nand = region_operator::op_nand, + op_and = region_operator::op_and, + op_or = region_operator::op_or, + op_xor = region_operator::op_xor +}; // ---------------------------------------------------------------------------- Region::Region() + : mBounds(0,0) { } Region::Region(const Region& rhs) - : mRegion(rhs.mRegion) + : mBounds(rhs.mBounds), mStorage(rhs.mStorage) { } -Region::Region(const SkRegion& rhs) - : mRegion(rhs) +Region::Region(const Rect& rhs) + : mBounds(rhs) { } +Region::Region(const Parcel& parcel) +{ + status_t err = read(parcel); + LOGE_IF(err<0, "error %s reading Region from parcel", strerror(err)); +} + +Region::Region(const void* buffer) +{ + status_t err = read(buffer); + LOGE_IF(err<0, "error %s reading Region from parcel", strerror(err)); +} + Region::~Region() { } -Region::Region(const Rect& rhs) -{ - set(rhs); -} - -Region::Region(const Parcel& parcel) -{ - read(parcel); -} - -Region::Region(const void* buffer) -{ - read(buffer); -} - Region& Region::operator = (const Region& rhs) { - mRegion = rhs.mRegion; +#if VALIDATE_REGIONS + validate(rhs, "operator="); +#endif + mBounds = rhs.mBounds; + mStorage = rhs.mStorage; return *this; } -const SkRegion& Region::toSkRegion() const -{ - return mRegion; -} - -Rect Region::bounds() const -{ - const SkIRect& b(mRegion.getBounds()); - return Rect(b.fLeft, b.fTop, b.fRight, b.fBottom); -} - void Region::clear() { - mRegion.setEmpty(); + mBounds.clear(); + mStorage.clear(); } void Region::set(const Rect& r) { - SkIRect ir; - ir.set(r.left, r.top, r.right, r.bottom); - mRegion.setRect(ir); + mBounds = r; + mStorage.clear(); } void Region::set(uint32_t w, uint32_t h) { - SkIRect ir; - ir.set(0, 0, w, h); - mRegion.setRect(ir); + mBounds = Rect(int(w), int(h)); + mStorage.clear(); } // ---------------------------------------------------------------------------- -Region& Region::orSelf(const Rect& r) +void Region::addRectUnchecked(int l, int t, int r, int b) { - SkIRect ir; - ir.set(r.left, r.top, r.right, r.bottom); - mRegion.op(ir, SkRegion::kUnion_Op); - return *this; + mStorage.add(Rect(l,t,r,b)); +#if VALIDATE_REGIONS + validate(*this, "addRectUnchecked"); +#endif } -Region& Region::andSelf(const Rect& r) -{ - SkIRect ir; - ir.set(r.left, r.top, r.right, r.bottom); - mRegion.op(ir, SkRegion::kIntersect_Op); +// ---------------------------------------------------------------------------- + +Region& Region::orSelf(const Rect& r) { + return operationSelf(r, op_or); +} +Region& Region::andSelf(const Rect& r) { + return operationSelf(r, op_and); +} +Region& Region::subtractSelf(const Rect& r) { + return operationSelf(r, op_nand); +} +Region& Region::operationSelf(const Rect& r, int op) { + Region lhs(*this); + boolean_operation(op, *this, lhs, r); return *this; } // ---------------------------------------------------------------------------- Region& Region::orSelf(const Region& rhs) { - mRegion.op(rhs.mRegion, SkRegion::kUnion_Op); - return *this; + return operationSelf(rhs, op_or); } - Region& Region::andSelf(const Region& rhs) { - mRegion.op(rhs.mRegion, SkRegion::kIntersect_Op); - return *this; + return operationSelf(rhs, op_and); } - Region& Region::subtractSelf(const Region& rhs) { - mRegion.op(rhs.mRegion, SkRegion::kDifference_Op); + return operationSelf(rhs, op_nand); +} +Region& Region::operationSelf(const Region& rhs, int op) { + Region lhs(*this); + boolean_operation(op, *this, lhs, rhs); return *this; } Region& Region::translateSelf(int x, int y) { - if (x|y) mRegion.translate(x, y); + if (x|y) translate(*this, x, y); return *this; } +// ---------------------------------------------------------------------------- + +Region Region::merge(const Rect& rhs) const { + return operation(rhs, op_or); +} +Region Region::intersect(const Rect& rhs) const { + return operation(rhs, op_and); +} +Region Region::subtract(const Rect& rhs) const { + return operation(rhs, op_nand); +} +Region Region::operation(const Rect& rhs, int op) const { + Region result; + boolean_operation(op, result, *this, rhs); + return result; +} + +// ---------------------------------------------------------------------------- + Region Region::merge(const Region& rhs) const { - Region result; - result.mRegion.op(mRegion, rhs.mRegion, SkRegion::kUnion_Op); - return result; + return operation(rhs, op_or); } - Region Region::intersect(const Region& rhs) const { - Region result; - result.mRegion.op(mRegion, rhs.mRegion, SkRegion::kIntersect_Op); - return result; + return operation(rhs, op_and); } - Region Region::subtract(const Region& rhs) const { + return operation(rhs, op_nand); +} +Region Region::operation(const Region& rhs, int op) const { Region result; - result.mRegion.op(mRegion, rhs.mRegion, SkRegion::kDifference_Op); + boolean_operation(op, result, *this, rhs); return result; } Region Region::translate(int x, int y) const { Region result; - mRegion.translate(x, y, &result.mRegion); + translate(result, *this, x, y); return result; } // ---------------------------------------------------------------------------- Region& Region::orSelf(const Region& rhs, int dx, int dy) { - SkRegion r(rhs.mRegion); - r.translate(dx, dy); - mRegion.op(r, SkRegion::kUnion_Op); - return *this; + return operationSelf(rhs, dx, dy, op_or); } - Region& Region::andSelf(const Region& rhs, int dx, int dy) { - SkRegion r(rhs.mRegion); - r.translate(dx, dy); - mRegion.op(r, SkRegion::kIntersect_Op); + return operationSelf(rhs, dx, dy, op_and); +} +Region& Region::subtractSelf(const Region& rhs, int dx, int dy) { + return operationSelf(rhs, dx, dy, op_nand); +} +Region& Region::operationSelf(const Region& rhs, int dx, int dy, int op) { + Region lhs(*this); + boolean_operation(op, *this, lhs, rhs, dx, dy); return *this; } -Region& Region::subtractSelf(const Region& rhs, int dx, int dy) { - SkRegion r(rhs.mRegion); - r.translate(dx, dy); - mRegion.op(r, SkRegion::kDifference_Op); - return *this; -} +// ---------------------------------------------------------------------------- Region Region::merge(const Region& rhs, int dx, int dy) const { - Region result; - SkRegion r(rhs.mRegion); - r.translate(dx, dy); - result.mRegion.op(mRegion, r, SkRegion::kUnion_Op); - return result; + return operation(rhs, dx, dy, op_or); } - Region Region::intersect(const Region& rhs, int dx, int dy) const { - Region result; - SkRegion r(rhs.mRegion); - r.translate(dx, dy); - result.mRegion.op(mRegion, r, SkRegion::kIntersect_Op); - return result; + return operation(rhs, dx, dy, op_and); } - Region Region::subtract(const Region& rhs, int dx, int dy) const { + return operation(rhs, dx, dy, op_nand); +} +Region Region::operation(const Region& rhs, int dx, int dy, int op) const { Region result; - SkRegion r(rhs.mRegion); - r.translate(dx, dy); - result.mRegion.op(mRegion, r, SkRegion::kDifference_Op); + boolean_operation(op, result, *this, rhs, dx, dy); return result; } // ---------------------------------------------------------------------------- -Region::iterator::iterator(const Region& r) - : mIt(r.mRegion) +// This is our region rasterizer, which merges rects and spans together +// to obtain an optimal region. +class Region::rasterizer : public region_operator::region_rasterizer { + Rect& bounds; + Vector& storage; + Rect* head; + Rect* tail; + Vector span; + Rect* cur; +public: + rasterizer(Region& reg) + : bounds(reg.mBounds), storage(reg.mStorage), head(), tail(), cur() { + bounds.top = bounds.bottom = 0; + bounds.left = INT_MAX; + bounds.right = INT_MIN; + storage.clear(); + } + + ~rasterizer() { + if (span.size()) { + flushSpan(); + } + if (storage.size()) { + bounds.top = storage.itemAt(0).top; + bounds.bottom = storage.top().bottom; + if (storage.size() == 1) { + storage.clear(); + } + } else { + bounds.left = 0; + bounds.right = 0; + } + } + + virtual void operator()(const Rect& rect) { + //LOGD(">>> %3d, %3d, %3d, %3d", + // rect.left, rect.top, rect.right, rect.bottom); + if (span.size()) { + if (cur->top != rect.top) { + flushSpan(); + } else if (cur->right == rect.left) { + cur->right = rect.right; + return; + } + } + span.add(rect); + cur = span.editArray() + (span.size() - 1); + } +private: + template + static inline T min(T rhs, T lhs) { return rhs < lhs ? rhs : lhs; } + template + static inline T max(T rhs, T lhs) { return rhs > lhs ? rhs : lhs; } + void flushSpan() { + bool merge = false; + if (tail-head == ssize_t(span.size())) { + Rect const* p = cur; + Rect const* q = head; + if (p->top == q->bottom) { + merge = true; + while (q != tail) { + if ((p->left != q->left) || (p->right != q->right)) { + merge = false; + break; + } + p++, q++; + } + } + } + if (merge) { + const int bottom = span[0].bottom; + Rect* r = head; + while (r != tail) { + r->bottom = bottom; + r++; + } + } else { + bounds.left = min(span.itemAt(0).left, bounds.left); + bounds.right = max(span.top().right, bounds.right); + storage.appendVector(span); + tail = storage.editArray() + storage.size(); + head = tail - span.size(); + } + span.clear(); + } +}; + +bool Region::validate(const Region& reg, const char* name) +{ + bool result = true; + const_iterator cur = reg.begin(); + const_iterator const tail = reg.end(); + const_iterator prev = cur++; + Rect b(*prev); + while (cur != tail) { + b.left = b.left < cur->left ? b.left : cur->left; + b.top = b.top < cur->top ? b.top : cur->top; + b.right = b.right > cur->right ? b.right : cur->right; + b.bottom = b.bottom > cur->bottom ? b.bottom : cur->bottom; + if (cur->top == prev->top) { + if (cur->bottom != prev->bottom) { + LOGE("%s: invalid span %p", name, cur); + result = false; + } else if (cur->left < prev->right) { + LOGE("%s: spans overlap horizontally prev=%p, cur=%p", + name, prev, cur); + result = false; + } + } else if (cur->top < prev->bottom) { + LOGE("%s: spans overlap vertically prev=%p, cur=%p", + name, prev, cur); + result = false; + } + prev = cur; + cur++; + } + if (b != reg.getBounds()) { + result = false; + LOGE("%s: invalid bounds [%d,%d,%d,%d] vs. [%d,%d,%d,%d]", name, + b.left, b.top, b.right, b.bottom, + reg.getBounds().left, reg.getBounds().top, + reg.getBounds().right, reg.getBounds().bottom); + } + if (result == false) { + reg.dump(name); + } + return result; } -int Region::iterator::iterate(Rect* rect) +void Region::boolean_operation(int op, Region& dst, + const Region& lhs, + const Region& rhs, int dx, int dy) { - if (mIt.done()) - return 0; - const SkIRect& r(mIt.rect()); - rect->left = r.fLeft; - rect->top = r.fTop; - rect->right = r.fRight; - rect->bottom= r.fBottom; - mIt.next(); - return 1; + size_t lhs_count; + Rect const * const lhs_rects = lhs.getArray(&lhs_count); + + size_t rhs_count; + Rect const * const rhs_rects = rhs.getArray(&rhs_count); + + region_operator::region lhs_region(lhs_rects, lhs_count); + region_operator::region rhs_region(rhs_rects, rhs_count, dx, dy); + region_operator operation(op, lhs_region, rhs_region); + { // scope for rasterizer (dtor has side effects) + rasterizer r(dst); + operation(r); + } + +#if VALIDATE_REGIONS + validate(lhs, "boolean_operation: lhs"); + validate(rhs, "boolean_operation: rhs"); + validate(dst, "boolean_operation: dst"); +#endif + +#if VALIDATE_WITH_CORECG + SkRegion sk_lhs; + SkRegion sk_rhs; + SkRegion sk_dst; + + for (size_t i=0 ; ileft != it.rect().fLeft || + head->top != it.rect().fTop || + head->right != it.rect().fRight || + head->bottom != it.rect().fBottom + ) { + same = false; + break; + } + } else { + same = false; + break; + } + head++; + it.next(); + } + + if (head != tail) { + same = false; + } + + if(!same) { + LOGD("---\nregion boolean %s failed", name); + lhs.dump("lhs"); + rhs.dump("rhs"); + dst.dump("dst"); + LOGD("should be"); + SkRegion::Iterator it(sk_dst); + while (!it.done()) { + LOGD(" [%3d, %3d, %3d, %3d]", + it.rect().fLeft, + it.rect().fTop, + it.rect().fRight, + it.rect().fBottom); + it.next(); + } + } +#endif +} + +void Region::boolean_operation(int op, Region& dst, + const Region& lhs, + const Rect& rhs, int dx, int dy) +{ +#if VALIDATE_WITH_CORECG || VALIDATE_REGIONS + boolean_operation(op, dst, lhs, Region(rhs), dx, dy); +#else + size_t lhs_count; + Rect const * const lhs_rects = lhs.getArray(&lhs_count); + + region_operator::region lhs_region(lhs_rects, lhs_count); + region_operator::region rhs_region(&rhs, 1, dx, dy); + region_operator operation(op, lhs_region, rhs_region); + { // scope for rasterizer (dtor has side effects) + rasterizer r(dst); + operation(r); + } + +#endif +} + +void Region::boolean_operation(int op, Region& dst, + const Region& lhs, const Region& rhs) +{ + boolean_operation(op, dst, lhs, rhs, 0, 0); +} + +void Region::boolean_operation(int op, Region& dst, + const Region& lhs, const Rect& rhs) +{ + boolean_operation(op, dst, lhs, rhs, 0, 0); +} + +void Region::translate(Region& reg, int dx, int dy) +{ + if (!reg.isEmpty()) { +#if VALIDATE_REGIONS + validate(reg, "translate (before)"); +#endif + reg.mBounds.translate(dx, dy); + size_t count = reg.mStorage.size(); + Rect* rects = reg.mStorage.editArray(); + while (count) { + rects->translate(dx, dy); + rects++; + count--; + } +#if VALIDATE_REGIONS + validate(reg, "translate (after)"); +#endif + } +} + +void Region::translate(Region& dst, const Region& reg, int dx, int dy) +{ + dst = reg; + translate(dst, dx, dy); } // ---------------------------------------------------------------------------- -// we write a 4byte size ahead of the actual region, so we know how much we'll need for reading - status_t Region::write(Parcel& parcel) const { - int32_t size = mRegion.flatten(NULL); - parcel.writeInt32(size); - mRegion.flatten(parcel.writeInplace(size)); +#if VALIDATE_REGIONS + validate(*this, "write(Parcel)"); +#endif + status_t err; + const size_t count = mStorage.size(); + const size_t sizeNeeded = sizeof(int32_t) + (1+count)*sizeof(Rect); + void* buffer = parcel.writeInplace(sizeNeeded); + if (!buffer) return NO_MEMORY; + ssize_t written = Region::write(buffer, sizeNeeded); + if (written < 0) return status_t(written); return NO_ERROR; } status_t Region::read(const Parcel& parcel) { - size_t size = parcel.readInt32(); - mRegion.unflatten(parcel.readInplace(size)); + void const* buffer = parcel.readInplace(sizeof(int32_t)); + if (!buffer) return NO_MEMORY; + const size_t count = *static_cast(buffer); + void const* dummy = parcel.readInplace((1+count)*sizeof(Rect)); + if (!dummy) return NO_MEMORY; + const size_t sizeNeeded = sizeof(int32_t) + (1+count)*sizeof(Rect); + const ssize_t read = Region::read(buffer); + if (read < 0) return status_t(read); +#if VALIDATE_REGIONS + validate(*this, "read(Parcel)"); +#endif return NO_ERROR; } ssize_t Region::write(void* buffer, size_t size) const { - size_t sizeNeeded = mRegion.flatten(NULL); +#if VALIDATE_REGIONS + validate(*this, "write(buffer)"); +#endif + const size_t count = mStorage.size(); + const size_t sizeNeeded = sizeof(int32_t) + (1+count)*sizeof(Rect); if (sizeNeeded > size) return NO_MEMORY; - return mRegion.flatten(buffer); + int32_t* const p = static_cast(buffer); + *p = count; + memcpy(p+1, &mBounds, sizeof(Rect)); + if (count) { + memcpy(p+5, mStorage.array(), count*sizeof(Rect)); + } + return ssize_t(sizeNeeded); } ssize_t Region::read(const void* buffer) { - return mRegion.unflatten(buffer); + int32_t const* const p = static_cast(buffer); + const size_t count = *p; + memcpy(&mBounds, p+1, sizeof(Rect)); + mStorage.clear(); + if (count) { + mStorage.insertAt(0, count); + memcpy(mStorage.editArray(), p+5, count*sizeof(Rect)); + } +#if VALIDATE_REGIONS + validate(*this, "read(buffer)"); +#endif + return ssize_t(sizeof(int32_t) + (1+count)*sizeof(Rect)); } ssize_t Region::writeEmpty(void* buffer, size_t size) { - if (size < 4) return NO_MEMORY; - // this needs to stay in sync with SkRegion - *static_cast(buffer) = -1; - return 4; + const size_t sizeNeeded = sizeof(int32_t) + sizeof(Rect); + if (sizeNeeded > size) return NO_MEMORY; + int32_t* const p = static_cast(buffer); + memset(p, 0, sizeNeeded); + return ssize_t(sizeNeeded); } bool Region::isEmpty(void* buffer) { - // this needs to stay in sync with SkRegion - return *static_cast(buffer) == -1; + int32_t const* const p = static_cast(buffer); + Rect const* const b = reinterpret_cast(p+1); + return b->isEmpty(); } -size_t Region::rects(Vector& rectList) const +// ---------------------------------------------------------------------------- + +Region::const_iterator Region::begin() const { + return isRect() ? &mBounds : mStorage.array(); +} + +Region::const_iterator Region::end() const { + return isRect() ? ((&mBounds) + 1) : (mStorage.array() + mStorage.size()); +} + +Rect const* Region::getArray(size_t* count) const { + const_iterator const b(begin()); + const_iterator const e(end()); + if (count) *count = e-b; + return b; +} + +size_t Region::getRects(Vector& rectList) const { - rectList.clear(); - if (!isEmpty()) { - SkRegion::Iterator iterator(mRegion); - while( !iterator.done() ) { - const SkIRect& ir(iterator.rect()); - rectList.push(Rect(ir.fLeft, ir.fTop, ir.fRight, ir.fBottom)); - iterator.next(); - } + rectList = mStorage; + if (rectList.isEmpty()) { + rectList.clear(); + rectList.add(mBounds); } return rectList.size(); } +// ---------------------------------------------------------------------------- + void Region::dump(String8& out, const char* what, uint32_t flags) const { (void)flags; - Vector r; - rects(r); - + const_iterator head = begin(); + const_iterator const tail = end(); + size_t SIZE = 256; char buffer[SIZE]; - - snprintf(buffer, SIZE, " Region %s (this=%p, count=%d)\n", what, this, r.size()); + + snprintf(buffer, SIZE, " Region %s (this=%p, count=%d)\n", + what, this, tail-head); out.append(buffer); - for (size_t i=0 ; ileft, head->top, head->right, head->bottom); out.append(buffer); + head++; } } void Region::dump(const char* what, uint32_t flags) const { (void)flags; - Vector r; - rects(r); - LOGD(" Region %s (this=%p, count=%d)\n", what, this, r.size()); - for (size_t i=0 ; ileft, head->top, head->right, head->bottom); + head++; } } diff --git a/libs/ui/Surface.cpp b/libs/ui/Surface.cpp index 6437619b20e26..6db30c3a2efc1 100644 --- a/libs/ui/Surface.cpp +++ b/libs/ui/Surface.cpp @@ -125,15 +125,17 @@ static void copyBlt( uint8_t* dst_bits; dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(), (void**)&dst_bits); - Region::iterator iterator(reg); - if (iterator) { + size_t c; + Rect const* const rects = reg.getArray(&c); + + if (c) { // NOTE: dst and src must be the same format - Rect r; const size_t bpp = bytesPerPixel(src->format); const size_t dbpr = dst->stride * bpp; const size_t sbpr = src->stride * bpp; - while (iterator.iterate(&r)) { + for (size_t i=0 ; i +#include +#include +#include + +using namespace android; + +int main() +{ + Region reg0( Rect( 0, 0, 100, 100 ) ); + Region reg1 = reg0; + Region reg2, reg3; + + reg0.dump("reg0"); + reg1.dump("reg1"); + + reg0 = reg0 | reg0.translate(150, 0); + reg0.dump("reg0"); + reg1.dump("reg1"); + + reg0 = reg0 | reg0.translate(300, 0); + reg0.dump("reg0"); + reg1.dump("reg1"); + + //reg2 = reg0 | reg0.translate(0, 100); + //reg0.dump("reg0"); + //reg1.dump("reg1"); + //reg2.dump("reg2"); + + //reg3 = reg0 | reg0.translate(0, 150); + //reg0.dump("reg0"); + //reg1.dump("reg1"); + //reg2.dump("reg2"); + //reg3.dump("reg3"); + + LOGD("---"); + reg2 = reg0 | reg0.translate(100, 0); + reg0.dump("reg0"); + reg1.dump("reg1"); + reg2.dump("reg2"); + + return 0; +} + From 8fe8a18160571621d0ce24c74b9ff943f8ad4ca3 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Wed, 27 May 2009 15:02:35 -0700 Subject: [PATCH 32/83] oops forgot these changes in the previous merge. fixes build --- include/ui/Rect.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/include/ui/Rect.h b/include/ui/Rect.h index da72944762464..a213c0930967d 100644 --- a/include/ui/Rect.h +++ b/include/ui/Rect.h @@ -30,6 +30,8 @@ public: int right; int bottom; + typedef int value_type; + // we don't provide copy-ctor and operator= on purpose // because we want the compiler generated versions @@ -46,7 +48,11 @@ public: } void makeInvalid(); - + + inline void clear() { + left = top = right = bottom = 0; + } + // a valid rectangle has a non negative width and height inline bool isValid() const { return (width()>=0) && (height()>=0); From 12c659a50ca1407a40f9f7dbf0dc8c174c7d3493 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Wed, 27 May 2009 17:01:58 -0700 Subject: [PATCH 33/83] make sure the Region code disallows constructs like "(a+b)=c;", which is somewhat meaningless. --- include/ui/Region.h | 42 +++++++++++++++++++++--------------------- libs/ui/Region.cpp | 26 +++++++++++++------------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/include/ui/Region.h b/include/ui/Region.h index e36dcb40c47ba..4299ea5a97872 100644 --- a/include/ui/Region.h +++ b/include/ui/Region.h @@ -65,14 +65,14 @@ public: Region& subtractSelf(const Region& rhs); // boolean operators - Region merge(const Rect& rhs) const; - Region intersect(const Rect& rhs) const; - Region subtract(const Rect& rhs) const; + const Region merge(const Rect& rhs) const; + const Region intersect(const Rect& rhs) const; + const Region subtract(const Rect& rhs) const; // boolean operators - Region merge(const Region& rhs) const; - Region intersect(const Region& rhs) const; - Region subtract(const Region& rhs) const; + const Region merge(const Region& rhs) const; + const Region intersect(const Region& rhs) const; + const Region subtract(const Region& rhs) const; // these translate rhs first Region& translateSelf(int dx, int dy); @@ -81,16 +81,16 @@ public: Region& subtractSelf(const Region& rhs, int dx, int dy); // these translate rhs first - Region translate(int dx, int dy) const; - Region merge(const Region& rhs, int dx, int dy) const; - Region intersect(const Region& rhs, int dx, int dy) const; - Region subtract(const Region& rhs, int dx, int dy) const; + const Region translate(int dx, int dy) const; + const Region merge(const Region& rhs, int dx, int dy) const; + const Region intersect(const Region& rhs, int dx, int dy) const; + const Region subtract(const Region& rhs, int dx, int dy) const; // convenience operators overloads - inline Region operator | (const Region& rhs) const; - inline Region operator & (const Region& rhs) const; - inline Region operator - (const Region& rhs) const; - inline Region operator + (const Point& pt) const; + inline const Region operator | (const Region& rhs) const; + inline const Region operator & (const Region& rhs) const; + inline const Region operator - (const Region& rhs) const; + inline const Region operator + (const Point& pt) const; inline Region& operator |= (const Region& rhs); inline Region& operator &= (const Region& rhs); @@ -136,9 +136,9 @@ private: Region& operationSelf(const Rect& r, int op); Region& operationSelf(const Region& r, int op); Region& operationSelf(const Region& r, int dx, int dy, int op); - Region operation(const Rect& rhs, int op) const; - Region operation(const Region& rhs, int op) const; - Region operation(const Region& rhs, int dx, int dy, int op) const; + const Region operation(const Rect& rhs, int op) const; + const Region operation(const Region& rhs, int op) const; + const Region operation(const Region& rhs, int dx, int dy, int op) const; static void boolean_operation(int op, Region& dst, const Region& lhs, const Region& rhs, int dx, int dy); @@ -160,16 +160,16 @@ private: }; -Region Region::operator | (const Region& rhs) const { +const Region Region::operator | (const Region& rhs) const { return merge(rhs); } -Region Region::operator & (const Region& rhs) const { +const Region Region::operator & (const Region& rhs) const { return intersect(rhs); } -Region Region::operator - (const Region& rhs) const { +const Region Region::operator - (const Region& rhs) const { return subtract(rhs); } -Region Region::operator + (const Point& pt) const { +const Region Region::operator + (const Point& pt) const { return translate(pt.x, pt.y); } diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp index 065ed5499f25b..2e6b241a310dd 100644 --- a/libs/ui/Region.cpp +++ b/libs/ui/Region.cpp @@ -156,16 +156,16 @@ Region& Region::translateSelf(int x, int y) { // ---------------------------------------------------------------------------- -Region Region::merge(const Rect& rhs) const { +const Region Region::merge(const Rect& rhs) const { return operation(rhs, op_or); } -Region Region::intersect(const Rect& rhs) const { +const Region Region::intersect(const Rect& rhs) const { return operation(rhs, op_and); } -Region Region::subtract(const Rect& rhs) const { +const Region Region::subtract(const Rect& rhs) const { return operation(rhs, op_nand); } -Region Region::operation(const Rect& rhs, int op) const { +const Region Region::operation(const Rect& rhs, int op) const { Region result; boolean_operation(op, result, *this, rhs); return result; @@ -173,22 +173,22 @@ Region Region::operation(const Rect& rhs, int op) const { // ---------------------------------------------------------------------------- -Region Region::merge(const Region& rhs) const { +const Region Region::merge(const Region& rhs) const { return operation(rhs, op_or); } -Region Region::intersect(const Region& rhs) const { +const Region Region::intersect(const Region& rhs) const { return operation(rhs, op_and); } -Region Region::subtract(const Region& rhs) const { +const Region Region::subtract(const Region& rhs) const { return operation(rhs, op_nand); } -Region Region::operation(const Region& rhs, int op) const { +const Region Region::operation(const Region& rhs, int op) const { Region result; boolean_operation(op, result, *this, rhs); return result; } -Region Region::translate(int x, int y) const { +const Region Region::translate(int x, int y) const { Region result; translate(result, *this, x, y); return result; @@ -213,16 +213,16 @@ Region& Region::operationSelf(const Region& rhs, int dx, int dy, int op) { // ---------------------------------------------------------------------------- -Region Region::merge(const Region& rhs, int dx, int dy) const { +const Region Region::merge(const Region& rhs, int dx, int dy) const { return operation(rhs, dx, dy, op_or); } -Region Region::intersect(const Region& rhs, int dx, int dy) const { +const Region Region::intersect(const Region& rhs, int dx, int dy) const { return operation(rhs, dx, dy, op_and); } -Region Region::subtract(const Region& rhs, int dx, int dy) const { +const Region Region::subtract(const Region& rhs, int dx, int dy) const { return operation(rhs, dx, dy, op_nand); } -Region Region::operation(const Region& rhs, int dx, int dy, int op) const { +const Region Region::operation(const Region& rhs, int dx, int dy, int op) const { Region result; boolean_operation(op, result, *this, rhs, dx, dy); return result; From d53c8ee26b9e6703633033ea51f4f7c21b253dd1 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Wed, 27 May 2009 20:31:18 -0700 Subject: [PATCH 34/83] add GLES 2.x headers --- opengl/include/GLES2/gl2.h | 620 ++++++++++++++++++++++++++++++++++ opengl/include/GLES2/gl2ext.h | 518 ++++++++++++++++++++++++++++ 2 files changed, 1138 insertions(+) create mode 100644 opengl/include/GLES2/gl2.h create mode 100644 opengl/include/GLES2/gl2ext.h diff --git a/opengl/include/GLES2/gl2.h b/opengl/include/GLES2/gl2.h new file mode 100644 index 0000000000000..83090741b00a5 --- /dev/null +++ b/opengl/include/GLES2/gl2.h @@ -0,0 +1,620 @@ +#ifndef __gl2_h_ +#define __gl2_h_ + +/* $Revision: 7173 $ on $Date:: 2009-01-09 11:18:21 -0800 #$ */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This document is licensed under the SGI Free Software B License Version + * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ . + */ + +/*------------------------------------------------------------------------- + * Data type definitions + *-----------------------------------------------------------------------*/ + +typedef void GLvoid; +typedef unsigned int GLenum; +typedef unsigned char GLboolean; +typedef unsigned int GLbitfield; +typedef khronos_int8_t GLbyte; +typedef short GLshort; +typedef int GLint; +typedef int GLsizei; +typedef khronos_uint8_t GLubyte; +typedef unsigned short GLushort; +typedef unsigned int GLuint; +typedef khronos_float_t GLfloat; +typedef khronos_float_t GLclampf; +typedef khronos_int32_t GLfixed; + +/* GL types for handling large vertex buffer objects */ +typedef khronos_intptr_t GLintptr; +typedef khronos_ssize_t GLsizeiptr; + +/* OpenGL ES core versions */ +#define GL_ES_VERSION_2_0 1 + +/* ClearBufferMask */ +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_COLOR_BUFFER_BIT 0x00004000 + +/* Boolean */ +#define GL_FALSE 0 +#define GL_TRUE 1 + +/* BeginMode */ +#define GL_POINTS 0x0000 +#define GL_LINES 0x0001 +#define GL_LINE_LOOP 0x0002 +#define GL_LINE_STRIP 0x0003 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRIANGLE_FAN 0x0006 + +/* AlphaFunction (not supported in ES20) */ +/* GL_NEVER */ +/* GL_LESS */ +/* GL_EQUAL */ +/* GL_LEQUAL */ +/* GL_GREATER */ +/* GL_NOTEQUAL */ +/* GL_GEQUAL */ +/* GL_ALWAYS */ + +/* BlendingFactorDest */ +#define GL_ZERO 0 +#define GL_ONE 1 +#define GL_SRC_COLOR 0x0300 +#define GL_ONE_MINUS_SRC_COLOR 0x0301 +#define GL_SRC_ALPHA 0x0302 +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_DST_ALPHA 0x0304 +#define GL_ONE_MINUS_DST_ALPHA 0x0305 + +/* BlendingFactorSrc */ +/* GL_ZERO */ +/* GL_ONE */ +#define GL_DST_COLOR 0x0306 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_SRC_ALPHA_SATURATE 0x0308 +/* GL_SRC_ALPHA */ +/* GL_ONE_MINUS_SRC_ALPHA */ +/* GL_DST_ALPHA */ +/* GL_ONE_MINUS_DST_ALPHA */ + +/* BlendEquationSeparate */ +#define GL_FUNC_ADD 0x8006 +#define GL_BLEND_EQUATION 0x8009 +#define GL_BLEND_EQUATION_RGB 0x8009 /* same as BLEND_EQUATION */ +#define GL_BLEND_EQUATION_ALPHA 0x883D + +/* BlendSubtract */ +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B + +/* Separate Blend Functions */ +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_BLEND_COLOR 0x8005 + +/* Buffer Objects */ +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 + +#define GL_STREAM_DRAW 0x88E0 +#define GL_STATIC_DRAW 0x88E4 +#define GL_DYNAMIC_DRAW 0x88E8 + +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 + +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 + +/* CullFaceMode */ +#define GL_FRONT 0x0404 +#define GL_BACK 0x0405 +#define GL_FRONT_AND_BACK 0x0408 + +/* DepthFunction */ +/* GL_NEVER */ +/* GL_LESS */ +/* GL_EQUAL */ +/* GL_LEQUAL */ +/* GL_GREATER */ +/* GL_NOTEQUAL */ +/* GL_GEQUAL */ +/* GL_ALWAYS */ + +/* EnableCap */ +#define GL_TEXTURE_2D 0x0DE1 +#define GL_CULL_FACE 0x0B44 +#define GL_BLEND 0x0BE2 +#define GL_DITHER 0x0BD0 +#define GL_STENCIL_TEST 0x0B90 +#define GL_DEPTH_TEST 0x0B71 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_POLYGON_OFFSET_FILL 0x8037 +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_COVERAGE 0x80A0 + +/* ErrorCode */ +#define GL_NO_ERROR 0 +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVALID_OPERATION 0x0502 +#define GL_OUT_OF_MEMORY 0x0505 + +/* FrontFaceDirection */ +#define GL_CW 0x0900 +#define GL_CCW 0x0901 + +/* GetPName */ +#define GL_LINE_WIDTH 0x0B21 +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_FRONT_FACE 0x0B46 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_FUNC 0x0B74 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_FUNC 0x0B92 +#define GL_STENCIL_FAIL 0x0B94 +#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 +#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 +#define GL_STENCIL_REF 0x0B97 +#define GL_STENCIL_VALUE_MASK 0x0B93 +#define GL_STENCIL_WRITEMASK 0x0B98 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 +#define GL_VIEWPORT 0x0BA2 +#define GL_SCISSOR_BOX 0x0C10 +/* GL_SCISSOR_TEST */ +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_RED_BITS 0x0D52 +#define GL_GREEN_BITS 0x0D53 +#define GL_BLUE_BITS 0x0D54 +#define GL_ALPHA_BITS 0x0D55 +#define GL_DEPTH_BITS 0x0D56 +#define GL_STENCIL_BITS 0x0D57 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +/* GL_POLYGON_OFFSET_FILL */ +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB + +/* GetTextureParameter */ +/* GL_TEXTURE_MAG_FILTER */ +/* GL_TEXTURE_MIN_FILTER */ +/* GL_TEXTURE_WRAP_S */ +/* GL_TEXTURE_WRAP_T */ + +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 + +/* HintMode */ +#define GL_DONT_CARE 0x1100 +#define GL_FASTEST 0x1101 +#define GL_NICEST 0x1102 + +/* HintTarget */ +#define GL_GENERATE_MIPMAP_HINT 0x8192 + +/* DataType */ +#define GL_BYTE 0x1400 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_SHORT 0x1402 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_INT 0x1404 +#define GL_UNSIGNED_INT 0x1405 +#define GL_FLOAT 0x1406 +#define GL_FIXED 0x140C + +/* PixelFormat */ +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_ALPHA 0x1906 +#define GL_RGB 0x1907 +#define GL_RGBA 0x1908 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A + +/* PixelType */ +/* GL_UNSIGNED_BYTE */ +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 + +/* Shaders */ +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB +#define GL_MAX_VARYING_VECTORS 0x8DFC +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD +#define GL_SHADER_TYPE 0x8B4F +#define GL_DELETE_STATUS 0x8B80 +#define GL_LINK_STATUS 0x8B82 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_CURRENT_PROGRAM 0x8B8D + +/* StencilFunction */ +#define GL_NEVER 0x0200 +#define GL_LESS 0x0201 +#define GL_EQUAL 0x0202 +#define GL_LEQUAL 0x0203 +#define GL_GREATER 0x0204 +#define GL_NOTEQUAL 0x0205 +#define GL_GEQUAL 0x0206 +#define GL_ALWAYS 0x0207 + +/* StencilOp */ +/* GL_ZERO */ +#define GL_KEEP 0x1E00 +#define GL_REPLACE 0x1E01 +#define GL_INCR 0x1E02 +#define GL_DECR 0x1E03 +#define GL_INVERT 0x150A +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 + +/* StringName */ +#define GL_VENDOR 0x1F00 +#define GL_RENDERER 0x1F01 +#define GL_VERSION 0x1F02 +#define GL_EXTENSIONS 0x1F03 + +/* TextureMagFilter */ +#define GL_NEAREST 0x2600 +#define GL_LINEAR 0x2601 + +/* TextureMinFilter */ +/* GL_NEAREST */ +/* GL_LINEAR */ +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 + +/* TextureParameterName */ +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 + +/* TextureTarget */ +/* GL_TEXTURE_2D */ +#define GL_TEXTURE 0x1702 + +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C + +/* TextureUnit */ +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 + +/* TextureWrapMode */ +#define GL_REPEAT 0x2901 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_MIRRORED_REPEAT 0x8370 + +/* Uniform Types */ +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_CUBE 0x8B60 + +/* Vertex Arrays */ +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F + +/* Read Format */ +#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B + +/* Shader Source */ +#define GL_COMPILE_STATUS 0x8B81 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_SHADER_COMPILER 0x8DFA + +/* Shader Binary */ +#define GL_SHADER_BINARY_FORMATS 0x8DF8 +#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 + +/* Shader Precision-Specified Types */ +#define GL_LOW_FLOAT 0x8DF0 +#define GL_MEDIUM_FLOAT 0x8DF1 +#define GL_HIGH_FLOAT 0x8DF2 +#define GL_LOW_INT 0x8DF3 +#define GL_MEDIUM_INT 0x8DF4 +#define GL_HIGH_INT 0x8DF5 + +/* Framebuffer Object. */ +#define GL_FRAMEBUFFER 0x8D40 +#define GL_RENDERBUFFER 0x8D41 + +#define GL_RGBA4 0x8056 +#define GL_RGB5_A1 0x8057 +#define GL_RGB565 0x8D62 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_STENCIL_INDEX 0x1901 +#define GL_STENCIL_INDEX8 0x8D48 + +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#define GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 + +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 + +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_STENCIL_ATTACHMENT 0x8D20 + +#define GL_NONE 0 + +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9 +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD + +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 + +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 + +/*------------------------------------------------------------------------- + * GL core functions. + *-----------------------------------------------------------------------*/ + +GL_APICALL void GL_APIENTRY glActiveTexture (GLenum texture); +GL_APICALL void GL_APIENTRY glAttachShader (GLuint program, GLuint shader); +GL_APICALL void GL_APIENTRY glBindAttribLocation (GLuint program, GLuint index, const char* name); +GL_APICALL void GL_APIENTRY glBindBuffer (GLenum target, GLuint buffer); +GL_APICALL void GL_APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer); +GL_APICALL void GL_APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer); +GL_APICALL void GL_APIENTRY glBindTexture (GLenum target, GLuint texture); +GL_APICALL void GL_APIENTRY glBlendColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +GL_APICALL void GL_APIENTRY glBlendEquation ( GLenum mode ); +GL_APICALL void GL_APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha); +GL_APICALL void GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor); +GL_APICALL void GL_APIENTRY glBlendFuncSeparate (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +GL_APICALL void GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const void* data, GLenum usage); +GL_APICALL void GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void* data); +GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus (GLenum target); +GL_APICALL void GL_APIENTRY glClear (GLbitfield mask); +GL_APICALL void GL_APIENTRY glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +GL_APICALL void GL_APIENTRY glClearDepthf (GLclampf depth); +GL_APICALL void GL_APIENTRY glClearStencil (GLint s); +GL_APICALL void GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +GL_APICALL void GL_APIENTRY glCompileShader (GLuint shader); +GL_APICALL void GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data); +GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data); +GL_APICALL void GL_APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GL_APICALL void GL_APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL GLuint GL_APIENTRY glCreateProgram (void); +GL_APICALL GLuint GL_APIENTRY glCreateShader (GLenum type); +GL_APICALL void GL_APIENTRY glCullFace (GLenum mode); +GL_APICALL void GL_APIENTRY glDeleteBuffers (GLsizei n, const GLuint* buffers); +GL_APICALL void GL_APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint* framebuffers); +GL_APICALL void GL_APIENTRY glDeleteProgram (GLuint program); +GL_APICALL void GL_APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint* renderbuffers); +GL_APICALL void GL_APIENTRY glDeleteShader (GLuint shader); +GL_APICALL void GL_APIENTRY glDeleteTextures (GLsizei n, const GLuint* textures); +GL_APICALL void GL_APIENTRY glDepthFunc (GLenum func); +GL_APICALL void GL_APIENTRY glDepthMask (GLboolean flag); +GL_APICALL void GL_APIENTRY glDepthRangef (GLclampf zNear, GLclampf zFar); +GL_APICALL void GL_APIENTRY glDetachShader (GLuint program, GLuint shader); +GL_APICALL void GL_APIENTRY glDisable (GLenum cap); +GL_APICALL void GL_APIENTRY glDisableVertexAttribArray (GLuint index); +GL_APICALL void GL_APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count); +GL_APICALL void GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const void* indices); +GL_APICALL void GL_APIENTRY glEnable (GLenum cap); +GL_APICALL void GL_APIENTRY glEnableVertexAttribArray (GLuint index); +GL_APICALL void GL_APIENTRY glFinish (void); +GL_APICALL void GL_APIENTRY glFlush (void); +GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +GL_APICALL void GL_APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GL_APICALL void GL_APIENTRY glFrontFace (GLenum mode); +GL_APICALL void GL_APIENTRY glGenBuffers (GLsizei n, GLuint* buffers); +GL_APICALL void GL_APIENTRY glGenerateMipmap (GLenum target); +GL_APICALL void GL_APIENTRY glGenFramebuffers (GLsizei n, GLuint* framebuffers); +GL_APICALL void GL_APIENTRY glGenRenderbuffers (GLsizei n, GLuint* renderbuffers); +GL_APICALL void GL_APIENTRY glGenTextures (GLsizei n, GLuint* textures); +GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name); +GL_APICALL void GL_APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name); +GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders); +GL_APICALL int GL_APIENTRY glGetAttribLocation (GLuint program, const char* name); +GL_APICALL void GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean* params); +GL_APICALL void GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint* params); +GL_APICALL GLenum GL_APIENTRY glGetError (void); +GL_APICALL void GL_APIENTRY glGetFloatv (GLenum pname, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetIntegerv (GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufsize, GLsizei* length, char* infolog); +GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog); +GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision); +GL_APICALL void GL_APIENTRY glGetShaderSource (GLuint shader, GLsizei bufsize, GLsizei* length, char* source); +GL_APICALL const GLubyte* GL_APIENTRY glGetString (GLenum name); +GL_APICALL void GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetUniformiv (GLuint program, GLint location, GLint* params); +GL_APICALL int GL_APIENTRY glGetUniformLocation (GLuint program, const char* name); +GL_APICALL void GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, void** pointer); +GL_APICALL void GL_APIENTRY glHint (GLenum target, GLenum mode); +GL_APICALL GLboolean GL_APIENTRY glIsBuffer (GLuint buffer); +GL_APICALL GLboolean GL_APIENTRY glIsEnabled (GLenum cap); +GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer (GLuint framebuffer); +GL_APICALL GLboolean GL_APIENTRY glIsProgram (GLuint program); +GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer (GLuint renderbuffer); +GL_APICALL GLboolean GL_APIENTRY glIsShader (GLuint shader); +GL_APICALL GLboolean GL_APIENTRY glIsTexture (GLuint texture); +GL_APICALL void GL_APIENTRY glLineWidth (GLfloat width); +GL_APICALL void GL_APIENTRY glLinkProgram (GLuint program); +GL_APICALL void GL_APIENTRY glPixelStorei (GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units); +GL_APICALL void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels); +GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void); +GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glSampleCoverage (GLclampf value, GLboolean invert); +GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length); +GL_APICALL void GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const char** string, const GLint* length); +GL_APICALL void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilMask (GLuint mask); +GL_APICALL void GL_APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass); +GL_APICALL void GL_APIENTRY glStencilOpSeparate (GLenum face, GLenum fail, GLenum zfail, GLenum zpass); +GL_APICALL void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels); +GL_APICALL void GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param); +GL_APICALL void GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat* params); +GL_APICALL void GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint* params); +GL_APICALL void GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels); +GL_APICALL void GL_APIENTRY glUniform1f (GLint location, GLfloat x); +GL_APICALL void GL_APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform1i (GLint location, GLint x); +GL_APICALL void GL_APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniform2f (GLint location, GLfloat x, GLfloat y); +GL_APICALL void GL_APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform2i (GLint location, GLint x, GLint y); +GL_APICALL void GL_APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniform3f (GLint location, GLfloat x, GLfloat y, GLfloat z); +GL_APICALL void GL_APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform3i (GLint location, GLint x, GLint y, GLint z); +GL_APICALL void GL_APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniform4f (GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GL_APICALL void GL_APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform4i (GLint location, GLint x, GLint y, GLint z, GLint w); +GL_APICALL void GL_APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUseProgram (GLuint program); +GL_APICALL void GL_APIENTRY glValidateProgram (GLuint program); +GL_APICALL void GL_APIENTRY glVertexAttrib1f (GLuint indx, GLfloat x); +GL_APICALL void GL_APIENTRY glVertexAttrib1fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttrib2f (GLuint indx, GLfloat x, GLfloat y); +GL_APICALL void GL_APIENTRY glVertexAttrib2fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttrib3f (GLuint indx, GLfloat x, GLfloat y, GLfloat z); +GL_APICALL void GL_APIENTRY glVertexAttrib3fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr); +GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height); + +#ifdef __cplusplus +} +#endif + +#endif /* __gl2_h_ */ diff --git a/opengl/include/GLES2/gl2ext.h b/opengl/include/GLES2/gl2ext.h new file mode 100644 index 0000000000000..b9a3847c45325 --- /dev/null +++ b/opengl/include/GLES2/gl2ext.h @@ -0,0 +1,518 @@ +#ifndef __gl2ext_h_ +#define __gl2ext_h_ + +/* $Revision: 8271 $ on $Date:: 2009-05-21 09:33:40 -0700 #$ */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This document is licensed under the SGI Free Software B License Version + * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ . + */ + +#ifndef GL_APIENTRYP +# define GL_APIENTRYP GL_APIENTRY* +#endif + +/*------------------------------------------------------------------------* + * OES extension tokens + *------------------------------------------------------------------------*/ + +/* GL_OES_compressed_ETC1_RGB8_texture */ +#ifndef GL_OES_compressed_ETC1_RGB8_texture +#define GL_ETC1_RGB8_OES 0x8D64 +#endif + +/* GL_OES_compressed_paletted_texture */ +#ifndef GL_OES_compressed_paletted_texture +#define GL_PALETTE4_RGB8_OES 0x8B90 +#define GL_PALETTE4_RGBA8_OES 0x8B91 +#define GL_PALETTE4_R5_G6_B5_OES 0x8B92 +#define GL_PALETTE4_RGBA4_OES 0x8B93 +#define GL_PALETTE4_RGB5_A1_OES 0x8B94 +#define GL_PALETTE8_RGB8_OES 0x8B95 +#define GL_PALETTE8_RGBA8_OES 0x8B96 +#define GL_PALETTE8_R5_G6_B5_OES 0x8B97 +#define GL_PALETTE8_RGBA4_OES 0x8B98 +#define GL_PALETTE8_RGB5_A1_OES 0x8B99 +#endif + +/* GL_OES_depth24 */ +#ifndef GL_OES_depth24 +#define GL_DEPTH_COMPONENT24_OES 0x81A6 +#endif + +/* GL_OES_depth32 */ +#ifndef GL_OES_depth32 +#define GL_DEPTH_COMPONENT32_OES 0x81A7 +#endif + +/* GL_OES_depth_texture */ +/* No new tokens introduced by this extension. */ + +/* GL_OES_EGL_image */ +#ifndef GL_OES_EGL_image +typedef void* GLeglImageOES; +#endif + +/* GL_OES_get_program_binary */ +#ifndef GL_OES_get_program_binary +#define GL_PROGRAM_BINARY_LENGTH_OES 0x8741 +#define GL_NUM_PROGRAM_BINARY_FORMATS_OES 0x87FE +#define GL_PROGRAM_BINARY_FORMATS_OES 0x87FF +#endif + +/* GL_OES_mapbuffer */ +#ifndef GL_OES_mapbuffer +#define GL_WRITE_ONLY_OES 0x88B9 +#define GL_BUFFER_ACCESS_OES 0x88BB +#define GL_BUFFER_MAPPED_OES 0x88BC +#define GL_BUFFER_MAP_POINTER_OES 0x88BD +#endif + +/* GL_OES_packed_depth_stencil */ +#ifndef GL_OES_packed_depth_stencil +#define GL_DEPTH_STENCIL_OES 0x84F9 +#define GL_UNSIGNED_INT_24_8_OES 0x84FA +#define GL_DEPTH24_STENCIL8_OES 0x88F0 +#endif + +/* GL_OES_rgb8_rgba8 */ +#ifndef GL_OES_rgb8_rgba8 +#define GL_RGB8_OES 0x8051 +#define GL_RGBA8_OES 0x8058 +#endif + +/* GL_OES_standard_derivatives */ +#ifndef GL_OES_standard_derivatives +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES 0x8B8B +#endif + +/* GL_OES_stencil1 */ +#ifndef GL_OES_stencil1 +#define GL_STENCIL_INDEX1_OES 0x8D46 +#endif + +/* GL_OES_stencil4 */ +#ifndef GL_OES_stencil4 +#define GL_STENCIL_INDEX4_OES 0x8D47 +#endif + +/* GL_OES_texture3D */ +#ifndef GL_OES_texture3D +#define GL_TEXTURE_WRAP_R_OES 0x8072 +#define GL_TEXTURE_3D_OES 0x806F +#define GL_TEXTURE_BINDING_3D_OES 0x806A +#define GL_MAX_3D_TEXTURE_SIZE_OES 0x8073 +#define GL_SAMPLER_3D_OES 0x8B5F +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES 0x8CD4 +#endif + +/* GL_OES_texture_half_float */ +#ifndef GL_OES_texture_half_float +#define GL_HALF_FLOAT_OES 0x8D61 +#endif + +/* GL_OES_vertex_half_float */ +/* GL_HALF_FLOAT_OES defined in GL_OES_texture_half_float already. */ + +/* GL_OES_vertex_type_10_10_10_2 */ +#ifndef GL_OES_vertex_type_10_10_10_2 +#define GL_UNSIGNED_INT_10_10_10_2_OES 0x8DF6 +#define GL_INT_10_10_10_2_OES 0x8DF7 +#endif + +/*------------------------------------------------------------------------* + * AMD extension tokens + *------------------------------------------------------------------------*/ + +/* GL_AMD_compressed_3DC_texture */ +#ifndef GL_AMD_compressed_3DC_texture +#define GL_3DC_X_AMD 0x87F9 +#define GL_3DC_XY_AMD 0x87FA +#endif + +/* GL_AMD_compressed_ATC_texture */ +#ifndef GL_AMD_compressed_ATC_texture +#define GL_ATC_RGB_AMD 0x8C92 +#define GL_ATC_RGBA_EXPLICIT_ALPHA_AMD 0x8C93 +#define GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD 0x87EE +#endif + +/* GL_AMD_program_binary_Z400 */ +#ifndef GL_AMD_program_binary_Z400 +#define GL_Z400_BINARY_AMD 0x8740 +#endif + +/* GL_AMD_performance_monitor */ +#ifndef GL_AMD_performance_monitor +#define GL_COUNTER_TYPE_AMD 0x8BC0 +#define GL_COUNTER_RANGE_AMD 0x8BC1 +#define GL_UNSIGNED_INT64_AMD 0x8BC2 +#define GL_PERCENTAGE_AMD 0x8BC3 +#define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4 +#define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5 +#define GL_PERFMON_RESULT_AMD 0x8BC6 +#endif + +/*------------------------------------------------------------------------* + * EXT extension tokens + *------------------------------------------------------------------------*/ + +/* GL_EXT_texture_filter_anisotropic */ +#ifndef GL_EXT_texture_filter_anisotropic +#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE +#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF +#endif + +/* GL_EXT_texture_type_2_10_10_10_REV */ +#ifndef GL_EXT_texture_type_2_10_10_10_REV +#define GL_UNSIGNED_INT_2_10_10_10_REV_EXT 0x8368 +#endif + +/* GL_EXT_texture_format_BGRA8888 */ +#ifndef GL_EXT_texture_format_BGRA8888 +#define GL_BGRA 0x80E1 +#endif + +/*------------------------------------------------------------------------* + * IMG extension tokens + *------------------------------------------------------------------------*/ + +/* GL_IMG_read_format */ +#ifndef GL_IMG_read_format +#define GL_BGRA 0x80E1 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#endif + +/* GL_IMG_texture_compression_pvrtc */ +#ifndef GL_IMG_texture_compression_pvrtc +#define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00 +#define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG 0x8C01 +#define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02 +#define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03 +#endif + +/*------------------------------------------------------------------------* + * NV extension tokens + *------------------------------------------------------------------------*/ + +/* GL_NV_fence */ +#ifndef GL_NV_fence +#define GL_ALL_COMPLETED_NV 0x84F2 +#define GL_FENCE_STATUS_NV 0x84F3 +#define GL_FENCE_CONDITION_NV 0x84F4 +#endif + +/*------------------------------------------------------------------------* + * QCOM extension tokens + *------------------------------------------------------------------------*/ + +/* GL_QCOM_driver_control */ +/* No new tokens introduced by this extension. */ + +/* GL_QCOM_perfmon_global_mode */ +#ifndef GL_QCOM_perfmon_global_mode +#define GL_PERFMON_GLOBAL_MODE_QCOM 0x8FA0 +#endif + +/*------------------------------------------------------------------------* + * End of extension tokens, start of corresponding extension functions + *------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------* + * OES extension functions + *------------------------------------------------------------------------*/ + +/* GL_OES_compressed_ETC1_RGB8_texture */ +#ifndef GL_OES_compressed_ETC1_RGB8_texture +#define GL_OES_compressed_ETC1_RGB8_texture 1 +#endif + +/* GL_OES_compressed_paletted_texture */ +#ifndef GL_OES_compressed_paletted_texture +#define GL_OES_compressed_paletted_texture 1 +#endif + +/* GL_OES_EGL_image */ +#ifndef GL_OES_EGL_image +#define GL_OES_EGL_image 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glEGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image); +GL_APICALL void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES (GLenum target, GLeglImageOES image); +#endif +typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES image); +typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image); +#endif + +/* GL_OES_depth24 */ +#ifndef GL_OES_depth24 +#define GL_OES_depth24 1 +#endif + +/* GL_OES_depth32 */ +#ifndef GL_OES_depth32 +#define GL_OES_depth32 1 +#endif + +/* GL_OES_depth_texture */ +#ifndef GL_OES_depth_texture +#define GL_OES_depth_texture 1 +#endif + +/* GL_OES_element_index_uint */ +#ifndef GL_OES_element_index_uint +#define GL_OES_element_index_uint 1 +#endif + +/* GL_OES_fbo_render_mipmap */ +#ifndef GL_OES_fbo_render_mipmap +#define GL_OES_fbo_render_mipmap 1 +#endif + +/* GL_OES_fragment_precision_high */ +#ifndef GL_OES_fragment_precision_high +#define GL_OES_fragment_precision_high 1 +#endif + +/* GL_OES_get_program_binary */ +#ifndef GL_OES_get_program_binary +#define GL_OES_get_program_binary 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGetProgramBinaryOES (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary); +GL_APICALL void GL_APIENTRY glProgramBinaryOES (GLuint program, GLenum binaryFormat, const void *binary, GLint length); +#endif +typedef void (GL_APIENTRYP PFNGLGETPROGRAMBINARYOESPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary); +typedef void (GL_APIENTRYP PFNGLPROGRAMBINARYOESPROC) (GLuint program, GLenum binaryFormat, const void *binary, GLint length); +#endif + +/* GL_OES_mapbuffer */ +#ifndef GL_OES_mapbuffer +#define GL_OES_mapbuffer 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void* GL_APIENTRY glMapBufferOES (GLenum target, GLenum access); +GL_APICALL GLboolean GL_APIENTRY glUnmapBufferOES (GLenum target); +GL_APICALL void GL_APIENTRY glGetBufferPointervOES (GLenum target, GLenum pname, void** params); +#endif +typedef void* (GL_APIENTRYP PFNGLMAPBUFFEROESPROC) (GLenum target, GLenum access); +typedef GLboolean (GL_APIENTRYP PFNGLUNMAPBUFFEROESPROC) (GLenum target); +typedef void (GL_APIENTRYP PFNGLGETBUFFERPOINTERVOESPROC) (GLenum target, GLenum pname, void** params); +#endif + +/* GL_OES_packed_depth_stencil */ +#ifndef GL_OES_packed_depth_stencil +#define GL_OES_packed_depth_stencil 1 +#endif + +/* GL_OES_rgb8_rgba8 */ +#ifndef GL_OES_rgb8_rgba8 +#define GL_OES_rgb8_rgba8 1 +#endif + +/* GL_OES_standard_derivatives */ +#ifndef GL_OES_standard_derivatives +#define GL_OES_standard_derivatives 1 +#endif + +/* GL_OES_stencil1 */ +#ifndef GL_OES_stencil1 +#define GL_OES_stencil1 1 +#endif + +/* GL_OES_stencil4 */ +#ifndef GL_OES_stencil4 +#define GL_OES_stencil4 1 +#endif + +/* GL_OES_texture_3D */ +#ifndef GL_OES_texture_3D +#define GL_OES_texture_3D 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glTexImage3DOES (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels); +GL_APICALL void GL_APIENTRY glTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels); +GL_APICALL void GL_APIENTRY glCopyTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glCompressedTexImage3DOES (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data); +GL_APICALL void GL_APIENTRY glCompressedTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data); +GL_APICALL void GL_APIENTRY glFramebufferTexture3DOES (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +#endif +typedef void (GL_APIENTRYP PFNGLTEXIMAGE3DOESPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels); +typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels); +typedef void (GL_APIENTRYP PFNGLCOPYTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DOESPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data); +typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DOES) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +#endif + +/* GL_OES_texture_float_linear */ +#ifndef GL_OES_texture_float_linear +#define GL_OES_texture_float_linear 1 +#endif + +/* GL_OES_texture_half_float_linear */ +#ifndef GL_OES_texture_half_float_linear +#define GL_OES_texture_half_float_linear 1 +#endif + +/* GL_OES_texture_float */ +#ifndef GL_OES_texture_float +#define GL_OES_texture_float 1 +#endif + +/* GL_OES_texture_half_float */ +#ifndef GL_OES_texture_half_float +#define GL_OES_texture_half_float 1 +#endif + +/* GL_OES_texture_npot */ +#ifndef GL_OES_texture_npot +#define GL_OES_texture_npot 1 +#endif + +/* GL_OES_vertex_half_float */ +#ifndef GL_OES_vertex_half_float +#define GL_OES_vertex_half_float 1 +#endif + +/* GL_OES_vertex_type_10_10_10_2 */ +#ifndef GL_OES_vertex_type_10_10_10_2 +#define GL_OES_vertex_type_10_10_10_2 1 +#endif + +/*------------------------------------------------------------------------* + * AMD extension functions + *------------------------------------------------------------------------*/ + +/* GL_AMD_compressed_3DC_texture */ +#ifndef GL_AMD_compressed_3DC_texture +#define GL_AMD_compressed_3DC_texture 1 +#endif + +/* GL_AMD_compressed_ATC_texture */ +#ifndef GL_AMD_compressed_ATC_texture +#define GL_AMD_compressed_ATC_texture 1 +#endif + +/* GL_AMD_program_binary_Z400 */ +#ifndef GL_AMD_program_binary_Z400 +#define GL_AMD_program_binary_Z400 1 +#endif + +/* AMD_performance_monitor */ +#ifndef GL_AMD_performance_monitor +#define GL_AMD_performance_monitor 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGetPerfMonitorGroupsAMD (GLint *numGroups, GLsizei groupsSize, GLuint *groups); +GL_APICALL void GL_APIENTRY glGetPerfMonitorCountersAMD (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters); +GL_APICALL void GL_APIENTRY glGetPerfMonitorGroupStringAMD (GLuint group, GLsizei bufSize, GLsizei *length, char *groupString); +GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterStringAMD (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, char *counterString); +GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterInfoAMD (GLuint group, GLuint counter, GLenum pname, void *data); +GL_APICALL void GL_APIENTRY glGenPerfMonitorsAMD (GLsizei n, GLuint *monitors); +GL_APICALL void GL_APIENTRY glDeletePerfMonitorsAMD (GLsizei n, GLuint *monitors); +GL_APICALL void GL_APIENTRY glSelectPerfMonitorCountersAMD (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *countersList); +GL_APICALL void GL_APIENTRY glBeginPerfMonitorAMD (GLuint monitor); +GL_APICALL void GL_APIENTRY glEndPerfMonitorAMD (GLuint monitor); +GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterDataAMD (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten); +#endif +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint *numGroups, GLsizei groupsSize, GLuint *groups); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei *length, char *groupString); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, char *counterString); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, void *data); +typedef void (GL_APIENTRYP PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors); +typedef void (GL_APIENTRYP PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors); +typedef void (GL_APIENTRYP PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *countersList); +typedef void (GL_APIENTRYP PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor); +typedef void (GL_APIENTRYP PFNGLENDPERFMONITORAMDPROC) (GLuint monitor); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten); +#endif + +/*------------------------------------------------------------------------* + * EXT extension functions + *------------------------------------------------------------------------*/ + +/* GL_EXT_texture_filter_anisotropic */ +#ifndef GL_EXT_texture_filter_anisotropic +#define GL_EXT_texture_filter_anisotropic 1 +#endif + +/* GL_EXT_texture_type_2_10_10_10_REV */ +#ifndef GL_EXT_texture_type_2_10_10_10_REV +#define GL_EXT_texture_type_2_10_10_10_REV 1 +#endif + +/* GL_EXT_texture_format_BGRA8888 */ +#ifndef GL_EXT_texture_format_BGRA8888 +#define GL_EXT_texture_format_BGRA8888 1 +#endif + +/*------------------------------------------------------------------------* + * IMG extension functions + *------------------------------------------------------------------------*/ + +/* GL_IMG_read_format */ +#ifndef GL_IMG_read_format +#define GL_IMG_read_format 1 +#endif + +/* GL_IMG_texture_compression_pvrtc */ +#ifndef GL_IMG_texture_compression_pvrtc +#define GL_IMG_texture_compression_pvrtc 1 +#endif + +/*------------------------------------------------------------------------* + * NV extension functions + *------------------------------------------------------------------------*/ + +/* GL_NV_fence */ +#ifndef GL_NV_fence +#define GL_NV_fence 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDeleteFencesNV (GLsizei, const GLuint *); +GL_APICALL void GL_APIENTRY glGenFencesNV (GLsizei, GLuint *); +GL_APICALL GLboolean GL_APIENTRY glIsFenceNV (GLuint); +GL_APICALL GLboolean GL_APIENTRY glTestFenceNV (GLuint); +GL_APICALL void GL_APIENTRY glGetFenceivNV (GLuint, GLenum, GLint *); +GL_APICALL void GL_APIENTRY glFinishFenceNV (GLuint); +GL_APICALL void GL_APIENTRY glSetFenceNV (GLuint, GLenum); +#endif +typedef void (GL_APIENTRYP PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint *fences); +typedef void (GL_APIENTRYP PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fences); +typedef GLboolean (GL_APIENTRYP PFNGLISFENCENVPROC) (GLuint fence); +typedef GLboolean (GL_APIENTRYP PFNGLTESTFENCENVPROC) (GLuint fence); +typedef void (GL_APIENTRYP PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLFINISHFENCENVPROC) (GLuint fence); +typedef void (GL_APIENTRYP PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition); +#endif + +/*------------------------------------------------------------------------* + * QCOM extension functions + *------------------------------------------------------------------------*/ + +/* GL_QCOM_driver_control */ +#ifndef GL_QCOM_driver_control +#define GL_QCOM_driver_control 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGetDriverControlsQCOM (GLint *num, GLsizei size, GLuint *driverControls); +GL_APICALL void GL_APIENTRY glGetDriverControlStringQCOM (GLuint driverControl, GLsizei bufSize, GLsizei *length, char *driverControlString); +GL_APICALL void GL_APIENTRY glEnableDriverControlQCOM (GLuint driverControl); +GL_APICALL void GL_APIENTRY glDisableDriverControlQCOM (GLuint driverControl); +#endif +typedef void (GL_APIENTRYP PFNGLGETDRIVERCONTROLSQCOMPROC) (GLint *num, GLsizei size, GLuint *driverControls); +typedef void (GL_APIENTRYP PFNGLGETDRIVERCONTROLSTRINGQCOMPROC) (GLuint driverControl, GLsizei bufSize, GLsizei *length, char *driverControlString); +typedef void (GL_APIENTRYP PFNGLENABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl); +typedef void (GL_APIENTRYP PFNGLDISABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl); +#endif + +/* GL_QCOM_perfmon_global_mode */ +#ifndef GL_QCOM_perfmon_global_mode +#define GL_QCOM_perfmon_global_mode 1 +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __gl2ext_h_ */ From f5fbc7983a85f42ec891decbae3581185c8428ab Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Wed, 27 May 2009 20:32:20 -0700 Subject: [PATCH 35/83] minor modifications to the official GLES 2.x headers - changed glTexImage2D() declaration so it matches that of GLES 1.x; otherwise we can't include both headers (!!!) - added parameter names to the declaration of some extensions (this is needed by glapigen and glentrygen) --- opengl/include/GLES2/gl2.h | 2 +- opengl/include/GLES2/gl2ext.h | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/opengl/include/GLES2/gl2.h b/opengl/include/GLES2/gl2.h index 83090741b00a5..0182a676d1b48 100644 --- a/opengl/include/GLES2/gl2.h +++ b/opengl/include/GLES2/gl2.h @@ -575,7 +575,7 @@ GL_APICALL void GL_APIENTRY glStencilMask (GLuint mask); GL_APICALL void GL_APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask); GL_APICALL void GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass); GL_APICALL void GL_APIENTRY glStencilOpSeparate (GLenum face, GLenum fail, GLenum zfail, GLenum zpass); -GL_APICALL void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels); +GL_APICALL void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels); GL_APICALL void GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param); GL_APICALL void GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat* params); GL_APICALL void GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param); diff --git a/opengl/include/GLES2/gl2ext.h b/opengl/include/GLES2/gl2ext.h index b9a3847c45325..72f1ae79ada95 100644 --- a/opengl/include/GLES2/gl2ext.h +++ b/opengl/include/GLES2/gl2ext.h @@ -470,13 +470,13 @@ typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monito #ifndef GL_NV_fence #define GL_NV_fence 1 #ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glDeleteFencesNV (GLsizei, const GLuint *); -GL_APICALL void GL_APIENTRY glGenFencesNV (GLsizei, GLuint *); -GL_APICALL GLboolean GL_APIENTRY glIsFenceNV (GLuint); -GL_APICALL GLboolean GL_APIENTRY glTestFenceNV (GLuint); -GL_APICALL void GL_APIENTRY glGetFenceivNV (GLuint, GLenum, GLint *); -GL_APICALL void GL_APIENTRY glFinishFenceNV (GLuint); -GL_APICALL void GL_APIENTRY glSetFenceNV (GLuint, GLenum); +GL_APICALL void GL_APIENTRY glDeleteFencesNV (GLsizei n, const GLuint *fences); +GL_APICALL void GL_APIENTRY glGenFencesNV (GLsizei n, GLuint *fences); +GL_APICALL GLboolean GL_APIENTRY glIsFenceNV (GLuint fence); +GL_APICALL GLboolean GL_APIENTRY glTestFenceNV (GLuint fence); +GL_APICALL void GL_APIENTRY glGetFenceivNV (GLuint fence, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glFinishFenceNV (GLuint fence); +GL_APICALL void GL_APIENTRY glSetFenceNV (GLuint fence, GLenum condition); #endif typedef void (GL_APIENTRYP PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint *fences); typedef void (GL_APIENTRYP PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fences); From 2820bd4eda4c75457007f11eb9d98da9bff24a27 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Wed, 27 May 2009 20:38:06 -0700 Subject: [PATCH 36/83] Added most of the support needed for GLES 2.x --- opengl/include/GLES2/gl2platform.h | 29 ++ opengl/libs/Android.mk | 39 +- opengl/libs/EGL/egl.cpp | 114 +++--- opengl/libs/{ => EGL}/egl_entries.in | 0 opengl/libs/GLES2/gl2.cpp | 111 ++++++ opengl/libs/GLES2/gl2_api.in | 426 +++++++++++++++++++++ opengl/libs/GLES2/gl2_entries.in | 142 +++++++ opengl/libs/GLES2/gl2ext_api.in | 105 +++++ opengl/libs/GLES2/gl2ext_entries.in | 35 ++ opengl/libs/{ => GLES_CM}/gl_entries.in | 0 opengl/libs/{ => GLES_CM}/glext_entries.in | 0 opengl/libs/gl_enums.in | 261 ------------- opengl/libs/hooks.h | 14 +- opengl/libs/tools/enumextract.sh | 32 -- opengl/libs/tools/genfiles | 11 +- opengl/libs/tools/glapigen | 15 +- opengl/libs/tools/glentrygen | 15 +- 17 files changed, 991 insertions(+), 358 deletions(-) create mode 100644 opengl/include/GLES2/gl2platform.h rename opengl/libs/{ => EGL}/egl_entries.in (100%) create mode 100644 opengl/libs/GLES2/gl2.cpp create mode 100644 opengl/libs/GLES2/gl2_api.in create mode 100644 opengl/libs/GLES2/gl2_entries.in create mode 100644 opengl/libs/GLES2/gl2ext_api.in create mode 100644 opengl/libs/GLES2/gl2ext_entries.in rename opengl/libs/{ => GLES_CM}/gl_entries.in (100%) rename opengl/libs/{ => GLES_CM}/glext_entries.in (100%) delete mode 100644 opengl/libs/gl_enums.in delete mode 100644 opengl/libs/tools/enumextract.sh diff --git a/opengl/include/GLES2/gl2platform.h b/opengl/include/GLES2/gl2platform.h new file mode 100644 index 0000000000000..3e9036c162c69 --- /dev/null +++ b/opengl/include/GLES2/gl2platform.h @@ -0,0 +1,29 @@ +#ifndef __gl2platform_h_ +#define __gl2platform_h_ + +/* $Revision: 7173 $ on $Date:: 2009-01-09 11:18:21 -0800 #$ */ + +/* + * This document is licensed under the SGI Free Software B License Version + * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ . + */ + +/* Platform-specific types and definitions for OpenGL ES 2.X gl2.h + * Last modified on 2008/12/19 + * + * Adopters may modify khrplatform.h and this file to suit their platform. + * You are encouraged to submit all modifications to the Khronos group so that + * they can be included in future versions of this file. Please submit changes + * by sending them to the public Khronos Bugzilla (http://khronos.org/bugzilla) + * by filing a bug against product "OpenGL-ES" component "Registry". + */ + +#include + +#ifndef GL_APICALL +#define GL_APICALL KHRONOS_APICALL +#endif + +#define GL_APIENTRY KHRONOS_APIENTRY + +#endif /* __gl2platform_h_ */ diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk index c8e11f0a5f718..67a67ec8b8778 100644 --- a/opengl/libs/Android.mk +++ b/opengl/libs/Android.mk @@ -1,6 +1,6 @@ LOCAL_PATH:= $(call my-dir) -# +############################################################################### # Build META EGL library # @@ -30,14 +30,14 @@ include $(BUILD_SHARED_LIBRARY) -# -# Build the wrapper OpenGL ES library +############################################################################### +# Build the wrapper OpenGL ES 1.x library # include $(CLEAR_VARS) -LOCAL_SRC_FILES:= \ - GLES_CM/gl.cpp.arm \ +LOCAL_SRC_FILES:= \ + GLES_CM/gl.cpp.arm \ # LOCAL_SHARED_LIBRARIES += libcutils libEGL @@ -57,3 +57,32 @@ LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES LOCAL_CFLAGS += -fvisibility=hidden include $(BUILD_SHARED_LIBRARY) + + +############################################################################### +# Build the wrapper OpenGL ES 2.x library +# + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + GLES2/gl2.cpp.arm \ +# + +LOCAL_SHARED_LIBRARIES += libcutils libEGL +LOCAL_LDLIBS := -lpthread -ldl +LOCAL_MODULE:= libGLESv2 + +# needed on sim build because of weird logging issues +ifeq ($(TARGET_SIMULATOR),true) +else + LOCAL_SHARED_LIBRARIES += libdl + # we need to access the Bionic private header + LOCAL_CFLAGS += -I$(LOCAL_PATH)/../../../../bionic/libc/private +endif + +LOCAL_CFLAGS += -DLOG_TAG=\"libGLESv2\" +LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES +LOCAL_CFLAGS += -fvisibility=hidden + +include $(BUILD_SHARED_LIBRARY) diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp index 2493fc67ee226..4eae98eee5d5a 100644 --- a/opengl/libs/EGL/egl.cpp +++ b/opengl/libs/EGL/egl.cpp @@ -153,8 +153,14 @@ static void gl_unimplemented() { #define EGL_ENTRY(_r, _api, ...) #_api, static char const * const gl_names[] = { - #include "gl_entries.in" - #include "glext_entries.in" + #include "GLES_CM/gl_entries.in" + #include "GLES_CM/glext_entries.in" + NULL +}; + +static char const * const gl2_names[] = { + #include "GLES2/gl2_entries.in" + #include "GLES2/gl2ext_entries.in" NULL }; @@ -275,11 +281,58 @@ EGLContext getContext() { /*****************************************************************************/ +typedef __eglMustCastToProperFunctionPointerType (*getProcAddressType)( + const char*); + +static __attribute__((noinline)) +void init_api(void* dso, + char const * const * api, + __eglMustCastToProperFunctionPointerType* curr, + getProcAddressType getProcAddress) +{ + char scrap[256]; + while (*api) { + char const * name = *api; + __eglMustCastToProperFunctionPointerType f = + (__eglMustCastToProperFunctionPointerType)dlsym(dso, name); + if (f == NULL) { + // couldn't find the entry-point, use eglGetProcAddress() + f = getProcAddress(name); + } + if (f == NULL) { + // Try without the OES postfix + ssize_t index = ssize_t(strlen(name)) - 3; + if ((index>0 && (index<255)) && (!strcmp(name+index, "OES"))) { + strncpy(scrap, name, index); + scrap[index] = 0; + f = (__eglMustCastToProperFunctionPointerType)dlsym(dso, scrap); + //LOGD_IF(f, "found <%s> instead", scrap); + } + } + if (f == NULL) { + // Try with the OES postfix + ssize_t index = ssize_t(strlen(name)) - 3; + if ((index>0 && (index<252)) && (strcmp(name+index, "OES"))) { + strncpy(scrap, name, index); + scrap[index] = 0; + strcat(scrap, "OES"); + f = (__eglMustCastToProperFunctionPointerType)dlsym(dso, scrap); + //LOGD_IF(f, "found <%s> instead", scrap); + } + } + if (f == NULL) { + //LOGD("%s", name); + f = (__eglMustCastToProperFunctionPointerType)gl_unimplemented; + } + *curr++ = f; + api++; + } +} + static __attribute__((noinline)) void *load_driver(const char* driver, gl_hooks_t* hooks) { //LOGD("%s", driver); - char scrap[256]; void* dso = dlopen(driver, RTLD_NOW | RTLD_LOCAL); LOGE_IF(!dso, "couldn't load <%s> library (%s)", @@ -296,13 +349,11 @@ void *load_driver(const char* driver, gl_hooks_t* hooks) LOGE_IF(!getProcAddress, "can't find eglGetProcAddress() in %s", driver); - - __eglMustCastToProperFunctionPointerType* curr; - char const * const * api; gl_hooks_t::egl_t* egl = &hooks->egl; - curr = (__eglMustCastToProperFunctionPointerType*)egl; - api = egl_names; + __eglMustCastToProperFunctionPointerType* curr = + (__eglMustCastToProperFunctionPointerType*)egl; + char const * const * api = egl_names; while (*api) { char const * name = *api; __eglMustCastToProperFunctionPointerType f = @@ -317,45 +368,14 @@ void *load_driver(const char* driver, gl_hooks_t* hooks) *curr++ = f; api++; } - gl_hooks_t::gl_t* gl = &hooks->gl; - curr = (__eglMustCastToProperFunctionPointerType*)gl; - api = gl_names; - while (*api) { - char const * name = *api; - __eglMustCastToProperFunctionPointerType f = - (__eglMustCastToProperFunctionPointerType)dlsym(dso, name); - if (f == NULL) { - // couldn't find the entry-point, use eglGetProcAddress() - f = getProcAddress(name); - } - if (f == NULL) { - // Try without the OES postfix - ssize_t index = ssize_t(strlen(name)) - 3; - if ((index>0 && (index<255)) && (!strcmp(name+index, "OES"))) { - strncpy(scrap, name, index); - scrap[index] = 0; - f = (__eglMustCastToProperFunctionPointerType)dlsym(dso, scrap); - //LOGD_IF(f, "found <%s> instead", scrap); - } - } - if (f == NULL) { - // Try with the OES postfix - ssize_t index = ssize_t(strlen(name)) - 3; - if ((index>0 && (index<252)) && (strcmp(name+index, "OES"))) { - strncpy(scrap, name, index); - scrap[index] = 0; - strcat(scrap, "OES"); - f = (__eglMustCastToProperFunctionPointerType)dlsym(dso, scrap); - //LOGD_IF(f, "found <%s> instead", scrap); - } - } - if (f == NULL) { - //LOGD("%s", name); - f = (__eglMustCastToProperFunctionPointerType)gl_unimplemented; - } - *curr++ = f; - api++; - } + + init_api(dso, gl_names, + (__eglMustCastToProperFunctionPointerType*)&hooks->gl, + getProcAddress); + + init_api(dso, gl2_names, + (__eglMustCastToProperFunctionPointerType*)&hooks->gl2, + getProcAddress); } return dso; } diff --git a/opengl/libs/egl_entries.in b/opengl/libs/EGL/egl_entries.in similarity index 100% rename from opengl/libs/egl_entries.in rename to opengl/libs/EGL/egl_entries.in diff --git a/opengl/libs/GLES2/gl2.cpp b/opengl/libs/GLES2/gl2.cpp new file mode 100644 index 0000000000000..e5358c3458081 --- /dev/null +++ b/opengl/libs/GLES2/gl2.cpp @@ -0,0 +1,111 @@ +/* + ** Copyright 2007, 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. + */ + +#include +#include +#include + +#include + +#include +#include + +#include +#include + +#include "hooks.h" +#include "egl_impl.h" + +using namespace android; + +// ---------------------------------------------------------------------------- +// Actual GL entry-points +// ---------------------------------------------------------------------------- + +#undef API_ENTRY +#undef CALL_GL_API +#undef CALL_GL_API_RETURN + +#if USE_FAST_TLS_KEY + + #define API_ENTRY(_api) __attribute__((naked)) _api + + #define CALL_GL_API(_api, ...) \ + asm volatile( \ + "mov r12, #0xFFFF0FFF \n" \ + "ldr r12, [r12, #-15] \n" \ + "ldr r12, [r12, %[tls]] \n" \ + "cmp r12, #0 \n" \ + "ldrne pc, [r12, %[api]] \n" \ + "bx lr \n" \ + : \ + : [tls] "J"(TLS_SLOT_OPENGL_API*4), \ + [api] "J"(__builtin_offsetof(gl_hooks_t, gl2._api)) \ + : \ + ); + + #define CALL_GL_API_RETURN(_api, ...) \ + CALL_GL_API(_api, __VA_ARGS__) \ + return 0; // placate gcc's warnings. never reached. + +#else + + #define API_ENTRY(_api) _api + + #define CALL_GL_API(_api, ...) \ + gl_hooks_t::gl2_t const * const _c = &getGlThreadSpecific()->gl2; \ + _c->_api(__VA_ARGS__) + + #define CALL_GL_API_RETURN(_api, ...) \ + gl_hooks_t::gl2_t const * const _c = &getGlThreadSpecific()->gl2; \ + return _c->_api(__VA_ARGS__) + +#endif + + +extern "C" { +#include "gl2_api.in" +#include "gl2ext_api.in" +} + +#undef API_ENTRY +#undef CALL_GL_API +#undef CALL_GL_API_RETURN + + +/* + * These GL calls are special because they need to EGL to retrieve some + * informations before they can execute. + */ + +extern "C" void __glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image); +extern "C" void __glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image); + + +void glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image) +{ + GLeglImageOES implImage = + (GLeglImageOES)egl_get_image_for_current_context((EGLImageKHR)image); + __glEGLImageTargetTexture2DOES(target, implImage); +} + +void glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image) +{ + GLeglImageOES implImage = + (GLeglImageOES)egl_get_image_for_current_context((EGLImageKHR)image); + __glEGLImageTargetRenderbufferStorageOES(target, image); +} + diff --git a/opengl/libs/GLES2/gl2_api.in b/opengl/libs/GLES2/gl2_api.in new file mode 100644 index 0000000000000..9c2e69aea0a32 --- /dev/null +++ b/opengl/libs/GLES2/gl2_api.in @@ -0,0 +1,426 @@ +void API_ENTRY(glActiveTexture)(GLenum texture) { + CALL_GL_API(glActiveTexture, texture); +} +void API_ENTRY(glAttachShader)(GLuint program, GLuint shader) { + CALL_GL_API(glAttachShader, program, shader); +} +void API_ENTRY(glBindAttribLocation)(GLuint program, GLuint index, const char* name) { + CALL_GL_API(glBindAttribLocation, program, index, name); +} +void API_ENTRY(glBindBuffer)(GLenum target, GLuint buffer) { + CALL_GL_API(glBindBuffer, target, buffer); +} +void API_ENTRY(glBindFramebuffer)(GLenum target, GLuint framebuffer) { + CALL_GL_API(glBindFramebuffer, target, framebuffer); +} +void API_ENTRY(glBindRenderbuffer)(GLenum target, GLuint renderbuffer) { + CALL_GL_API(glBindRenderbuffer, target, renderbuffer); +} +void API_ENTRY(glBindTexture)(GLenum target, GLuint texture) { + CALL_GL_API(glBindTexture, target, texture); +} +void API_ENTRY(glBlendColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { + CALL_GL_API(glBlendColor, red, green, blue, alpha); +} +void API_ENTRY(glBlendEquation)( GLenum mode ) { + CALL_GL_API(glBlendEquation, mode); +} +void API_ENTRY(glBlendEquationSeparate)(GLenum modeRGB, GLenum modeAlpha) { + CALL_GL_API(glBlendEquationSeparate, modeRGB, modeAlpha); +} +void API_ENTRY(glBlendFunc)(GLenum sfactor, GLenum dfactor) { + CALL_GL_API(glBlendFunc, sfactor, dfactor); +} +void API_ENTRY(glBlendFuncSeparate)(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) { + CALL_GL_API(glBlendFuncSeparate, srcRGB, dstRGB, srcAlpha, dstAlpha); +} +void API_ENTRY(glBufferData)(GLenum target, GLsizeiptr size, const void* data, GLenum usage) { + CALL_GL_API(glBufferData, target, size, data, usage); +} +void API_ENTRY(glBufferSubData)(GLenum target, GLintptr offset, GLsizeiptr size, const void* data) { + CALL_GL_API(glBufferSubData, target, offset, size, data); +} +GLenum API_ENTRY(glCheckFramebufferStatus)(GLenum target) { + CALL_GL_API_RETURN(glCheckFramebufferStatus, target); +} +void API_ENTRY(glClear)(GLbitfield mask) { + CALL_GL_API(glClear, mask); +} +void API_ENTRY(glClearColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { + CALL_GL_API(glClearColor, red, green, blue, alpha); +} +void API_ENTRY(glClearDepthf)(GLclampf depth) { + CALL_GL_API(glClearDepthf, depth); +} +void API_ENTRY(glClearStencil)(GLint s) { + CALL_GL_API(glClearStencil, s); +} +void API_ENTRY(glColorMask)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) { + CALL_GL_API(glColorMask, red, green, blue, alpha); +} +void API_ENTRY(glCompileShader)(GLuint shader) { + CALL_GL_API(glCompileShader, shader); +} +void API_ENTRY(glCompressedTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data) { + CALL_GL_API(glCompressedTexImage2D, target, level, internalformat, width, height, border, imageSize, data); +} +void API_ENTRY(glCompressedTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data) { + CALL_GL_API(glCompressedTexSubImage2D, target, level, xoffset, yoffset, width, height, format, imageSize, data); +} +void API_ENTRY(glCopyTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) { + CALL_GL_API(glCopyTexImage2D, target, level, internalformat, x, y, width, height, border); +} +void API_ENTRY(glCopyTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) { + CALL_GL_API(glCopyTexSubImage2D, target, level, xoffset, yoffset, x, y, width, height); +} +GLuint API_ENTRY(glCreateProgram)(void) { + CALL_GL_API_RETURN(glCreateProgram); +} +GLuint API_ENTRY(glCreateShader)(GLenum type) { + CALL_GL_API_RETURN(glCreateShader, type); +} +void API_ENTRY(glCullFace)(GLenum mode) { + CALL_GL_API(glCullFace, mode); +} +void API_ENTRY(glDeleteBuffers)(GLsizei n, const GLuint* buffers) { + CALL_GL_API(glDeleteBuffers, n, buffers); +} +void API_ENTRY(glDeleteFramebuffers)(GLsizei n, const GLuint* framebuffers) { + CALL_GL_API(glDeleteFramebuffers, n, framebuffers); +} +void API_ENTRY(glDeleteProgram)(GLuint program) { + CALL_GL_API(glDeleteProgram, program); +} +void API_ENTRY(glDeleteRenderbuffers)(GLsizei n, const GLuint* renderbuffers) { + CALL_GL_API(glDeleteRenderbuffers, n, renderbuffers); +} +void API_ENTRY(glDeleteShader)(GLuint shader) { + CALL_GL_API(glDeleteShader, shader); +} +void API_ENTRY(glDeleteTextures)(GLsizei n, const GLuint* textures) { + CALL_GL_API(glDeleteTextures, n, textures); +} +void API_ENTRY(glDepthFunc)(GLenum func) { + CALL_GL_API(glDepthFunc, func); +} +void API_ENTRY(glDepthMask)(GLboolean flag) { + CALL_GL_API(glDepthMask, flag); +} +void API_ENTRY(glDepthRangef)(GLclampf zNear, GLclampf zFar) { + CALL_GL_API(glDepthRangef, zNear, zFar); +} +void API_ENTRY(glDetachShader)(GLuint program, GLuint shader) { + CALL_GL_API(glDetachShader, program, shader); +} +void API_ENTRY(glDisable)(GLenum cap) { + CALL_GL_API(glDisable, cap); +} +void API_ENTRY(glDisableVertexAttribArray)(GLuint index) { + CALL_GL_API(glDisableVertexAttribArray, index); +} +void API_ENTRY(glDrawArrays)(GLenum mode, GLint first, GLsizei count) { + CALL_GL_API(glDrawArrays, mode, first, count); +} +void API_ENTRY(glDrawElements)(GLenum mode, GLsizei count, GLenum type, const void* indices) { + CALL_GL_API(glDrawElements, mode, count, type, indices); +} +void API_ENTRY(glEnable)(GLenum cap) { + CALL_GL_API(glEnable, cap); +} +void API_ENTRY(glEnableVertexAttribArray)(GLuint index) { + CALL_GL_API(glEnableVertexAttribArray, index); +} +void API_ENTRY(glFinish)(void) { + CALL_GL_API(glFinish); +} +void API_ENTRY(glFlush)(void) { + CALL_GL_API(glFlush); +} +void API_ENTRY(glFramebufferRenderbuffer)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) { + CALL_GL_API(glFramebufferRenderbuffer, target, attachment, renderbuffertarget, renderbuffer); +} +void API_ENTRY(glFramebufferTexture2D)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) { + CALL_GL_API(glFramebufferTexture2D, target, attachment, textarget, texture, level); +} +void API_ENTRY(glFrontFace)(GLenum mode) { + CALL_GL_API(glFrontFace, mode); +} +void API_ENTRY(glGenBuffers)(GLsizei n, GLuint* buffers) { + CALL_GL_API(glGenBuffers, n, buffers); +} +void API_ENTRY(glGenerateMipmap)(GLenum target) { + CALL_GL_API(glGenerateMipmap, target); +} +void API_ENTRY(glGenFramebuffers)(GLsizei n, GLuint* framebuffers) { + CALL_GL_API(glGenFramebuffers, n, framebuffers); +} +void API_ENTRY(glGenRenderbuffers)(GLsizei n, GLuint* renderbuffers) { + CALL_GL_API(glGenRenderbuffers, n, renderbuffers); +} +void API_ENTRY(glGenTextures)(GLsizei n, GLuint* textures) { + CALL_GL_API(glGenTextures, n, textures); +} +void API_ENTRY(glGetActiveAttrib)(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) { + CALL_GL_API(glGetActiveAttrib, program, index, bufsize, length, size, type, name); +} +void API_ENTRY(glGetActiveUniform)(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) { + CALL_GL_API(glGetActiveUniform, program, index, bufsize, length, size, type, name); +} +void API_ENTRY(glGetAttachedShaders)(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) { + CALL_GL_API(glGetAttachedShaders, program, maxcount, count, shaders); +} +int API_ENTRY(glGetAttribLocation)(GLuint program, const char* name) { + CALL_GL_API_RETURN(glGetAttribLocation, program, name); +} +void API_ENTRY(glGetBooleanv)(GLenum pname, GLboolean* params) { + CALL_GL_API(glGetBooleanv, pname, params); +} +void API_ENTRY(glGetBufferParameteriv)(GLenum target, GLenum pname, GLint* params) { + CALL_GL_API(glGetBufferParameteriv, target, pname, params); +} +GLenum API_ENTRY(glGetError)(void) { + CALL_GL_API_RETURN(glGetError); +} +void API_ENTRY(glGetFloatv)(GLenum pname, GLfloat* params) { + CALL_GL_API(glGetFloatv, pname, params); +} +void API_ENTRY(glGetFramebufferAttachmentParameteriv)(GLenum target, GLenum attachment, GLenum pname, GLint* params) { + CALL_GL_API(glGetFramebufferAttachmentParameteriv, target, attachment, pname, params); +} +void API_ENTRY(glGetIntegerv)(GLenum pname, GLint* params) { + CALL_GL_API(glGetIntegerv, pname, params); +} +void API_ENTRY(glGetProgramiv)(GLuint program, GLenum pname, GLint* params) { + CALL_GL_API(glGetProgramiv, program, pname, params); +} +void API_ENTRY(glGetProgramInfoLog)(GLuint program, GLsizei bufsize, GLsizei* length, char* infolog) { + CALL_GL_API(glGetProgramInfoLog, program, bufsize, length, infolog); +} +void API_ENTRY(glGetRenderbufferParameteriv)(GLenum target, GLenum pname, GLint* params) { + CALL_GL_API(glGetRenderbufferParameteriv, target, pname, params); +} +void API_ENTRY(glGetShaderiv)(GLuint shader, GLenum pname, GLint* params) { + CALL_GL_API(glGetShaderiv, shader, pname, params); +} +void API_ENTRY(glGetShaderInfoLog)(GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog) { + CALL_GL_API(glGetShaderInfoLog, shader, bufsize, length, infolog); +} +void API_ENTRY(glGetShaderPrecisionFormat)(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) { + CALL_GL_API(glGetShaderPrecisionFormat, shadertype, precisiontype, range, precision); +} +void API_ENTRY(glGetShaderSource)(GLuint shader, GLsizei bufsize, GLsizei* length, char* source) { + CALL_GL_API(glGetShaderSource, shader, bufsize, length, source); +} +const GLubyte* API_ENTRY(glGetString)(GLenum name) { + CALL_GL_API_RETURN(glGetString, name); +} +void API_ENTRY(glGetTexParameterfv)(GLenum target, GLenum pname, GLfloat* params) { + CALL_GL_API(glGetTexParameterfv, target, pname, params); +} +void API_ENTRY(glGetTexParameteriv)(GLenum target, GLenum pname, GLint* params) { + CALL_GL_API(glGetTexParameteriv, target, pname, params); +} +void API_ENTRY(glGetUniformfv)(GLuint program, GLint location, GLfloat* params) { + CALL_GL_API(glGetUniformfv, program, location, params); +} +void API_ENTRY(glGetUniformiv)(GLuint program, GLint location, GLint* params) { + CALL_GL_API(glGetUniformiv, program, location, params); +} +int API_ENTRY(glGetUniformLocation)(GLuint program, const char* name) { + CALL_GL_API_RETURN(glGetUniformLocation, program, name); +} +void API_ENTRY(glGetVertexAttribfv)(GLuint index, GLenum pname, GLfloat* params) { + CALL_GL_API(glGetVertexAttribfv, index, pname, params); +} +void API_ENTRY(glGetVertexAttribiv)(GLuint index, GLenum pname, GLint* params) { + CALL_GL_API(glGetVertexAttribiv, index, pname, params); +} +void API_ENTRY(glGetVertexAttribPointerv)(GLuint index, GLenum pname, void** pointer) { + CALL_GL_API(glGetVertexAttribPointerv, index, pname, pointer); +} +void API_ENTRY(glHint)(GLenum target, GLenum mode) { + CALL_GL_API(glHint, target, mode); +} +GLboolean API_ENTRY(glIsBuffer)(GLuint buffer) { + CALL_GL_API_RETURN(glIsBuffer, buffer); +} +GLboolean API_ENTRY(glIsEnabled)(GLenum cap) { + CALL_GL_API_RETURN(glIsEnabled, cap); +} +GLboolean API_ENTRY(glIsFramebuffer)(GLuint framebuffer) { + CALL_GL_API_RETURN(glIsFramebuffer, framebuffer); +} +GLboolean API_ENTRY(glIsProgram)(GLuint program) { + CALL_GL_API_RETURN(glIsProgram, program); +} +GLboolean API_ENTRY(glIsRenderbuffer)(GLuint renderbuffer) { + CALL_GL_API_RETURN(glIsRenderbuffer, renderbuffer); +} +GLboolean API_ENTRY(glIsShader)(GLuint shader) { + CALL_GL_API_RETURN(glIsShader, shader); +} +GLboolean API_ENTRY(glIsTexture)(GLuint texture) { + CALL_GL_API_RETURN(glIsTexture, texture); +} +void API_ENTRY(glLineWidth)(GLfloat width) { + CALL_GL_API(glLineWidth, width); +} +void API_ENTRY(glLinkProgram)(GLuint program) { + CALL_GL_API(glLinkProgram, program); +} +void API_ENTRY(glPixelStorei)(GLenum pname, GLint param) { + CALL_GL_API(glPixelStorei, pname, param); +} +void API_ENTRY(glPolygonOffset)(GLfloat factor, GLfloat units) { + CALL_GL_API(glPolygonOffset, factor, units); +} +void API_ENTRY(glReadPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) { + CALL_GL_API(glReadPixels, x, y, width, height, format, type, pixels); +} +void API_ENTRY(glReleaseShaderCompiler)(void) { + CALL_GL_API(glReleaseShaderCompiler); +} +void API_ENTRY(glRenderbufferStorage)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) { + CALL_GL_API(glRenderbufferStorage, target, internalformat, width, height); +} +void API_ENTRY(glSampleCoverage)(GLclampf value, GLboolean invert) { + CALL_GL_API(glSampleCoverage, value, invert); +} +void API_ENTRY(glScissor)(GLint x, GLint y, GLsizei width, GLsizei height) { + CALL_GL_API(glScissor, x, y, width, height); +} +void API_ENTRY(glShaderBinary)(GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length) { + CALL_GL_API(glShaderBinary, n, shaders, binaryformat, binary, length); +} +void API_ENTRY(glShaderSource)(GLuint shader, GLsizei count, const char** string, const GLint* length) { + CALL_GL_API(glShaderSource, shader, count, string, length); +} +void API_ENTRY(glStencilFunc)(GLenum func, GLint ref, GLuint mask) { + CALL_GL_API(glStencilFunc, func, ref, mask); +} +void API_ENTRY(glStencilFuncSeparate)(GLenum face, GLenum func, GLint ref, GLuint mask) { + CALL_GL_API(glStencilFuncSeparate, face, func, ref, mask); +} +void API_ENTRY(glStencilMask)(GLuint mask) { + CALL_GL_API(glStencilMask, mask); +} +void API_ENTRY(glStencilMaskSeparate)(GLenum face, GLuint mask) { + CALL_GL_API(glStencilMaskSeparate, face, mask); +} +void API_ENTRY(glStencilOp)(GLenum fail, GLenum zfail, GLenum zpass) { + CALL_GL_API(glStencilOp, fail, zfail, zpass); +} +void API_ENTRY(glStencilOpSeparate)(GLenum face, GLenum fail, GLenum zfail, GLenum zpass) { + CALL_GL_API(glStencilOpSeparate, face, fail, zfail, zpass); +} +void API_ENTRY(glTexImage2D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels) { + CALL_GL_API(glTexImage2D, target, level, internalformat, width, height, border, format, type, pixels); +} +void API_ENTRY(glTexParameterf)(GLenum target, GLenum pname, GLfloat param) { + CALL_GL_API(glTexParameterf, target, pname, param); +} +void API_ENTRY(glTexParameterfv)(GLenum target, GLenum pname, const GLfloat* params) { + CALL_GL_API(glTexParameterfv, target, pname, params); +} +void API_ENTRY(glTexParameteri)(GLenum target, GLenum pname, GLint param) { + CALL_GL_API(glTexParameteri, target, pname, param); +} +void API_ENTRY(glTexParameteriv)(GLenum target, GLenum pname, const GLint* params) { + CALL_GL_API(glTexParameteriv, target, pname, params); +} +void API_ENTRY(glTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels) { + CALL_GL_API(glTexSubImage2D, target, level, xoffset, yoffset, width, height, format, type, pixels); +} +void API_ENTRY(glUniform1f)(GLint location, GLfloat x) { + CALL_GL_API(glUniform1f, location, x); +} +void API_ENTRY(glUniform1fv)(GLint location, GLsizei count, const GLfloat* v) { + CALL_GL_API(glUniform1fv, location, count, v); +} +void API_ENTRY(glUniform1i)(GLint location, GLint x) { + CALL_GL_API(glUniform1i, location, x); +} +void API_ENTRY(glUniform1iv)(GLint location, GLsizei count, const GLint* v) { + CALL_GL_API(glUniform1iv, location, count, v); +} +void API_ENTRY(glUniform2f)(GLint location, GLfloat x, GLfloat y) { + CALL_GL_API(glUniform2f, location, x, y); +} +void API_ENTRY(glUniform2fv)(GLint location, GLsizei count, const GLfloat* v) { + CALL_GL_API(glUniform2fv, location, count, v); +} +void API_ENTRY(glUniform2i)(GLint location, GLint x, GLint y) { + CALL_GL_API(glUniform2i, location, x, y); +} +void API_ENTRY(glUniform2iv)(GLint location, GLsizei count, const GLint* v) { + CALL_GL_API(glUniform2iv, location, count, v); +} +void API_ENTRY(glUniform3f)(GLint location, GLfloat x, GLfloat y, GLfloat z) { + CALL_GL_API(glUniform3f, location, x, y, z); +} +void API_ENTRY(glUniform3fv)(GLint location, GLsizei count, const GLfloat* v) { + CALL_GL_API(glUniform3fv, location, count, v); +} +void API_ENTRY(glUniform3i)(GLint location, GLint x, GLint y, GLint z) { + CALL_GL_API(glUniform3i, location, x, y, z); +} +void API_ENTRY(glUniform3iv)(GLint location, GLsizei count, const GLint* v) { + CALL_GL_API(glUniform3iv, location, count, v); +} +void API_ENTRY(glUniform4f)(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { + CALL_GL_API(glUniform4f, location, x, y, z, w); +} +void API_ENTRY(glUniform4fv)(GLint location, GLsizei count, const GLfloat* v) { + CALL_GL_API(glUniform4fv, location, count, v); +} +void API_ENTRY(glUniform4i)(GLint location, GLint x, GLint y, GLint z, GLint w) { + CALL_GL_API(glUniform4i, location, x, y, z, w); +} +void API_ENTRY(glUniform4iv)(GLint location, GLsizei count, const GLint* v) { + CALL_GL_API(glUniform4iv, location, count, v); +} +void API_ENTRY(glUniformMatrix2fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { + CALL_GL_API(glUniformMatrix2fv, location, count, transpose, value); +} +void API_ENTRY(glUniformMatrix3fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { + CALL_GL_API(glUniformMatrix3fv, location, count, transpose, value); +} +void API_ENTRY(glUniformMatrix4fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { + CALL_GL_API(glUniformMatrix4fv, location, count, transpose, value); +} +void API_ENTRY(glUseProgram)(GLuint program) { + CALL_GL_API(glUseProgram, program); +} +void API_ENTRY(glValidateProgram)(GLuint program) { + CALL_GL_API(glValidateProgram, program); +} +void API_ENTRY(glVertexAttrib1f)(GLuint indx, GLfloat x) { + CALL_GL_API(glVertexAttrib1f, indx, x); +} +void API_ENTRY(glVertexAttrib1fv)(GLuint indx, const GLfloat* values) { + CALL_GL_API(glVertexAttrib1fv, indx, values); +} +void API_ENTRY(glVertexAttrib2f)(GLuint indx, GLfloat x, GLfloat y) { + CALL_GL_API(glVertexAttrib2f, indx, x, y); +} +void API_ENTRY(glVertexAttrib2fv)(GLuint indx, const GLfloat* values) { + CALL_GL_API(glVertexAttrib2fv, indx, values); +} +void API_ENTRY(glVertexAttrib3f)(GLuint indx, GLfloat x, GLfloat y, GLfloat z) { + CALL_GL_API(glVertexAttrib3f, indx, x, y, z); +} +void API_ENTRY(glVertexAttrib3fv)(GLuint indx, const GLfloat* values) { + CALL_GL_API(glVertexAttrib3fv, indx, values); +} +void API_ENTRY(glVertexAttrib4f)(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { + CALL_GL_API(glVertexAttrib4f, indx, x, y, z, w); +} +void API_ENTRY(glVertexAttrib4fv)(GLuint indx, const GLfloat* values) { + CALL_GL_API(glVertexAttrib4fv, indx, values); +} +void API_ENTRY(glVertexAttribPointer)(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr) { + CALL_GL_API(glVertexAttribPointer, indx, size, type, normalized, stride, ptr); +} +void API_ENTRY(glViewport)(GLint x, GLint y, GLsizei width, GLsizei height) { + CALL_GL_API(glViewport, x, y, width, height); +} diff --git a/opengl/libs/GLES2/gl2_entries.in b/opengl/libs/GLES2/gl2_entries.in new file mode 100644 index 0000000000000..6a41b94fc6e1d --- /dev/null +++ b/opengl/libs/GLES2/gl2_entries.in @@ -0,0 +1,142 @@ +GL_ENTRY(void, glActiveTexture, GLenum texture) +GL_ENTRY(void, glAttachShader, GLuint program, GLuint shader) +GL_ENTRY(void, glBindAttribLocation, GLuint program, GLuint index, const char* name) +GL_ENTRY(void, glBindBuffer, GLenum target, GLuint buffer) +GL_ENTRY(void, glBindFramebuffer, GLenum target, GLuint framebuffer) +GL_ENTRY(void, glBindRenderbuffer, GLenum target, GLuint renderbuffer) +GL_ENTRY(void, glBindTexture, GLenum target, GLuint texture) +GL_ENTRY(void, glBlendColor, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) +GL_ENTRY(void, glBlendEquation, GLenum mode ) +GL_ENTRY(void, glBlendEquationSeparate, GLenum modeRGB, GLenum modeAlpha) +GL_ENTRY(void, glBlendFunc, GLenum sfactor, GLenum dfactor) +GL_ENTRY(void, glBlendFuncSeparate, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) +GL_ENTRY(void, glBufferData, GLenum target, GLsizeiptr size, const void* data, GLenum usage) +GL_ENTRY(void, glBufferSubData, GLenum target, GLintptr offset, GLsizeiptr size, const void* data) +GL_ENTRY(GLenum, glCheckFramebufferStatus, GLenum target) +GL_ENTRY(void, glClear, GLbitfield mask) +GL_ENTRY(void, glClearColor, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) +GL_ENTRY(void, glClearDepthf, GLclampf depth) +GL_ENTRY(void, glClearStencil, GLint s) +GL_ENTRY(void, glColorMask, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) +GL_ENTRY(void, glCompileShader, GLuint shader) +GL_ENTRY(void, glCompressedTexImage2D, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data) +GL_ENTRY(void, glCompressedTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data) +GL_ENTRY(void, glCopyTexImage2D, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) +GL_ENTRY(void, glCopyTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) +GL_ENTRY(GLuint, glCreateProgram, void) +GL_ENTRY(GLuint, glCreateShader, GLenum type) +GL_ENTRY(void, glCullFace, GLenum mode) +GL_ENTRY(void, glDeleteBuffers, GLsizei n, const GLuint* buffers) +GL_ENTRY(void, glDeleteFramebuffers, GLsizei n, const GLuint* framebuffers) +GL_ENTRY(void, glDeleteProgram, GLuint program) +GL_ENTRY(void, glDeleteRenderbuffers, GLsizei n, const GLuint* renderbuffers) +GL_ENTRY(void, glDeleteShader, GLuint shader) +GL_ENTRY(void, glDeleteTextures, GLsizei n, const GLuint* textures) +GL_ENTRY(void, glDepthFunc, GLenum func) +GL_ENTRY(void, glDepthMask, GLboolean flag) +GL_ENTRY(void, glDepthRangef, GLclampf zNear, GLclampf zFar) +GL_ENTRY(void, glDetachShader, GLuint program, GLuint shader) +GL_ENTRY(void, glDisable, GLenum cap) +GL_ENTRY(void, glDisableVertexAttribArray, GLuint index) +GL_ENTRY(void, glDrawArrays, GLenum mode, GLint first, GLsizei count) +GL_ENTRY(void, glDrawElements, GLenum mode, GLsizei count, GLenum type, const void* indices) +GL_ENTRY(void, glEnable, GLenum cap) +GL_ENTRY(void, glEnableVertexAttribArray, GLuint index) +GL_ENTRY(void, glFinish, void) +GL_ENTRY(void, glFlush, void) +GL_ENTRY(void, glFramebufferRenderbuffer, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) +GL_ENTRY(void, glFramebufferTexture2D, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) +GL_ENTRY(void, glFrontFace, GLenum mode) +GL_ENTRY(void, glGenBuffers, GLsizei n, GLuint* buffers) +GL_ENTRY(void, glGenerateMipmap, GLenum target) +GL_ENTRY(void, glGenFramebuffers, GLsizei n, GLuint* framebuffers) +GL_ENTRY(void, glGenRenderbuffers, GLsizei n, GLuint* renderbuffers) +GL_ENTRY(void, glGenTextures, GLsizei n, GLuint* textures) +GL_ENTRY(void, glGetActiveAttrib, GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) +GL_ENTRY(void, glGetActiveUniform, GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) +GL_ENTRY(void, glGetAttachedShaders, GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) +GL_ENTRY(int, glGetAttribLocation, GLuint program, const char* name) +GL_ENTRY(void, glGetBooleanv, GLenum pname, GLboolean* params) +GL_ENTRY(void, glGetBufferParameteriv, GLenum target, GLenum pname, GLint* params) +GL_ENTRY(GLenum, glGetError, void) +GL_ENTRY(void, glGetFloatv, GLenum pname, GLfloat* params) +GL_ENTRY(void, glGetFramebufferAttachmentParameteriv, GLenum target, GLenum attachment, GLenum pname, GLint* params) +GL_ENTRY(void, glGetIntegerv, GLenum pname, GLint* params) +GL_ENTRY(void, glGetProgramiv, GLuint program, GLenum pname, GLint* params) +GL_ENTRY(void, glGetProgramInfoLog, GLuint program, GLsizei bufsize, GLsizei* length, char* infolog) +GL_ENTRY(void, glGetRenderbufferParameteriv, GLenum target, GLenum pname, GLint* params) +GL_ENTRY(void, glGetShaderiv, GLuint shader, GLenum pname, GLint* params) +GL_ENTRY(void, glGetShaderInfoLog, GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog) +GL_ENTRY(void, glGetShaderPrecisionFormat, GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) +GL_ENTRY(void, glGetShaderSource, GLuint shader, GLsizei bufsize, GLsizei* length, char* source) +GL_ENTRY(const GLubyte*, glGetString, GLenum name) +GL_ENTRY(void, glGetTexParameterfv, GLenum target, GLenum pname, GLfloat* params) +GL_ENTRY(void, glGetTexParameteriv, GLenum target, GLenum pname, GLint* params) +GL_ENTRY(void, glGetUniformfv, GLuint program, GLint location, GLfloat* params) +GL_ENTRY(void, glGetUniformiv, GLuint program, GLint location, GLint* params) +GL_ENTRY(int, glGetUniformLocation, GLuint program, const char* name) +GL_ENTRY(void, glGetVertexAttribfv, GLuint index, GLenum pname, GLfloat* params) +GL_ENTRY(void, glGetVertexAttribiv, GLuint index, GLenum pname, GLint* params) +GL_ENTRY(void, glGetVertexAttribPointerv, GLuint index, GLenum pname, void** pointer) +GL_ENTRY(void, glHint, GLenum target, GLenum mode) +GL_ENTRY(GLboolean, glIsBuffer, GLuint buffer) +GL_ENTRY(GLboolean, glIsEnabled, GLenum cap) +GL_ENTRY(GLboolean, glIsFramebuffer, GLuint framebuffer) +GL_ENTRY(GLboolean, glIsProgram, GLuint program) +GL_ENTRY(GLboolean, glIsRenderbuffer, GLuint renderbuffer) +GL_ENTRY(GLboolean, glIsShader, GLuint shader) +GL_ENTRY(GLboolean, glIsTexture, GLuint texture) +GL_ENTRY(void, glLineWidth, GLfloat width) +GL_ENTRY(void, glLinkProgram, GLuint program) +GL_ENTRY(void, glPixelStorei, GLenum pname, GLint param) +GL_ENTRY(void, glPolygonOffset, GLfloat factor, GLfloat units) +GL_ENTRY(void, glReadPixels, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) +GL_ENTRY(void, glReleaseShaderCompiler, void) +GL_ENTRY(void, glRenderbufferStorage, GLenum target, GLenum internalformat, GLsizei width, GLsizei height) +GL_ENTRY(void, glSampleCoverage, GLclampf value, GLboolean invert) +GL_ENTRY(void, glScissor, GLint x, GLint y, GLsizei width, GLsizei height) +GL_ENTRY(void, glShaderBinary, GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length) +GL_ENTRY(void, glShaderSource, GLuint shader, GLsizei count, const char** string, const GLint* length) +GL_ENTRY(void, glStencilFunc, GLenum func, GLint ref, GLuint mask) +GL_ENTRY(void, glStencilFuncSeparate, GLenum face, GLenum func, GLint ref, GLuint mask) +GL_ENTRY(void, glStencilMask, GLuint mask) +GL_ENTRY(void, glStencilMaskSeparate, GLenum face, GLuint mask) +GL_ENTRY(void, glStencilOp, GLenum fail, GLenum zfail, GLenum zpass) +GL_ENTRY(void, glStencilOpSeparate, GLenum face, GLenum fail, GLenum zfail, GLenum zpass) +GL_ENTRY(void, glTexImage2D, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels) +GL_ENTRY(void, glTexParameterf, GLenum target, GLenum pname, GLfloat param) +GL_ENTRY(void, glTexParameterfv, GLenum target, GLenum pname, const GLfloat* params) +GL_ENTRY(void, glTexParameteri, GLenum target, GLenum pname, GLint param) +GL_ENTRY(void, glTexParameteriv, GLenum target, GLenum pname, const GLint* params) +GL_ENTRY(void, glTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels) +GL_ENTRY(void, glUniform1f, GLint location, GLfloat x) +GL_ENTRY(void, glUniform1fv, GLint location, GLsizei count, const GLfloat* v) +GL_ENTRY(void, glUniform1i, GLint location, GLint x) +GL_ENTRY(void, glUniform1iv, GLint location, GLsizei count, const GLint* v) +GL_ENTRY(void, glUniform2f, GLint location, GLfloat x, GLfloat y) +GL_ENTRY(void, glUniform2fv, GLint location, GLsizei count, const GLfloat* v) +GL_ENTRY(void, glUniform2i, GLint location, GLint x, GLint y) +GL_ENTRY(void, glUniform2iv, GLint location, GLsizei count, const GLint* v) +GL_ENTRY(void, glUniform3f, GLint location, GLfloat x, GLfloat y, GLfloat z) +GL_ENTRY(void, glUniform3fv, GLint location, GLsizei count, const GLfloat* v) +GL_ENTRY(void, glUniform3i, GLint location, GLint x, GLint y, GLint z) +GL_ENTRY(void, glUniform3iv, GLint location, GLsizei count, const GLint* v) +GL_ENTRY(void, glUniform4f, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) +GL_ENTRY(void, glUniform4fv, GLint location, GLsizei count, const GLfloat* v) +GL_ENTRY(void, glUniform4i, GLint location, GLint x, GLint y, GLint z, GLint w) +GL_ENTRY(void, glUniform4iv, GLint location, GLsizei count, const GLint* v) +GL_ENTRY(void, glUniformMatrix2fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +GL_ENTRY(void, glUniformMatrix3fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +GL_ENTRY(void, glUniformMatrix4fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +GL_ENTRY(void, glUseProgram, GLuint program) +GL_ENTRY(void, glValidateProgram, GLuint program) +GL_ENTRY(void, glVertexAttrib1f, GLuint indx, GLfloat x) +GL_ENTRY(void, glVertexAttrib1fv, GLuint indx, const GLfloat* values) +GL_ENTRY(void, glVertexAttrib2f, GLuint indx, GLfloat x, GLfloat y) +GL_ENTRY(void, glVertexAttrib2fv, GLuint indx, const GLfloat* values) +GL_ENTRY(void, glVertexAttrib3f, GLuint indx, GLfloat x, GLfloat y, GLfloat z) +GL_ENTRY(void, glVertexAttrib3fv, GLuint indx, const GLfloat* values) +GL_ENTRY(void, glVertexAttrib4f, GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w) +GL_ENTRY(void, glVertexAttrib4fv, GLuint indx, const GLfloat* values) +GL_ENTRY(void, glVertexAttribPointer, GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr) +GL_ENTRY(void, glViewport, GLint x, GLint y, GLsizei width, GLsizei height) diff --git a/opengl/libs/GLES2/gl2ext_api.in b/opengl/libs/GLES2/gl2ext_api.in new file mode 100644 index 0000000000000..6eeecb33dc192 --- /dev/null +++ b/opengl/libs/GLES2/gl2ext_api.in @@ -0,0 +1,105 @@ +void API_ENTRY(__glEGLImageTargetTexture2DOES)(GLenum target, GLeglImageOES image) { + CALL_GL_API(glEGLImageTargetTexture2DOES, target, image); +} +void API_ENTRY(__glEGLImageTargetRenderbufferStorageOES)(GLenum target, GLeglImageOES image) { + CALL_GL_API(glEGLImageTargetRenderbufferStorageOES, target, image); +} +void API_ENTRY(glGetProgramBinaryOES)(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary) { + CALL_GL_API(glGetProgramBinaryOES, program, bufSize, length, binaryFormat, binary); +} +void API_ENTRY(glProgramBinaryOES)(GLuint program, GLenum binaryFormat, const void *binary, GLint length) { + CALL_GL_API(glProgramBinaryOES, program, binaryFormat, binary, length); +} +void* API_ENTRY(glMapBufferOES)(GLenum target, GLenum access) { + CALL_GL_API_RETURN(glMapBufferOES, target, access); +} +GLboolean API_ENTRY(glUnmapBufferOES)(GLenum target) { + CALL_GL_API_RETURN(glUnmapBufferOES, target); +} +void API_ENTRY(glGetBufferPointervOES)(GLenum target, GLenum pname, void** params) { + CALL_GL_API(glGetBufferPointervOES, target, pname, params); +} +void API_ENTRY(glTexImage3DOES)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels) { + CALL_GL_API(glTexImage3DOES, target, level, internalformat, width, height, depth, border, format, type, pixels); +} +void API_ENTRY(glTexSubImage3DOES)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels) { + CALL_GL_API(glTexSubImage3DOES, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); +} +void API_ENTRY(glCopyTexSubImage3DOES)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) { + CALL_GL_API(glCopyTexSubImage3DOES, target, level, xoffset, yoffset, zoffset, x, y, width, height); +} +void API_ENTRY(glCompressedTexImage3DOES)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data) { + CALL_GL_API(glCompressedTexImage3DOES, target, level, internalformat, width, height, depth, border, imageSize, data); +} +void API_ENTRY(glCompressedTexSubImage3DOES)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data) { + CALL_GL_API(glCompressedTexSubImage3DOES, target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data); +} +void API_ENTRY(glFramebufferTexture3DOES)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset) { + CALL_GL_API(glFramebufferTexture3DOES, target, attachment, textarget, texture, level, zoffset); +} +void API_ENTRY(glGetPerfMonitorGroupsAMD)(GLint *numGroups, GLsizei groupsSize, GLuint *groups) { + CALL_GL_API(glGetPerfMonitorGroupsAMD, numGroups, groupsSize, groups); +} +void API_ENTRY(glGetPerfMonitorCountersAMD)(GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters) { + CALL_GL_API(glGetPerfMonitorCountersAMD, group, numCounters, maxActiveCounters, counterSize, counters); +} +void API_ENTRY(glGetPerfMonitorGroupStringAMD)(GLuint group, GLsizei bufSize, GLsizei *length, char *groupString) { + CALL_GL_API(glGetPerfMonitorGroupStringAMD, group, bufSize, length, groupString); +} +void API_ENTRY(glGetPerfMonitorCounterStringAMD)(GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, char *counterString) { + CALL_GL_API(glGetPerfMonitorCounterStringAMD, group, counter, bufSize, length, counterString); +} +void API_ENTRY(glGetPerfMonitorCounterInfoAMD)(GLuint group, GLuint counter, GLenum pname, void *data) { + CALL_GL_API(glGetPerfMonitorCounterInfoAMD, group, counter, pname, data); +} +void API_ENTRY(glGenPerfMonitorsAMD)(GLsizei n, GLuint *monitors) { + CALL_GL_API(glGenPerfMonitorsAMD, n, monitors); +} +void API_ENTRY(glDeletePerfMonitorsAMD)(GLsizei n, GLuint *monitors) { + CALL_GL_API(glDeletePerfMonitorsAMD, n, monitors); +} +void API_ENTRY(glSelectPerfMonitorCountersAMD)(GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *countersList) { + CALL_GL_API(glSelectPerfMonitorCountersAMD, monitor, enable, group, numCounters, countersList); +} +void API_ENTRY(glBeginPerfMonitorAMD)(GLuint monitor) { + CALL_GL_API(glBeginPerfMonitorAMD, monitor); +} +void API_ENTRY(glEndPerfMonitorAMD)(GLuint monitor) { + CALL_GL_API(glEndPerfMonitorAMD, monitor); +} +void API_ENTRY(glGetPerfMonitorCounterDataAMD)(GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten) { + CALL_GL_API(glGetPerfMonitorCounterDataAMD, monitor, pname, dataSize, data, bytesWritten); +} +void API_ENTRY(glDeleteFencesNV)(GLsizei n, const GLuint *fences) { + CALL_GL_API(glDeleteFencesNV, n, fences); +} +void API_ENTRY(glGenFencesNV)(GLsizei n, GLuint *fences) { + CALL_GL_API(glGenFencesNV, n, fences); +} +GLboolean API_ENTRY(glIsFenceNV)(GLuint fence) { + CALL_GL_API_RETURN(glIsFenceNV, fence); +} +GLboolean API_ENTRY(glTestFenceNV)(GLuint fence) { + CALL_GL_API_RETURN(glTestFenceNV, fence); +} +void API_ENTRY(glGetFenceivNV)(GLuint fence, GLenum pname, GLint *params) { + CALL_GL_API(glGetFenceivNV, fence, pname, params); +} +void API_ENTRY(glFinishFenceNV)(GLuint fence) { + CALL_GL_API(glFinishFenceNV, fence); +} +void API_ENTRY(glSetFenceNV)(GLuint fence, GLenum condition) { + CALL_GL_API(glSetFenceNV, fence, condition); +} +void API_ENTRY(glGetDriverControlsQCOM)(GLint *num, GLsizei size, GLuint *driverControls) { + CALL_GL_API(glGetDriverControlsQCOM, num, size, driverControls); +} +void API_ENTRY(glGetDriverControlStringQCOM)(GLuint driverControl, GLsizei bufSize, GLsizei *length, char *driverControlString) { + CALL_GL_API(glGetDriverControlStringQCOM, driverControl, bufSize, length, driverControlString); +} +void API_ENTRY(glEnableDriverControlQCOM)(GLuint driverControl) { + CALL_GL_API(glEnableDriverControlQCOM, driverControl); +} +void API_ENTRY(glDisableDriverControlQCOM)(GLuint driverControl) { + CALL_GL_API(glDisableDriverControlQCOM, driverControl); +} diff --git a/opengl/libs/GLES2/gl2ext_entries.in b/opengl/libs/GLES2/gl2ext_entries.in new file mode 100644 index 0000000000000..e608f5d33668e --- /dev/null +++ b/opengl/libs/GLES2/gl2ext_entries.in @@ -0,0 +1,35 @@ +GL_ENTRY(void, glEGLImageTargetTexture2DOES, GLenum target, GLeglImageOES image) +GL_ENTRY(void, glEGLImageTargetRenderbufferStorageOES, GLenum target, GLeglImageOES image) +GL_ENTRY(void, glGetProgramBinaryOES, GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary) +GL_ENTRY(void, glProgramBinaryOES, GLuint program, GLenum binaryFormat, const void *binary, GLint length) +GL_ENTRY(void*, glMapBufferOES, GLenum target, GLenum access) +GL_ENTRY(GLboolean, glUnmapBufferOES, GLenum target) +GL_ENTRY(void, glGetBufferPointervOES, GLenum target, GLenum pname, void** params) +GL_ENTRY(void, glTexImage3DOES, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels) +GL_ENTRY(void, glTexSubImage3DOES, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels) +GL_ENTRY(void, glCopyTexSubImage3DOES, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) +GL_ENTRY(void, glCompressedTexImage3DOES, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data) +GL_ENTRY(void, glCompressedTexSubImage3DOES, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data) +GL_ENTRY(void, glFramebufferTexture3DOES, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset) +GL_ENTRY(void, glGetPerfMonitorGroupsAMD, GLint *numGroups, GLsizei groupsSize, GLuint *groups) +GL_ENTRY(void, glGetPerfMonitorCountersAMD, GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters) +GL_ENTRY(void, glGetPerfMonitorGroupStringAMD, GLuint group, GLsizei bufSize, GLsizei *length, char *groupString) +GL_ENTRY(void, glGetPerfMonitorCounterStringAMD, GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, char *counterString) +GL_ENTRY(void, glGetPerfMonitorCounterInfoAMD, GLuint group, GLuint counter, GLenum pname, void *data) +GL_ENTRY(void, glGenPerfMonitorsAMD, GLsizei n, GLuint *monitors) +GL_ENTRY(void, glDeletePerfMonitorsAMD, GLsizei n, GLuint *monitors) +GL_ENTRY(void, glSelectPerfMonitorCountersAMD, GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *countersList) +GL_ENTRY(void, glBeginPerfMonitorAMD, GLuint monitor) +GL_ENTRY(void, glEndPerfMonitorAMD, GLuint monitor) +GL_ENTRY(void, glGetPerfMonitorCounterDataAMD, GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten) +GL_ENTRY(void, glDeleteFencesNV, GLsizei n, const GLuint *fences) +GL_ENTRY(void, glGenFencesNV, GLsizei n, GLuint *fences) +GL_ENTRY(GLboolean, glIsFenceNV, GLuint fence) +GL_ENTRY(GLboolean, glTestFenceNV, GLuint fence) +GL_ENTRY(void, glGetFenceivNV, GLuint fence, GLenum pname, GLint *params) +GL_ENTRY(void, glFinishFenceNV, GLuint fence) +GL_ENTRY(void, glSetFenceNV, GLuint fence, GLenum condition) +GL_ENTRY(void, glGetDriverControlsQCOM, GLint *num, GLsizei size, GLuint *driverControls) +GL_ENTRY(void, glGetDriverControlStringQCOM, GLuint driverControl, GLsizei bufSize, GLsizei *length, char *driverControlString) +GL_ENTRY(void, glEnableDriverControlQCOM, GLuint driverControl) +GL_ENTRY(void, glDisableDriverControlQCOM, GLuint driverControl) diff --git a/opengl/libs/gl_entries.in b/opengl/libs/GLES_CM/gl_entries.in similarity index 100% rename from opengl/libs/gl_entries.in rename to opengl/libs/GLES_CM/gl_entries.in diff --git a/opengl/libs/glext_entries.in b/opengl/libs/GLES_CM/glext_entries.in similarity index 100% rename from opengl/libs/glext_entries.in rename to opengl/libs/GLES_CM/glext_entries.in diff --git a/opengl/libs/gl_enums.in b/opengl/libs/gl_enums.in deleted file mode 100644 index ffc2fad4302da..0000000000000 --- a/opengl/libs/gl_enums.in +++ /dev/null @@ -1,261 +0,0 @@ -GLENUM(GL_POINTS, 0x0000) -GLENUM(GL_LINES, 0x0001) -GLENUM(GL_LINE_LOOP, 0x0002) -GLENUM(GL_LINE_STRIP, 0x0003) -GLENUM(GL_TRIANGLES, 0x0004) -GLENUM(GL_TRIANGLE_STRIP, 0x0005) -GLENUM(GL_TRIANGLE_FAN, 0x0006) -GLENUM(GL_ADD, 0x0104) -GLENUM(GL_NEVER, 0x0200) -GLENUM(GL_LESS, 0x0201) -GLENUM(GL_EQUAL, 0x0202) -GLENUM(GL_LEQUAL, 0x0203) -GLENUM(GL_GREATER, 0x0204) -GLENUM(GL_NOTEQUAL, 0x0205) -GLENUM(GL_GEQUAL, 0x0206) -GLENUM(GL_ALWAYS, 0x0207) -GLENUM(GL_SRC_COLOR, 0x0300) -GLENUM(GL_ONE_MINUS_SRC_COLOR, 0x0301) -GLENUM(GL_SRC_ALPHA, 0x0302) -GLENUM(GL_ONE_MINUS_SRC_ALPHA, 0x0303) -GLENUM(GL_DST_ALPHA, 0x0304) -GLENUM(GL_ONE_MINUS_DST_ALPHA, 0x0305) -GLENUM(GL_DST_COLOR, 0x0306) -GLENUM(GL_ONE_MINUS_DST_COLOR, 0x0307) -GLENUM(GL_SRC_ALPHA_SATURATE, 0x0308) -GLENUM(GL_FRONT, 0x0404) -GLENUM(GL_BACK, 0x0405) -GLENUM(GL_FRONT_AND_BACK, 0x0408) -GLENUM(GL_INVALID_ENUM, 0x0500) -GLENUM(GL_INVALID_VALUE, 0x0501) -GLENUM(GL_INVALID_OPERATION, 0x0502) -GLENUM(GL_STACK_OVERFLOW, 0x0503) -GLENUM(GL_STACK_UNDERFLOW, 0x0504) -GLENUM(GL_OUT_OF_MEMORY, 0x0505) -GLENUM(GL_EXP, 0x0800) -GLENUM(GL_EXP2, 0x0801) -GLENUM(GL_CW, 0x0900) -GLENUM(GL_CCW, 0x0901) -GLENUM(GL_POINT_SMOOTH, 0x0B10) -GLENUM(GL_SMOOTH_POINT_SIZE_RANGE, 0x0B12) -GLENUM(GL_LINE_SMOOTH, 0x0B20) -GLENUM(GL_SMOOTH_LINE_WIDTH_RANGE, 0x0B22) -GLENUM(GL_CULL_FACE, 0x0B44) -GLENUM(GL_LIGHTING, 0x0B50) -GLENUM(GL_LIGHT_MODEL_TWO_SIDE, 0x0B52) -GLENUM(GL_LIGHT_MODEL_AMBIENT, 0x0B53) -GLENUM(GL_COLOR_MATERIAL, 0x0B57) -GLENUM(GL_FOG, 0x0B60) -GLENUM(GL_FOG_DENSITY, 0x0B62) -GLENUM(GL_FOG_START, 0x0B63) -GLENUM(GL_FOG_END, 0x0B64) -GLENUM(GL_FOG_MODE, 0x0B65) -GLENUM(GL_FOG_COLOR, 0x0B66) -GLENUM(GL_DEPTH_TEST, 0x0B71) -GLENUM(GL_STENCIL_TEST, 0x0B90) -GLENUM(GL_NORMALIZE, 0x0BA1) -GLENUM(GL_ALPHA_TEST, 0x0BC0) -GLENUM(GL_DITHER, 0x0BD0) -GLENUM(GL_BLEND, 0x0BE2) -GLENUM(GL_COLOR_LOGIC_OP, 0x0BF2) -GLENUM(GL_SCISSOR_TEST, 0x0C11) -GLENUM(GL_PERSPECTIVE_CORRECTION_HINT, 0x0C50) -GLENUM(GL_POINT_SMOOTH_HINT, 0x0C51) -GLENUM(GL_LINE_SMOOTH_HINT, 0x0C52) -GLENUM(GL_POLYGON_SMOOTH_HINT, 0x0C53) -GLENUM(GL_FOG_HINT, 0x0C54) -GLENUM(GL_UNPACK_ALIGNMENT, 0x0CF5) -GLENUM(GL_PACK_ALIGNMENT, 0x0D05) -GLENUM(GL_MAX_LIGHTS, 0x0D31) -GLENUM(GL_MAX_CLIP_PLANES, 0x0D32) -GLENUM(GL_MAX_TEXTURE_SIZE, 0x0D33) -GLENUM(GL_MAX_MODELVIEW_STACK_DEPTH, 0x0D36) -GLENUM(GL_MAX_PROJECTION_STACK_DEPTH, 0x0D38) -GLENUM(GL_MAX_TEXTURE_STACK_DEPTH, 0x0D39) -GLENUM(GL_MAX_VIEWPORT_DIMS, 0x0D3A) -GLENUM(GL_RED_BITS, 0x0D52) -GLENUM(GL_GREEN_BITS, 0x0D53) -GLENUM(GL_BLUE_BITS, 0x0D54) -GLENUM(GL_ALPHA_BITS, 0x0D55) -GLENUM(GL_DEPTH_BITS, 0x0D56) -GLENUM(GL_STENCIL_BITS, 0x0D57) -GLENUM(GL_TEXTURE_2D, 0x0DE1) -GLENUM(GL_DONT_CARE, 0x1100) -GLENUM(GL_FASTEST, 0x1101) -GLENUM(GL_NICEST, 0x1102) -GLENUM(GL_AMBIENT, 0x1200) -GLENUM(GL_DIFFUSE, 0x1201) -GLENUM(GL_SPECULAR, 0x1202) -GLENUM(GL_POSITION, 0x1203) -GLENUM(GL_SPOT_DIRECTION, 0x1204) -GLENUM(GL_SPOT_EXPONENT, 0x1205) -GLENUM(GL_SPOT_CUTOFF, 0x1206) -GLENUM(GL_CONSTANT_ATTENUATION, 0x1207) -GLENUM(GL_LINEAR_ATTENUATION, 0x1208) -GLENUM(GL_QUADRATIC_ATTENUATION, 0x1209) -GLENUM(GL_BYTE, 0x1400) -GLENUM(GL_UNSIGNED_BYTE, 0x1401) -GLENUM(GL_SHORT, 0x1402) -GLENUM(GL_UNSIGNED_SHORT, 0x1403) -GLENUM(GL_FLOAT, 0x1406) -GLENUM(GL_FIXED, 0x140C) -GLENUM(GL_CLEAR, 0x1500) -GLENUM(GL_AND, 0x1501) -GLENUM(GL_AND_REVERSE, 0x1502) -GLENUM(GL_COPY, 0x1503) -GLENUM(GL_AND_INVERTED, 0x1504) -GLENUM(GL_NOOP, 0x1505) -GLENUM(GL_XOR, 0x1506) -GLENUM(GL_OR, 0x1507) -GLENUM(GL_NOR, 0x1508) -GLENUM(GL_EQUIV, 0x1509) -GLENUM(GL_INVERT, 0x150A) -GLENUM(GL_OR_REVERSE, 0x150B) -GLENUM(GL_COPY_INVERTED, 0x150C) -GLENUM(GL_OR_INVERTED, 0x150D) -GLENUM(GL_NAND, 0x150E) -GLENUM(GL_SET, 0x150F) -GLENUM(GL_EMISSION, 0x1600) -GLENUM(GL_SHININESS, 0x1601) -GLENUM(GL_AMBIENT_AND_DIFFUSE, 0x1602) -GLENUM(GL_MODELVIEW, 0x1700) -GLENUM(GL_PROJECTION, 0x1701) -GLENUM(GL_TEXTURE, 0x1702) -GLENUM(GL_ALPHA, 0x1906) -GLENUM(GL_RGB, 0x1907) -GLENUM(GL_RGBA, 0x1908) -GLENUM(GL_LUMINANCE, 0x1909) -GLENUM(GL_LUMINANCE_ALPHA, 0x190A) -GLENUM(GL_FLAT, 0x1D00) -GLENUM(GL_SMOOTH, 0x1D01) -GLENUM(GL_KEEP, 0x1E00) -GLENUM(GL_REPLACE, 0x1E01) -GLENUM(GL_REPLACE, 0x1E01) -GLENUM(GL_INCR, 0x1E02) -GLENUM(GL_DECR, 0x1E03) -GLENUM(GL_VENDOR, 0x1F00) -GLENUM(GL_RENDERER, 0x1F01) -GLENUM(GL_VERSION, 0x1F02) -GLENUM(GL_EXTENSIONS, 0x1F03) -GLENUM(GL_MODULATE, 0x2100) -GLENUM(GL_DECAL, 0x2101) -GLENUM(GL_TEXTURE_ENV_MODE, 0x2200) -GLENUM(GL_TEXTURE_ENV_COLOR, 0x2201) -GLENUM(GL_TEXTURE_ENV, 0x2300) -GLENUM(GL_NEAREST, 0x2600) -GLENUM(GL_LINEAR, 0x2601) -GLENUM(GL_NEAREST_MIPMAP_NEAREST, 0x2700) -GLENUM(GL_LINEAR_MIPMAP_NEAREST, 0x2701) -GLENUM(GL_NEAREST_MIPMAP_LINEAR, 0x2702) -GLENUM(GL_LINEAR_MIPMAP_LINEAR, 0x2703) -GLENUM(GL_TEXTURE_MAG_FILTER, 0x2800) -GLENUM(GL_TEXTURE_MIN_FILTER, 0x2801) -GLENUM(GL_TEXTURE_WRAP_S, 0x2802) -GLENUM(GL_TEXTURE_WRAP_T, 0x2803) -GLENUM(GL_CLAMP, 0x2900) -GLENUM(GL_REPEAT, 0x2901) -GLENUM(GL_CLIP_PLANE0, 0x3000) -GLENUM(GL_CLIP_PLANE1, 0x3001) -GLENUM(GL_CLIP_PLANE2, 0x3002) -GLENUM(GL_CLIP_PLANE3, 0x3003) -GLENUM(GL_CLIP_PLANE4, 0x3004) -GLENUM(GL_CLIP_PLANE5, 0x3005) -GLENUM(GL_LIGHT0, 0x4000) -GLENUM(GL_LIGHT1, 0x4001) -GLENUM(GL_LIGHT2, 0x4002) -GLENUM(GL_LIGHT3, 0x4003) -GLENUM(GL_LIGHT4, 0x4004) -GLENUM(GL_LIGHT5, 0x4005) -GLENUM(GL_LIGHT6, 0x4006) -GLENUM(GL_LIGHT7, 0x4007) -GLENUM(GL_DIRECT_TEXTURE_2D_QUALCOMM, 0x7E80) -GLENUM(GL_UNSIGNED_SHORT_4_4_4_4, 0x8033) -GLENUM(GL_UNSIGNED_SHORT_5_5_5_1, 0x8034) -GLENUM(GL_POLYGON_OFFSET_FILL, 0x8037) -GLENUM(GL_RESCALE_NORMAL, 0x803A) -GLENUM(GL_VERTEX_ARRAY, 0x8074) -GLENUM(GL_NORMAL_ARRAY, 0x8075) -GLENUM(GL_COLOR_ARRAY, 0x8076) -GLENUM(GL_TEXTURE_COORD_ARRAY, 0x8078) -GLENUM(GL_MULTISAMPLE, 0x809D) -GLENUM(GL_SAMPLE_ALPHA_TO_COVERAGE, 0x809E) -GLENUM(GL_SAMPLE_ALPHA_TO_ONE, 0x809F) -GLENUM(GL_SAMPLE_COVERAGE, 0x80A0) -GLENUM(GL_MAX_ELEMENTS_VERTICES, 0x80E8) -GLENUM(GL_MAX_ELEMENTS_INDICES, 0x80E9) -GLENUM(GL_CLAMP_TO_EDGE, 0x812F) -GLENUM(GL_GENERATE_MIPMAP, 0x8191) -GLENUM(GL_GENERATE_MIPMAP_HINT, 0x8192) -GLENUM(GL_UNSIGNED_SHORT_5_6_5, 0x8363) -GLENUM(GL_ALIASED_POINT_SIZE_RANGE, 0x846D) -GLENUM(GL_ALIASED_LINE_WIDTH_RANGE, 0x846E) -GLENUM(GL_TEXTURE0, 0x84C0) -GLENUM(GL_TEXTURE1, 0x84C1) -GLENUM(GL_TEXTURE2, 0x84C2) -GLENUM(GL_TEXTURE3, 0x84C3) -GLENUM(GL_TEXTURE4, 0x84C4) -GLENUM(GL_TEXTURE5, 0x84C5) -GLENUM(GL_TEXTURE6, 0x84C6) -GLENUM(GL_TEXTURE7, 0x84C7) -GLENUM(GL_TEXTURE8, 0x84C8) -GLENUM(GL_TEXTURE9, 0x84C9) -GLENUM(GL_TEXTURE10, 0x84CA) -GLENUM(GL_TEXTURE11, 0x84CB) -GLENUM(GL_TEXTURE12, 0x84CC) -GLENUM(GL_TEXTURE13, 0x84CD) -GLENUM(GL_TEXTURE14, 0x84CE) -GLENUM(GL_TEXTURE15, 0x84CF) -GLENUM(GL_TEXTURE16, 0x84D0) -GLENUM(GL_TEXTURE17, 0x84D1) -GLENUM(GL_TEXTURE18, 0x84D2) -GLENUM(GL_TEXTURE19, 0x84D3) -GLENUM(GL_TEXTURE20, 0x84D4) -GLENUM(GL_TEXTURE21, 0x84D5) -GLENUM(GL_TEXTURE22, 0x84D6) -GLENUM(GL_TEXTURE23, 0x84D7) -GLENUM(GL_TEXTURE24, 0x84D8) -GLENUM(GL_TEXTURE25, 0x84D9) -GLENUM(GL_TEXTURE26, 0x84DA) -GLENUM(GL_TEXTURE27, 0x84DB) -GLENUM(GL_TEXTURE28, 0x84DC) -GLENUM(GL_TEXTURE29, 0x84DD) -GLENUM(GL_TEXTURE30, 0x84DE) -GLENUM(GL_TEXTURE31, 0x84DF) -GLENUM(GL_MAX_TEXTURE_UNITS, 0x84E2) -GLENUM(GL_NUM_COMPRESSED_TEXTURE_FORMATS, 0x86A2) -GLENUM(GL_COMPRESSED_TEXTURE_FORMATS, 0x86A3) -GLENUM(GL_BUFFER_SIZE, 0x8764) -GLENUM(GL_BUFFER_USAGE, 0x8765) -GLENUM(GL_POINT_SPRITE_OES, 0x8861) -GLENUM(GL_COORD_REPLACE_OES, 0x8862) -GLENUM(GL_ARRAY_BUFFER, 0x8892) -GLENUM(GL_ELEMENT_ARRAY_BUFFER, 0x8893) -GLENUM(GL_ARRAY_BUFFER_BINDING, 0x8894) -GLENUM(GL_ELEMENT_ARRAY_BUFFER_BINDING, 0x8895) -GLENUM(GL_VERTEX_ARRAY_BUFFER_BINDING, 0x8896) -GLENUM(GL_NORMAL_ARRAY_BUFFER_BINDING, 0x8897) -GLENUM(GL_COLOR_ARRAY_BUFFER_BINDING, 0x8898) -GLENUM(GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING, 0x889A) -GLENUM(GL_STATIC_DRAW, 0x88E4) -GLENUM(GL_DYNAMIC_DRAW, 0x88E8) -GLENUM(GL_POINT_SIZE_ARRAY_TYPE_OES, 0x898A) -GLENUM(GL_POINT_SIZE_ARRAY_STRIDE_OES, 0x898B) -GLENUM(GL_POINT_SIZE_ARRAY_POINTER_OES, 0x898C) -GLENUM(GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES, 0x898D) -GLENUM(GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES, 0x898E) -GLENUM(GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES, 0x898F) -GLENUM(GL_PALETTE4_RGB8_OES, 0x8B90) -GLENUM(GL_PALETTE4_RGBA8_OES, 0x8B91) -GLENUM(GL_PALETTE4_R5_G6_B5_OES, 0x8B92) -GLENUM(GL_PALETTE4_RGBA4_OES, 0x8B93) -GLENUM(GL_PALETTE4_RGB5_A1_OES, 0x8B94) -GLENUM(GL_PALETTE8_RGB8_OES, 0x8B95) -GLENUM(GL_PALETTE8_RGBA8_OES, 0x8B96) -GLENUM(GL_PALETTE8_R5_G6_B5_OES, 0x8B97) -GLENUM(GL_PALETTE8_RGBA4_OES, 0x8B98) -GLENUM(GL_PALETTE8_RGB5_A1_OES, 0x8B99) -GLENUM(GL_IMPLEMENTATION_COLOR_READ_TYPE_OES, 0x8B9A) -GLENUM(GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES, 0x8B9B) -GLENUM(GL_POINT_SIZE_ARRAY_OES, 0x8B9C) -GLENUM(GL_TEXTURE_CROP_RECT_OES, 0x8B9D) -GLENUM(GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES, 0x8B9F) diff --git a/opengl/libs/hooks.h b/opengl/libs/hooks.h index fd9725468a200..1257785c03d53 100644 --- a/opengl/libs/hooks.h +++ b/opengl/libs/hooks.h @@ -23,9 +23,13 @@ #include #include + #include #include +#include +#include + #if !defined(__arm__) #define USE_SLOW_BINDING 1 #else @@ -76,11 +80,15 @@ enum { struct gl_hooks_t { struct gl_t { - #include "gl_entries.in" - #include "glext_entries.in" + #include "GLES_CM/gl_entries.in" + #include "GLES_CM/glext_entries.in" } gl; + struct gl2_t { + #include "GLES2/gl2_entries.in" + #include "GLES2/gl2ext_entries.in" + } gl2; struct egl_t { - #include "egl_entries.in" + #include "EGL/egl_entries.in" } egl; struct gl_ext_t { void (*extensions[MAX_NUMBER_OF_GL_EXTENSIONS])(void); diff --git a/opengl/libs/tools/enumextract.sh b/opengl/libs/tools/enumextract.sh deleted file mode 100644 index 570730215f179..0000000000000 --- a/opengl/libs/tools/enumextract.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/sh - -awk ' -/^#define GL_/ { - names[count] = $2; - values[count] = $3; - sort[count] = $3 + 0; - count++; -} -END { - for (i = 1; i < count; i++) { - for (j = 0; j < i; j++) { - if (sort[i] < sort[j]) { - tn = names[i]; - tv = values[i]; - ts = sort[i]; - names[i] = names[j]; - values[i] = values[j]; - sort[i] = sort[j]; - names[j] = tn; - values[j] = tv; - sort[j] = ts; - } - } - } - - for (i = 0; i < count; i++) { - printf("GLENUM(%s, %s)\n", names[i], values[i]); - } -} -' < $1 - diff --git a/opengl/libs/tools/genfiles b/opengl/libs/tools/genfiles index 107768bf5ced4..4f8eda46539bb 100755 --- a/opengl/libs/tools/genfiles +++ b/opengl/libs/tools/genfiles @@ -15,6 +15,13 @@ # limitations under the License. ./glapigen ../../include/GLES/gl.h > ../GLES_CM/gl_api.in -./glentrygen ../../include/GLES/gl.h > ../gl_entries.in +./glentrygen ../../include/GLES/gl.h > ../GLES_CM/gl_entries.in + ./glapigen ../../include/GLES/glext.h > ../GLES_CM/glext_api.in -./glentrygen ../../include/GLES/glext.h > ../glext_entries.in +./glentrygen ../../include/GLES/glext.h > ../GLES_CM/glext_entries.in + +./glapigen ../../include/GLES2/gl2.h > ../GLES2/gl2_api.in +./glentrygen ../../include/GLES2/gl2.h > ../GLES2/gl2_entries.in + +./glapigen ../../include/GLES2/gl2ext.h > ../GLES2/gl2ext_api.in +./glentrygen ../../include/GLES2/gl2ext.h > ../GLES2/gl2ext_entries.in diff --git a/opengl/libs/tools/glapigen b/opengl/libs/tools/glapigen index a2c3a7bff26d7..bd8dda3625615 100755 --- a/opengl/libs/tools/glapigen +++ b/opengl/libs/tools/glapigen @@ -16,16 +16,23 @@ use strict; +sub rtrim($) +{ + my $string = shift; + $string =~ s/\s+$//; + return $string; +} + while (my $line = <>) { next if $line =~ /^\//; next if $line =~ /^#/; next if $line =~ /^\s*$/; - if ($line !~ /^GL_API\s+(.+)\s+GL_APIENTRY\s+([\w]+)\s*\(([^\)]+)\);/) { + if ($line !~ /^GL_API(CALL)?\s+(.+)\s+GL_APIENTRY\s+([\w]+)\s*\(([^\)]+)\);/) { next; } - my $type = $1; - my $name = $2; - my $args = $3; + my $type = rtrim($2); + my $name = $3; + my $args = $4; #printf("%s", $line); diff --git a/opengl/libs/tools/glentrygen b/opengl/libs/tools/glentrygen index 5e0f7b60d506b..170f04131a58d 100755 --- a/opengl/libs/tools/glentrygen +++ b/opengl/libs/tools/glentrygen @@ -16,16 +16,23 @@ use strict; +sub rtrim($) +{ + my $string = shift; + $string =~ s/\s+$//; + return $string; +} + while (my $line = <>) { next if $line =~ /^\//; next if $line =~ /^#/; next if $line =~ /^\s*$/; - if ($line !~ /^GL_API\s+(.+)\s+GL_APIENTRY\s+([\w]+)\s*\(([^\)]+)\);/) { + if ($line !~ /^GL_API(CALL)?\s+(.+)\s+GL_APIENTRY\s+([\w]+)\s*\(([^\)]+)\);/) { next; } - my $type = $1; - my $name = $2; - my $args = $3; + my $type = rtrim($2); + my $name = $3; + my $args = $4; printf("GL_ENTRY(%s, %s, %s)\n", $type, $name, $args); } From 1837beb08d3b7f1ddd68bff1969e66a57f104075 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Thu, 28 May 2009 12:31:00 -0700 Subject: [PATCH 37/83] fix typo defining a singleton attrbutes for an object that is not a singleton -- no side effects, but useless --- libs/ui/Surface.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/libs/ui/Surface.cpp b/libs/ui/Surface.cpp index 0fe28d462fb04..b8b428f9a2e37 100644 --- a/libs/ui/Surface.cpp +++ b/libs/ui/Surface.cpp @@ -48,8 +48,6 @@ namespace android { // SurfaceBuffer // ============================================================================ -ANDROID_SINGLETON_STATIC_INSTANCE( SurfaceBuffer ) - SurfaceBuffer::SurfaceBuffer() : BASE(), mOwner(false), mBufferMapper(BufferMapper::get()) { From e9d7445acea438b731273ac91114426bf1e5056c Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Thu, 28 May 2009 12:31:31 -0700 Subject: [PATCH 38/83] force explicit instantiation of Singleton<> objects --- include/utils/Singleton.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/utils/Singleton.h b/include/utils/Singleton.h index 2f7c7c2dbf258..bc7626a821398 100644 --- a/include/utils/Singleton.h +++ b/include/utils/Singleton.h @@ -57,6 +57,7 @@ private: */ #define ANDROID_SINGLETON_STATIC_INSTANCE(TYPE) \ + template class Singleton< TYPE >; \ template< class TYPE > Mutex Singleton< TYPE >::sLock; \ template<> TYPE* Singleton< TYPE >::sInstance(0); From 9d17c057bdb9da5fa991a2c3efebe453106ca0a7 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Thu, 28 May 2009 17:39:03 -0700 Subject: [PATCH 39/83] implement a real loader for EGL drivers we now look for a config file in /system/lib/egl/egl.cfg that describes the association of a display to a driver. these drivers are named: /system/lib/egl/lib{[EGL|GLESv1_CM|GLESv2] | GLES}_$TAG.so --- opengl/libagl/Android.mk | 4 +- opengl/libs/Android.mk | 20 ++- opengl/libs/EGL/Loader.cpp | 278 +++++++++++++++++++++++++++++++++++++ opengl/libs/EGL/Loader.h | 90 ++++++++++++ opengl/libs/EGL/egl.cpp | 148 ++------------------ opengl/libs/EGL/hooks.cpp | 67 +++++++++ opengl/libs/egl_impl.h | 2 +- opengl/libs/hooks.h | 11 +- 8 files changed, 479 insertions(+), 141 deletions(-) create mode 100644 opengl/libs/EGL/Loader.cpp create mode 100644 opengl/libs/EGL/Loader.h create mode 100644 opengl/libs/EGL/hooks.cpp diff --git a/opengl/libagl/Android.mk b/opengl/libagl/Android.mk index 946e84914a919..060f3c6d11c6b 100644 --- a/opengl/libagl/Android.mk +++ b/opengl/libagl/Android.mk @@ -47,6 +47,8 @@ LOCAL_SHARED_LIBRARIES := libcutils libhardware libutils libpixelflinger LOCAL_CFLAGS += -fvisibility=hidden LOCAL_LDLIBS := -lpthread -ldl -LOCAL_MODULE:= libagl + +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/egl +LOCAL_MODULE:= libGLES_android include $(BUILD_SHARED_LIBRARY) diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk index 67a67ec8b8778..33a1698880dc1 100644 --- a/opengl/libs/Android.mk +++ b/opengl/libs/Android.mk @@ -8,9 +8,11 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ EGL/egl.cpp \ + EGL/hooks.cpp \ + EGL/Loader.cpp \ # -LOCAL_SHARED_LIBRARIES += libcutils +LOCAL_SHARED_LIBRARIES += libcutils libutils LOCAL_LDLIBS := -lpthread -ldl LOCAL_MODULE:= libEGL @@ -27,8 +29,24 @@ LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES LOCAL_CFLAGS += -fvisibility=hidden include $(BUILD_SHARED_LIBRARY) +installed_libEGL := $(LOCAL_INSTALLED_MODULE) +# OpenGL drivers config file +ifneq ($(BOARD_EGL_CFG),) + +include $(CLEAR_VARS) +LOCAL_MODULE := egl.cfg +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_CLASS := ETC +LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/egl +LOCAL_SRC_FILES := ../../../../$(BOARD_EGL_CFG) +include $(BUILD_PREBUILT) + +# make sure we depend on egl.cfg, so it gets installed +$(installed_libEGL): | egl.cfg + +endif ############################################################################### # Build the wrapper OpenGL ES 1.x library diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp new file mode 100644 index 0000000000000..0e0f2c2632f1b --- /dev/null +++ b/opengl/libs/EGL/Loader.cpp @@ -0,0 +1,278 @@ +/* + ** Copyright 2007, 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. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include "hooks.h" +#include "egl_impl.h" + +#include "Loader.h" + +// ---------------------------------------------------------------------------- +namespace android { +// ---------------------------------------------------------------------------- + + +/* + * EGL drivers are called + * + * /system/lib/egl/lib{[EGL|GLESv1_CM|GLESv2] | GLES}_$TAG.so + * + */ + +ANDROID_SINGLETON_STATIC_INSTANCE( Loader ) + +// ---------------------------------------------------------------------------- + +Loader::driver_t::driver_t(void* gles) +{ + dso[0] = gles; + for (size_t i=1 ; i>> %u %u %s", dpy, impl, tag); + gConfig.add( entry_t(dpy, impl, tag) ); + } + } + fclose(cfg); + } +} + +Loader::~Loader() +{ +} + +const char* Loader::getTag(int dpy, int impl) +{ + const Vector& cfgs(gConfig); + const size_t c = cfgs.size(); + for (size_t i=0 ; iset( load_driver(path, hooks, GLESv1_CM), GLESv1_CM ); + + snprintf(path, PATH_MAX, format, "GLESv2", tag); + hnd->set( load_driver(path, hooks, GLESv2), GLESv2 ); + } + } + } + + LOG_FATAL_IF(!index && !impl && !hnd, + "couldn't't find the default OpenGL ES implementation " + "for default display"); + + return (void*)hnd; +} + +status_t Loader::close(void* driver) +{ + driver_t* hnd = (driver_t*)driver; + delete hnd; + return NO_ERROR; +} + +void Loader::init_api(void* dso, + char const * const * api, + __eglMustCastToProperFunctionPointerType* curr, + getProcAddressType getProcAddress) +{ + char scrap[256]; + while (*api) { + char const * name = *api; + __eglMustCastToProperFunctionPointerType f = + (__eglMustCastToProperFunctionPointerType)dlsym(dso, name); + if (f == NULL) { + // couldn't find the entry-point, use eglGetProcAddress() + f = getProcAddress(name); + } + if (f == NULL) { + // Try without the OES postfix + ssize_t index = ssize_t(strlen(name)) - 3; + if ((index>0 && (index<255)) && (!strcmp(name+index, "OES"))) { + strncpy(scrap, name, index); + scrap[index] = 0; + f = (__eglMustCastToProperFunctionPointerType)dlsym(dso, scrap); + //LOGD_IF(f, "found <%s> instead", scrap); + } + } + if (f == NULL) { + // Try with the OES postfix + ssize_t index = ssize_t(strlen(name)) - 3; + if ((index>0 && (index<252)) && (strcmp(name+index, "OES"))) { + strncpy(scrap, name, index); + scrap[index] = 0; + strcat(scrap, "OES"); + f = (__eglMustCastToProperFunctionPointerType)dlsym(dso, scrap); + //LOGD_IF(f, "found <%s> instead", scrap); + } + } + if (f == NULL) { + //LOGD("%s", name); + f = (__eglMustCastToProperFunctionPointerType)gl_unimplemented; + } + *curr++ = f; + api++; + } +} + +void *Loader::load_driver(const char* driver, gl_hooks_t* hooks, uint32_t mask) +{ + //LOGD("%s", driver); + void* dso = dlopen(driver, RTLD_NOW | RTLD_LOCAL); + LOGE_IF(!dso, + "couldn't load <%s> library (%s)", + driver, dlerror()); + if (dso == 0) + return 0; + + if (mask & EGL) { + getProcAddress = (getProcAddressType)dlsym(dso, "eglGetProcAddress"); + + LOGE_IF(!getProcAddress, + "can't find eglGetProcAddress() in %s", driver); + + gl_hooks_t::egl_t* egl = &hooks->egl; + __eglMustCastToProperFunctionPointerType* curr = + (__eglMustCastToProperFunctionPointerType*)egl; + char const * const * api = egl_names; + while (*api) { + char const * name = *api; + __eglMustCastToProperFunctionPointerType f = + (__eglMustCastToProperFunctionPointerType)dlsym(dso, name); + if (f == NULL) { + // couldn't find the entry-point, use eglGetProcAddress() + f = getProcAddress(name); + if (f == NULL) { + f = (__eglMustCastToProperFunctionPointerType)0; + } + } + *curr++ = f; + api++; + } + } + + if (mask & GLESv1_CM) { + init_api(dso, gl_names, + (__eglMustCastToProperFunctionPointerType*)&hooks->gl, + getProcAddress); + } + + if (mask & GLESv2) { + init_api(dso, gl2_names, + (__eglMustCastToProperFunctionPointerType*)&hooks->gl2, + getProcAddress); + } + + return dso; +} + +// ---------------------------------------------------------------------------- +}; // namespace android +// ---------------------------------------------------------------------------- diff --git a/opengl/libs/EGL/Loader.h b/opengl/libs/EGL/Loader.h new file mode 100644 index 0000000000000..69f6dd5c27225 --- /dev/null +++ b/opengl/libs/EGL/Loader.h @@ -0,0 +1,90 @@ +/* + ** Copyright 2009, 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. + */ + +#ifndef ANDROID_EGL_LOADER_H +#define ANDROID_EGL_LOADER_H + +#include +#include +#include + +#include +#include +#include +#include + +#include + +// ---------------------------------------------------------------------------- +namespace android { +// ---------------------------------------------------------------------------- + +struct gl_hooks_t; + +class Loader : public Singleton +{ + friend class Singleton; + + typedef __eglMustCastToProperFunctionPointerType (*getProcAddressType)( + const char*); + + enum { + EGL = 0x01, + GLESv1_CM = 0x02, + GLESv2 = 0x04 + }; + struct driver_t { + driver_t(void* gles); + ~driver_t(); + status_t set(void* hnd, int32_t api); + void* dso[3]; + }; + + struct entry_t { + entry_t() { } + entry_t(int dpy, int impl, const char* tag); + int dpy; + int impl; + String8 tag; + }; + + Vector gConfig; + getProcAddressType getProcAddress; + + const char* getTag(int dpy, int impl); + +public: + ~Loader(); + + void* open(EGLNativeDisplayType display, int impl, gl_hooks_t* hooks); + status_t close(void* driver); + +private: + Loader(); + void *load_driver(const char* driver, gl_hooks_t* hooks, uint32_t mask); + + static __attribute__((noinline)) + void init_api(void* dso, + char const * const * api, + __eglMustCastToProperFunctionPointerType* curr, + getProcAddressType getProcAddress); +}; + +// ---------------------------------------------------------------------------- +}; // namespace android +// ---------------------------------------------------------------------------- + +#endif /* ANDROID_EGL_LOADER_H */ diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp index 4eae98eee5d5a..77648f280fc73 100644 --- a/opengl/libs/EGL/egl.cpp +++ b/opengl/libs/EGL/egl.cpp @@ -38,7 +38,7 @@ #include "hooks.h" #include "egl_impl.h" - +#include "Loader.h" #define MAKE_CONFIG(_impl, _index) ((EGLConfig)(((_impl)<<24) | (_index))) #define setError(_e, _r) setErrorEtc(__FUNCTION__, __LINE__, _e, _r) @@ -139,38 +139,6 @@ struct tls_t EGLContext ctx; }; -static void gl_unimplemented() { - LOGE("called unimplemented OpenGL ES API"); -} - -// ---------------------------------------------------------------------------- -// GL / EGL hooks -// ---------------------------------------------------------------------------- - -#undef GL_ENTRY -#undef EGL_ENTRY -#define GL_ENTRY(_r, _api, ...) #_api, -#define EGL_ENTRY(_r, _api, ...) #_api, - -static char const * const gl_names[] = { - #include "GLES_CM/gl_entries.in" - #include "GLES_CM/glext_entries.in" - NULL -}; - -static char const * const gl2_names[] = { - #include "GLES2/gl2_entries.in" - #include "GLES2/gl2ext_entries.in" - NULL -}; - -static char const * const egl_names[] = { - #include "egl_entries.in" - NULL -}; - -#undef GL_ENTRY -#undef EGL_ENTRY // ---------------------------------------------------------------------------- @@ -281,105 +249,6 @@ EGLContext getContext() { /*****************************************************************************/ -typedef __eglMustCastToProperFunctionPointerType (*getProcAddressType)( - const char*); - -static __attribute__((noinline)) -void init_api(void* dso, - char const * const * api, - __eglMustCastToProperFunctionPointerType* curr, - getProcAddressType getProcAddress) -{ - char scrap[256]; - while (*api) { - char const * name = *api; - __eglMustCastToProperFunctionPointerType f = - (__eglMustCastToProperFunctionPointerType)dlsym(dso, name); - if (f == NULL) { - // couldn't find the entry-point, use eglGetProcAddress() - f = getProcAddress(name); - } - if (f == NULL) { - // Try without the OES postfix - ssize_t index = ssize_t(strlen(name)) - 3; - if ((index>0 && (index<255)) && (!strcmp(name+index, "OES"))) { - strncpy(scrap, name, index); - scrap[index] = 0; - f = (__eglMustCastToProperFunctionPointerType)dlsym(dso, scrap); - //LOGD_IF(f, "found <%s> instead", scrap); - } - } - if (f == NULL) { - // Try with the OES postfix - ssize_t index = ssize_t(strlen(name)) - 3; - if ((index>0 && (index<252)) && (strcmp(name+index, "OES"))) { - strncpy(scrap, name, index); - scrap[index] = 0; - strcat(scrap, "OES"); - f = (__eglMustCastToProperFunctionPointerType)dlsym(dso, scrap); - //LOGD_IF(f, "found <%s> instead", scrap); - } - } - if (f == NULL) { - //LOGD("%s", name); - f = (__eglMustCastToProperFunctionPointerType)gl_unimplemented; - } - *curr++ = f; - api++; - } -} - -static __attribute__((noinline)) -void *load_driver(const char* driver, gl_hooks_t* hooks) -{ - //LOGD("%s", driver); - void* dso = dlopen(driver, RTLD_NOW | RTLD_LOCAL); - LOGE_IF(!dso, - "couldn't load <%s> library (%s)", - driver, dlerror()); - - if (dso) { - // first find the symbol for eglGetProcAddress - - typedef __eglMustCastToProperFunctionPointerType (*getProcAddressType)( - const char*); - - getProcAddressType getProcAddress = - (getProcAddressType)dlsym(dso, "eglGetProcAddress"); - - LOGE_IF(!getProcAddress, - "can't find eglGetProcAddress() in %s", driver); - - gl_hooks_t::egl_t* egl = &hooks->egl; - __eglMustCastToProperFunctionPointerType* curr = - (__eglMustCastToProperFunctionPointerType*)egl; - char const * const * api = egl_names; - while (*api) { - char const * name = *api; - __eglMustCastToProperFunctionPointerType f = - (__eglMustCastToProperFunctionPointerType)dlsym(dso, name); - if (f == NULL) { - // couldn't find the entry-point, use eglGetProcAddress() - f = getProcAddress(name); - if (f == NULL) { - f = (__eglMustCastToProperFunctionPointerType)0; - } - } - *curr++ = f; - api++; - } - - init_api(dso, gl_names, - (__eglMustCastToProperFunctionPointerType*)&hooks->gl, - getProcAddress); - - init_api(dso, gl2_names, - (__eglMustCastToProperFunctionPointerType*)&hooks->gl2, - getProcAddress); - } - return dso; -} - template static __attribute__((noinline)) int binarySearch( @@ -605,12 +474,15 @@ EGLDisplay egl_init_displays(NativeDisplayType display) EGLDisplay dpy = EGLDisplay(uintptr_t(display) + 1LU); egl_display_t* d = &gDisplay[index]; + // get our driver loader + Loader& loader(Loader::getInstance()); + // dynamically load all our EGL implementations for that display // and call into the real eglGetGisplay() egl_connection_t* cnx = &gEGLImpl[IMPL_SOFTWARE]; if (cnx->dso == 0) { cnx->hooks = &gHooks[IMPL_SOFTWARE]; - cnx->dso = load_driver("libagl.so", cnx->hooks); + cnx->dso = loader.open(display, 0, cnx->hooks); } if (cnx->dso && d->dpys[IMPL_SOFTWARE]==EGL_NO_DISPLAY) { d->dpys[IMPL_SOFTWARE] = cnx->hooks->egl.eglGetDisplay(display); @@ -624,7 +496,7 @@ EGLDisplay egl_init_displays(NativeDisplayType display) property_get("debug.egl.hw", value, "1"); if (atoi(value) != 0) { cnx->hooks = &gHooks[IMPL_HARDWARE]; - cnx->dso = load_driver("libhgl2.so", cnx->hooks); + cnx->dso = loader.open(display, 1, cnx->hooks); } else { LOGD("3D hardware acceleration is disabled"); } @@ -656,7 +528,8 @@ EGLDisplay egl_init_displays(NativeDisplayType display) if (d->dpys[IMPL_HARDWARE] == EGL_NO_DISPLAY) { LOGE("h/w accelerated eglGetDisplay() failed (%s)", egl_strerror(cnx->hooks->egl.eglGetError())); - dlclose((void*)cnx->dso); + + loader.close(cnx->dso); cnx->dso = 0; // in case of failure, we want to make sure we don't try again // as it's expensive. @@ -768,6 +641,8 @@ EGLBoolean eglTerminate(EGLDisplay dpy) if (android_atomic_dec(&dp->refs) != 1) return EGL_TRUE; + Loader& loader(Loader::getInstance()); + EGLBoolean res = EGL_FALSE; for (int i=0 ; iqueryString[i].extensions); dp->numConfigs[i] = 0; dp->dpys[i] = EGL_NO_DISPLAY; - dlclose((void*)cnx->dso); + + loader.close(cnx->dso); cnx->dso = 0; res = EGL_TRUE; } diff --git a/opengl/libs/EGL/hooks.cpp b/opengl/libs/EGL/hooks.cpp new file mode 100644 index 0000000000000..224636669e10e --- /dev/null +++ b/opengl/libs/EGL/hooks.cpp @@ -0,0 +1,67 @@ +/* + ** Copyright 2009, 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. + */ + +#include +#include +#include + +#include + +#include "hooks.h" + +// ---------------------------------------------------------------------------- +namespace android { +// ---------------------------------------------------------------------------- + +void gl_unimplemented() { + LOGE("called unimplemented OpenGL ES API"); +} + + +// ---------------------------------------------------------------------------- +// GL / EGL hooks +// ---------------------------------------------------------------------------- + +#undef GL_ENTRY +#undef EGL_ENTRY +#define GL_ENTRY(_r, _api, ...) #_api, +#define EGL_ENTRY(_r, _api, ...) #_api, + +char const * const gl_names[] = { + #include "GLES_CM/gl_entries.in" + #include "GLES_CM/glext_entries.in" + NULL +}; + +char const * const gl2_names[] = { + #include "GLES2/gl2_entries.in" + #include "GLES2/gl2ext_entries.in" + NULL +}; + +char const * const egl_names[] = { + #include "egl_entries.in" + NULL +}; + +#undef GL_ENTRY +#undef EGL_ENTRY + + +// ---------------------------------------------------------------------------- +}; // namespace android +// ---------------------------------------------------------------------------- + diff --git a/opengl/libs/egl_impl.h b/opengl/libs/egl_impl.h index 80455d0a26ab4..c5f753d56a16d 100644 --- a/opengl/libs/egl_impl.h +++ b/opengl/libs/egl_impl.h @@ -31,7 +31,7 @@ struct gl_hooks_t; struct egl_connection_t { - void volatile * dso; + void * dso; gl_hooks_t * hooks; EGLint major; EGLint minor; diff --git a/opengl/libs/hooks.h b/opengl/libs/hooks.h index 1257785c03d53..37292eef07ec2 100644 --- a/opengl/libs/hooks.h +++ b/opengl/libs/hooks.h @@ -21,12 +21,12 @@ #include #include +#include + #include #include - #include #include - #include #include @@ -102,6 +102,13 @@ struct gl_hooks_t { extern gl_hooks_t gHooks[IMPL_NUM_IMPLEMENTATIONS]; extern pthread_key_t gGLWrapperKey; +extern "C" void gl_unimplemented(); + +extern char const * const gl_names[]; +extern char const * const gl2_names[]; +extern char const * const egl_names[]; + +// ---------------------------------------------------------------------------- #if USE_FAST_TLS_KEY From 1277bb01166bc7ef75305014cff36166b4c2b393 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Wed, 3 Jun 2009 14:49:08 -0700 Subject: [PATCH 40/83] when looking for an EGLConfig always pick the first one that matches, not the last one --- libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp index 25e351c10f865..52b0f685c60fb 100644 --- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp +++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp @@ -164,6 +164,7 @@ void DisplayHardware::init(uint32_t dpy) eglGetConfigAttrib(display, configs[i], EGL_ALPHA_SIZE, &a); if (fbSzA == a && fbSzR == r && fbSzG == g && fbSzB == b) { config = configs[i]; + break; } } } From a650aaa3918f47ceb116ce8dfd3f1e423687fa69 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Wed, 3 Jun 2009 17:32:49 -0700 Subject: [PATCH 41/83] fix build --- media/libmediaplayerservice/MediaPlayerService.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index a17e6512fad33..8ac697e20ec2c 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -27,14 +27,18 @@ #include #include + #include +#include + +#include #include + #include #include #include #include -#include #include #include From b4b4c11f82e88f9a1cecd97460a9fcc192b37612 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Wed, 3 Jun 2009 18:26:58 -0700 Subject: [PATCH 42/83] fix/clean these Android.mk following dbort and joeo's comments --- opengl/libagl/Android.mk | 5 +++-- opengl/libs/Android.mk | 12 ++++++------ opengl/libs/EGL/Loader.cpp | 6 ++---- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/opengl/libagl/Android.mk b/opengl/libagl/Android.mk index 060f3c6d11c6b..d1ed82e5eb007 100644 --- a/opengl/libagl/Android.mk +++ b/opengl/libagl/Android.mk @@ -32,12 +32,13 @@ endif ifneq ($(TARGET_SIMULATOR),true) # we need to access the private Bionic header - LOCAL_CFLAGS += -I$(LOCAL_PATH)/../../../../bionic/libc/private + LOCAL_C_INCLUDES += bionic/libc/private endif ifeq ($(LIBAGL_USE_GRALLOC_COPYBITS),1) - LOCAL_CFLAGS += -DLIBAGL_USE_GRALLOC_COPYBITS -I$(LOCAL_PATH)/../../../../hardware/libhardware/modules/gralloc + LOCAL_CFLAGS += -DLIBAGL_USE_GRALLOC_COPYBITS LOCAL_SRC_FILES += copybit.cpp + LOCAL_C_INCLUDES += hardware/libhardware/modules/gralloc endif LOCAL_CFLAGS += -DLOG_TAG=\"libagl\" diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk index 33a1698880dc1..e1fd48b7fa98e 100644 --- a/opengl/libs/Android.mk +++ b/opengl/libs/Android.mk @@ -20,8 +20,8 @@ LOCAL_MODULE:= libEGL ifeq ($(TARGET_SIMULATOR),true) else LOCAL_SHARED_LIBRARIES += libdl - # we need to access the Bionic private header - LOCAL_CFLAGS += -I$(LOCAL_PATH)/../../../../bionic/libc/private + # we need to access the private Bionic header + LOCAL_C_INCLUDES += bionic/libc/private endif LOCAL_CFLAGS += -DLOG_TAG=\"libEGL\" @@ -66,8 +66,8 @@ LOCAL_MODULE:= libGLESv1_CM ifeq ($(TARGET_SIMULATOR),true) else LOCAL_SHARED_LIBRARIES += libdl - # we need to access the Bionic private header - LOCAL_CFLAGS += -I$(LOCAL_PATH)/../../../../bionic/libc/private + # we need to access the private Bionic header + LOCAL_C_INCLUDES += bionic/libc/private endif LOCAL_CFLAGS += -DLOG_TAG=\"libGLESv1\" @@ -95,8 +95,8 @@ LOCAL_MODULE:= libGLESv2 ifeq ($(TARGET_SIMULATOR),true) else LOCAL_SHARED_LIBRARIES += libdl - # we need to access the Bionic private header - LOCAL_CFLAGS += -I$(LOCAL_PATH)/../../../../bionic/libc/private + # we need to access the private Bionic header + LOCAL_C_INCLUDES += bionic/libc/private endif LOCAL_CFLAGS += -DLOG_TAG=\"libGLESv2\" diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp index 0e0f2c2632f1b..103522ebec785 100644 --- a/opengl/libs/EGL/Loader.cpp +++ b/opengl/libs/EGL/Loader.cpp @@ -165,7 +165,7 @@ void* Loader::open(EGLNativeDisplayType display, int impl, gl_hooks_t* hooks) } LOG_FATAL_IF(!index && !impl && !hnd, - "couldn't't find the default OpenGL ES implementation " + "couldn't find the default OpenGL ES implementation " "for default display"); return (void*)hnd; @@ -226,9 +226,7 @@ void *Loader::load_driver(const char* driver, gl_hooks_t* hooks, uint32_t mask) { //LOGD("%s", driver); void* dso = dlopen(driver, RTLD_NOW | RTLD_LOCAL); - LOGE_IF(!dso, - "couldn't load <%s> library (%s)", - driver, dlerror()); + LOGE_IF(!dso, "%s", dlerror()); if (dso == 0) return 0; From 4098d78b3507bfecce9f7a8a4b5d334c7842ff88 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Wed, 3 Jun 2009 18:30:22 -0700 Subject: [PATCH 43/83] remove some spurious debuging LOGD --- opengl/libs/EGL/Loader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp index 103522ebec785..4f9939f0355c9 100644 --- a/opengl/libs/EGL/Loader.cpp +++ b/opengl/libs/EGL/Loader.cpp @@ -104,7 +104,7 @@ Loader::Loader() int dpy; int impl; if (sscanf(line, "%u %u %s", &dpy, &impl, tag) == 3) { - LOGD(">>> %u %u %s", dpy, impl, tag); + //LOGD(">>> %u %u %s", dpy, impl, tag); gConfig.add( entry_t(dpy, impl, tag) ); } } From 36432ccc13f6d3db7af35661683c33ffa3406d85 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Wed, 3 Jun 2009 19:00:53 -0700 Subject: [PATCH 44/83] make sure clear the draw and read EGLSurface when eglMakeCurrent() is called for unbinding from the thread --- opengl/libagl/egl.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp index f50257abb7e8e..0df2bbaa584f6 100644 --- a/opengl/libagl/egl.cpp +++ b/opengl/libagl/egl.cpp @@ -384,7 +384,7 @@ void egl_window_surface_v2_t::connect() void egl_window_surface_v2_t::disconnect() { - if (buffer) { + if (buffer && bits) { bits = NULL; unlock(buffer); } @@ -1681,10 +1681,12 @@ EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw, egl_surface_t* d = (egl_surface_t*)c->draw; egl_surface_t* r = (egl_surface_t*)c->read; if (d) { + c->draw = 0; d->ctx = EGL_NO_CONTEXT; d->disconnect(); } if (r) { + c->read = 0; r->ctx = EGL_NO_CONTEXT; // FIXME: unlock/disconnect the read surface too } From 2d5ee25556cb363700dc5127f88ca05fb9493e14 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Thu, 4 Jun 2009 18:46:21 -0700 Subject: [PATCH 45/83] fix a bunch of problems with destroying surfaces. now, all destruction path, go through the purgatory which is emptied when ~ISurface is called, but we also make sure to remove the surface from the current list from there (in case a client forgot to request the destruction explicitely). --- include/ui/ISurfaceComposer.h | 1 - libs/surfaceflinger/SurfaceFlinger.cpp | 96 ++++++++++++++++---------- libs/surfaceflinger/SurfaceFlinger.h | 3 + 3 files changed, 63 insertions(+), 37 deletions(-) diff --git a/include/ui/ISurfaceComposer.h b/include/ui/ISurfaceComposer.h index ab6dd56e64e9d..ce2b94c3e1601 100644 --- a/include/ui/ISurfaceComposer.h +++ b/include/ui/ISurfaceComposer.h @@ -62,7 +62,6 @@ public: eTransparentRegionChanged = 0x00000020, eVisibilityChanged = 0x00000040, eFreezeTintChanged = 0x00000080, - eDestroyed = 0x00000100 }; enum { diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp index 70f34a1a4418e..0d1be2d06c979 100644 --- a/libs/surfaceflinger/SurfaceFlinger.cpp +++ b/libs/surfaceflinger/SurfaceFlinger.cpp @@ -246,12 +246,12 @@ void SurfaceFlinger::destroyConnection(ClientID cid) Client* const client = mClientsMap.valueFor(cid); if (client) { // free all the layers this client owns - const Vector< wp >& layers = client->getLayers(); + Vector< wp > layers(client->getLayers()); const size_t count = layers.size(); for (size_t i=0 ; i layer(layers[i].promote()); if (layer != 0) { - removeLayer_l(layer); + purgatorizeLayer_l(layer); } } @@ -551,9 +551,25 @@ void SurfaceFlinger::handleConsoleEvents() void SurfaceFlinger::handleTransaction(uint32_t transactionFlags) { - Mutex::Autolock _l(mStateLock); + Vector< sp > ditchedLayers; - const LayerVector& currentLayers = mCurrentState.layersSortedByZ; + { // scope for the lock + Mutex::Autolock _l(mStateLock); + handleTransactionLocked(transactionFlags, ditchedLayers); + } + + // do this without lock held + const size_t count = ditchedLayers.size(); + for (size_t i=0 ; iditch(); + } +} + +void SurfaceFlinger::handleTransactionLocked( + uint32_t transactionFlags, Vector< sp >& ditchedLayers) +{ + const LayerVector& currentLayers(mCurrentState.layersSortedByZ); const size_t count = currentLayers.size(); /* @@ -628,14 +644,12 @@ void SurfaceFlinger::handleTransaction(uint32_t transactionFlags) if (mLayersRemoved) { mVisibleRegionsDirty = true; const LayerVector& previousLayers(mDrawingState.layersSortedByZ); - const ssize_t count = previousLayers.size(); - for (ssize_t i=0 ; i& layer(previousLayers[i]); if (currentLayers.indexOf( layer ) < 0) { // this layer is not visible anymore - // FIXME: would be better to call without the lock held - //LOGD("ditching layer %p", layer.get()); - layer->ditch(); + ditchedLayers.add(layer); } } } @@ -1012,9 +1026,10 @@ status_t SurfaceFlinger::addLayer(const sp& layer) status_t SurfaceFlinger::removeLayer(const sp& layer) { Mutex::Autolock _l(mStateLock); - removeLayer_l(layer); - setTransactionFlags(eTransactionNeeded); - return NO_ERROR; + status_t err = purgatorizeLayer_l(layer); + if (err == NO_ERROR) + setTransactionFlags(eTransactionNeeded); + return err; } status_t SurfaceFlinger::invalidateLayerVisibility(const sp& layer) @@ -1047,11 +1062,7 @@ status_t SurfaceFlinger::removeLayer_l(const sp& layerBase) } return NO_ERROR; } - // it's possible that we don't find a layer, because it might - // have been destroyed already -- this is not technically an error - // from the user because there is a race between BClient::destroySurface(), - // ~BClient() and destroySurface-from-a-transaction. - return (index == NAME_NOT_FOUND) ? status_t(NO_ERROR) : index; + return status_t(index); } status_t SurfaceFlinger::purgatorizeLayer_l(const sp& layerBase) @@ -1062,6 +1073,10 @@ status_t SurfaceFlinger::purgatorizeLayer_l(const sp& layerBase) if (err >= 0) { mLayerPurgatory.add(layerBase); } + // it's possible that we don't find a layer, because it might + // have been destroyed already -- this is not technically an error + // from the user because there is a race between BClient::destroySurface(), + // ~BClient() and ~ISurface(). return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err; } @@ -1294,12 +1309,7 @@ status_t SurfaceFlinger::removeSurface(SurfaceID index) status_t SurfaceFlinger::destroySurface(const sp& layer) { - /* - * called by ~ISurface() when all references are gone - * - * the surface must be removed from purgatory from the main thread - * since its dtor must run from there (b/c of OpenGL ES). - */ + /* called by ~ISurface() when all references are gone */ class MessageDestroySurface : public MessageBase { SurfaceFlinger* flinger; @@ -1310,11 +1320,33 @@ status_t SurfaceFlinger::destroySurface(const sp& layer) : flinger(flinger), layer(layer) { } virtual bool handler() { Mutex::Autolock _l(flinger->mStateLock); - ssize_t idx = flinger->mLayerPurgatory.remove(layer); - LOGE_IF(idx<0, "layer=%p is not in the purgatory list", layer.get()); + // remove the layer from the current list -- chances are that it's + // not in the list anyway, because it should have been removed + // already upon request of the client (eg: window manager). + // However, a buggy client could have not done that. + // Since we know we don't have any more clients, we don't need + // to use the purgatory. + status_t err = flinger->removeLayer_l(layer); + if (err == NAME_NOT_FOUND) { + // The surface wasn't in the current list, which means it was + // removed already, which means it is in the purgatory, + // and need to be removed from there. + // This needs to happen from the main thread since its dtor + // must run from there (b/c of OpenGL ES). Additionally, we + // can't really acquire our internal lock from + // destroySurface() -- see postMessage() below. + ssize_t idx = flinger->mLayerPurgatory.remove(layer); + LOGE_IF(idx < 0, + "layer=%p is not in the purgatory list", layer.get()); + } return true; } }; + + // It's better to not acquire our internal lock here, because it's hard + // to predict that it's not going to be already taken when ~Surface() + // is called. + mEventQueue.postMessage( new MessageDestroySurface(this, layer) ); return NO_ERROR; } @@ -1329,18 +1361,9 @@ status_t SurfaceFlinger::setClientState( cid <<= 16; for (int i=0 ; i& layer = getLayerUser_l(s.surface | cid); + sp layer(getLayerUser_l(s.surface | cid)); if (layer != 0) { const uint32_t what = s.what; - // check if it has been destroyed first - if (what & eDestroyed) { - if (removeLayer_l(layer) == NO_ERROR) { - flags |= eTransactionNeeded; - // we skip everything else... well, no, not really - // we skip ONLY that transaction. - continue; - } - } if (what & ePositionChanged) { if (layer->setPosition(s.x, s.y)) flags |= eTraversalNeeded; @@ -1486,7 +1509,8 @@ status_t SurfaceFlinger::dump(int fd, const Vector& args) mFreezeDisplay?"yes":"no", mFreezeCount, mCurrentState.orientation, hw.canDraw()); result.append(buffer); - + snprintf(buffer, SIZE, " purgatory size: %d\n", mLayerPurgatory.size()); + result.append(buffer); const BufferAllocator& alloc(BufferAllocator::get()); alloc.dump(result); } diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h index 6bbb21ff5c9c9..a21e18644be1a 100644 --- a/libs/surfaceflinger/SurfaceFlinger.h +++ b/libs/surfaceflinger/SurfaceFlinger.h @@ -246,6 +246,9 @@ private: void handleConsoleEvents(); void handleTransaction(uint32_t transactionFlags); + void handleTransactionLocked( + uint32_t transactionFlags, + Vector< sp >& ditchedLayers); void computeVisibleRegions( LayerVector& currentLayers, From eb22c5b358af775a5f1192fc248594c7a0025d56 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Thu, 4 Jun 2009 23:29:29 -0700 Subject: [PATCH 46/83] cleanup Debug.h a bit --- include/private/ui/SharedState.h | 17 +++++------------ include/utils/Debug.h | 31 +++++++++++++++++++++++++++---- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/include/private/ui/SharedState.h b/include/private/ui/SharedState.h index 646cc10e9a4de..3bc7979ca8109 100644 --- a/include/private/ui/SharedState.h +++ b/include/private/ui/SharedState.h @@ -20,6 +20,7 @@ #include #include +#include #include namespace android { @@ -140,19 +141,11 @@ struct surface_flinger_cblk_t // 4KB max // --------------------------------------------------------------------------- -template struct CTA; -template<> struct CTA { }; - -// compile-time assertions. just to avoid catastrophes. -inline void compile_time_asserts() { - CTA sizeof__layer_cblk_t__eq_128; - (void)sizeof__layer_cblk_t__eq_128; // we don't want a warning - CTA sizeof__per_client_cblk_t__le_4096; - (void)sizeof__per_client_cblk_t__le_4096; // we don't want a warning - CTA sizeof__surface_flinger_cblk_t__le_4096; - (void)sizeof__surface_flinger_cblk_t__le_4096; // we don't want a warning -} +COMPILE_TIME_ASSERT(sizeof(layer_cblk_t) == 128) +COMPILE_TIME_ASSERT(sizeof(per_client_cblk_t) <= 4096) +COMPILE_TIME_ASSERT(sizeof(surface_flinger_cblk_t) <= 4096) +// --------------------------------------------------------------------------- }; // namespace android #endif // ANDROID_UI_SHARED_STATE_H diff --git a/include/utils/Debug.h b/include/utils/Debug.h index a662b9cc27dcd..21d04bdcec32d 100644 --- a/include/utils/Debug.h +++ b/include/utils/Debug.h @@ -14,10 +14,6 @@ * limitations under the License. */ -// -// Debugging tools. These should be able to be stripped -// in release builds. -// #ifndef ANDROID_DEBUG_H #define ANDROID_DEBUG_H @@ -25,9 +21,30 @@ #include namespace android { +// --------------------------------------------------------------------------- +#ifdef __cplusplus template struct CompileTimeAssert; template<> struct CompileTimeAssert {}; +#define COMPILE_TIME_ASSERT(_exp) \ + template class CompileTimeAssert< (_exp) >; +#endif + +// --------------------------------------------------------------------------- + +#ifdef __cplusplus +template struct CompileTimeIfElse; +template +struct CompileTimeIfElse { typedef LHS TYPE; }; +template +struct CompileTimeIfElse { typedef RHS TYPE; }; +#endif + +// --------------------------------------------------------------------------- + +#ifdef __cplusplus +extern "C" { +#endif const char* stringForIndent(int32_t indentLevel); @@ -35,11 +52,17 @@ typedef void (*debugPrintFunc)(void* cookie, const char* txt); void printTypeCode(uint32_t typeCode, debugPrintFunc func = 0, void* cookie = 0); + void printHexData(int32_t indent, const void *buf, size_t length, size_t bytesPerLine=16, int32_t singleLineBytesCutoff=16, size_t alignment=0, bool cArrayStyle=false, debugPrintFunc func = 0, void* cookie = 0); +#ifdef __cplusplus +} +#endif + +// --------------------------------------------------------------------------- }; // namespace android #endif // ANDROID_DEBUG_H From 07fcf4c3a91e421dc6f3d17f28264d18e8b2bfdb Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Tue, 9 Jun 2009 21:38:08 -0700 Subject: [PATCH 47/83] revive the copybit test. --- include/private/ui/SurfaceBuffer.h | 1 + opengl/tests/copybits/Android.mk | 2 +- opengl/tests/copybits/copybits.cpp | 156 ++++++++++++----------------- 3 files changed, 66 insertions(+), 93 deletions(-) diff --git a/include/private/ui/SurfaceBuffer.h b/include/private/ui/SurfaceBuffer.h index c45abeb73c250..bf684060218a6 100644 --- a/include/private/ui/SurfaceBuffer.h +++ b/include/private/ui/SurfaceBuffer.h @@ -29,6 +29,7 @@ namespace android { // --------------------------------------------------------------------------- class BufferMapper; +class Parcel; class Rect; class Surface; class SurfaceBuffer; diff --git a/opengl/tests/copybits/Android.mk b/opengl/tests/copybits/Android.mk index 2876a1eec4424..d5ded42b5fb18 100644 --- a/opengl/tests/copybits/Android.mk +++ b/opengl/tests/copybits/Android.mk @@ -14,5 +14,5 @@ LOCAL_MODULE:= test-opengl-copybits LOCAL_MODULE_TAGS := tests -##include $(BUILD_EXECUTABLE) +include $(BUILD_EXECUTABLE) diff --git a/opengl/tests/copybits/copybits.cpp b/opengl/tests/copybits/copybits.cpp index 404932ad24705..d15526c65e948 100644 --- a/opengl/tests/copybits/copybits.cpp +++ b/opengl/tests/copybits/copybits.cpp @@ -17,7 +17,8 @@ #include -#include +#include +#include #include #include @@ -53,70 +54,58 @@ int create_physical_texture(); int readTimer(); // =========================================================================== -// Buffer and implementation of android_native_buffer_t +// Buffer an implementation of android_native_buffer_t // =========================================================================== class NativeBuffer; -class Buffer : public android_native_buffer_t, - public LightRefBase +class Buffer : public android::SurfaceBuffer { public: - // creates w * h buffer - Buffer(uint32_t w, uint32_t h, PixelFormat format, int usage); + Buffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage); // return status status_t initCheck() const; - - uint32_t getWidth() const { return mWidth; } - uint32_t getHeight() const { return mHeight; } - uint32_t getStride() const { return mStride; } - uint32_t getUsage() const { return mUsage; } - PixelFormat getPixelFormat() const { return mFormat; } - buffer_handle_t getHandle() const { return mBufferHandle; } - + uint32_t getWidth() const { return width; } + uint32_t getHeight() const { return height; } + uint32_t getStride() const { return stride; } + uint32_t getUsage() const { return usage; } + PixelFormat getPixelFormat() const { return format; } + + android_native_buffer_t* getNativeBuffer() const; void setPixel(int x, int y, int r, int g, int b, int a); + status_t lock(GGLSurface* surface, uint32_t usage); + void lock() { + GGLSurface s; + lock(&s, GRALLOC_USAGE_SW_WRITE_OFTEN); + mData = (void*)s.data; + } + private: friend class LightRefBase; Buffer(const Buffer& rhs); - ~Buffer(); + virtual ~Buffer(); Buffer& operator = (const Buffer& rhs); const Buffer& operator = (const Buffer& rhs) const; status_t initSize(uint32_t w, uint32_t h); - static void incRef(android_native_base_t* buffer); - static void decRef(android_native_base_t* buffer); - static int getHandlePriv(android_native_buffer_t const * buffer, - buffer_handle_t* handle); - - buffer_handle_t mBufferHandle; ssize_t mInitCheck; - - uint32_t mWidth; - uint32_t mHeight; - uint32_t mStride; + uint32_t mFlags; uint32_t mVStride; - PixelFormat mFormat; void* mData; - uint32_t mUsage; }; -Buffer::Buffer(uint32_t w, uint32_t h, PixelFormat format, int usage) - : mBufferHandle(0), mInitCheck(NO_INIT), - mWidth(0), mHeight(0), mStride(0), mVStride(0), mFormat(format), mData(0), - mUsage(usage) +Buffer::Buffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage) + : SurfaceBuffer(), mInitCheck(NO_INIT), mVStride(0) { - common.magic = ANDROID_NATIVE_BUFFER_MAGIC; - common.version = sizeof(android_native_buffer_t); - common.incRef = incRef; - common.decRef = decRef; - android_native_buffer_t::getHandle = getHandlePriv; + this->usage = usage; + this->format = format; if (w>0 && h>0) { mInitCheck = initSize(w, h); } @@ -124,66 +113,30 @@ Buffer::Buffer(uint32_t w, uint32_t h, PixelFormat format, int usage) Buffer::~Buffer() { - if (mBufferHandle) { - - gralloc_module_t* mod = (gralloc_module_t*)sAllocDev->common.module; - mod->unmap(mod, mBufferHandle); - - sAllocDev->free(sAllocDev, mBufferHandle); + if (handle) { + sAllocDev->free(sAllocDev, handle); } } -void Buffer::incRef(android_native_base_t* buffer) { - Buffer* self = static_cast( - reinterpret_cast(buffer)); - self->incStrong(self); -} - -void Buffer::decRef(android_native_base_t* buffer) { - Buffer* self = static_cast( - reinterpret_cast(buffer)); - self->decStrong(self); -} - -int Buffer::getHandlePriv(android_native_buffer_t const * buffer, - buffer_handle_t* handle) { - Buffer const * self = static_cast(buffer); - *handle = self->getHandle(); - return 0; -} - status_t Buffer::initCheck() const { return mInitCheck; } android_native_buffer_t* Buffer::getNativeBuffer() const { - Buffer* that = const_cast(this); - that->android_native_buffer_t::width = mWidth; - that->android_native_buffer_t::height = mHeight; - that->android_native_buffer_t::stride = mStride; - that->android_native_buffer_t::format = mFormat; - that->android_native_buffer_t::usage = mUsage; - that->android_native_buffer_t::bits = mData; - return static_cast(that); + return static_cast(const_cast(this)); } status_t Buffer::initSize(uint32_t w, uint32_t h) { status_t err = NO_ERROR; - int32_t stride; - err = sAllocDev->alloc(sAllocDev, w, h, mFormat, mUsage, &mBufferHandle, &stride); - + err = sAllocDev->alloc(sAllocDev, w, h, format, usage, &handle, &stride); + if (err == NO_ERROR) { - void* addr = 0; - gralloc_module_t* mod = (gralloc_module_t*)sAllocDev->common.module; - err = mod->map(mod, mBufferHandle, &addr); if (err == NO_ERROR) { - mData = addr; - mWidth = w; - mHeight = h; - mStride = stride; + width = w; + height = h; mVStride = 0; } } @@ -191,14 +144,31 @@ status_t Buffer::initSize(uint32_t w, uint32_t h) return err; } +status_t Buffer::lock(GGLSurface* sur, uint32_t usage) +{ + void* vaddr; + status_t res = SurfaceBuffer::lock(usage, &vaddr); + if (res == NO_ERROR && sur) { + sur->version = sizeof(GGLSurface); + sur->width = width; + sur->height = height; + sur->stride = stride; + sur->format = format; + sur->vstride = mVStride; + sur->data = static_cast(vaddr); + } + return res; +} + + void Buffer::setPixel(int x, int y, int r, int g, int b, int a) { - if (x < 0 || (unsigned int) x >= mWidth - || y < 0 || (unsigned int) y >= mHeight) { + if (x < 0 || (unsigned int) x >= width + || y < 0 || (unsigned int) y >= height) { // clipped return; } - int index = mStride * y + x; - switch (mFormat) { + int index = stride * y + x; + switch (format) { case HAL_PIXEL_FORMAT_RGB_565: { unsigned short val = (unsigned short) ( ((0x1f & (r >> 3)) << 11) @@ -340,6 +310,10 @@ int init_gl_surface(void) return 0; } +#if EGL_ANDROID_swap_rectangle + eglSetSwapRectangleANDROID(eglDisplay, eglSurface, 0, 0, 320, 480); +#endif + return 1; } @@ -347,7 +321,7 @@ void free_gl_surface(void) { if (eglDisplay != EGL_NO_DISPLAY) { - eglMakeCurrent( EGL_NO_DISPLAY, EGL_NO_SURFACE, + eglMakeCurrent( eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT ); eglDestroyContext( eglDisplay, eglContext ); eglDestroySurface( eglDisplay, eglSurface ); @@ -465,14 +439,11 @@ int create_physical_texture(unsigned int w, unsigned int h) return -1; } - if (buffer->bits == NULL) { - printf("No bits allocated for image.\n"); - return -2; - } - + bufferObject->lock(); setOrientedCheckerboard(bufferObject); // setSmoothGradient(bufferObject); // setSmoothAlphaGradient(bufferObject); + bufferObject->unlock(); glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); @@ -658,6 +629,7 @@ int testRot90() glDisable(GL_CULL_FACE); for(int frame = 0; frame < 2; frame++) { + LOGD("frame = %d", frame); glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); int baseX = 10; for (int x = 0; x < SCALE_COUNT; x++) { @@ -708,7 +680,7 @@ int testRot90() glVertexPointer(2, GL_FIXED, 0, vertices); glTexCoordPointer(2, GL_FIXED, 0, texCoords); - LOGW("testRot90 %d, %d %d, %d", baseX, baseY, width, height); + LOGD("testRot90 %d, %d %d, %d", baseX, baseY, width, height); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); baseY += height + 10; @@ -744,8 +716,8 @@ int main(int argc, char **argv) printf("Start test...\n"); // testTime(); - // testStretch(); - testRot90(); + testStretch(); + //testRot90(); free_gl_surface(); return 0; From 350d651706d8f484d9aeb539d491526f822fa84a Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Wed, 10 Jun 2009 16:01:54 -0700 Subject: [PATCH 48/83] fix a bug where copybit only renders in the first buffer when used with s/w GL --- include/private/opengles/gl_context.h | 5 ++--- opengl/libagl/TextureObjectManager.cpp | 2 +- opengl/libagl/TextureObjectManager.h | 2 +- opengl/libagl/copybit.cpp | 27 ++++++++++++++++---------- opengl/libagl/copybit.h | 4 ++-- opengl/libagl/egl.cpp | 10 +++++----- opengl/libagl/state.cpp | 2 +- opengl/libagl/texture.cpp | 10 ++++------ opengl/tests/copybits/copybits.cpp | 16 +++++++-------- 9 files changed, 40 insertions(+), 38 deletions(-) diff --git a/include/private/opengles/gl_context.h b/include/private/opengles/gl_context.h index 641961f3a822e..3b406779af5ab 100644 --- a/include/private/opengles/gl_context.h +++ b/include/private/opengles/gl_context.h @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -600,9 +601,7 @@ struct copybits_context_t { copybit_device_t* blitEngine; int32_t minScale; int32_t maxScale; - // File descriptor of current drawing surface, if it's suitable for use as - // a copybits destination, else -1. - int drawSurfaceFd; + buffer_handle_t drawSurfaceBuffer; }; struct ogles_context_t { diff --git a/opengl/libagl/TextureObjectManager.cpp b/opengl/libagl/TextureObjectManager.cpp index 9deb2cf9eea41..255ccac3565ba 100644 --- a/opengl/libagl/TextureObjectManager.cpp +++ b/opengl/libagl/TextureObjectManager.cpp @@ -56,7 +56,7 @@ void EGLTextureObject::init() generate_mipmap = GL_FALSE; direct = GL_FALSE; #ifdef LIBAGL_USE_GRALLOC_COPYBITS - copybits_fd = -1; + try_copybit = false; #endif // LIBAGL_USE_GRALLOC_COPYBITS buffer = 0; } diff --git a/opengl/libagl/TextureObjectManager.h b/opengl/libagl/TextureObjectManager.h index e0eadf147959c..496e6947d7371 100644 --- a/opengl/libagl/TextureObjectManager.h +++ b/opengl/libagl/TextureObjectManager.h @@ -80,7 +80,7 @@ public: GLint generate_mipmap; GLint direct; #ifdef LIBAGL_USE_GRALLOC_COPYBITS - int copybits_fd; + bool try_copybit; #endif // LIBAGL_USE_GRALLOC_COPYBITS android_native_buffer_t* buffer; }; diff --git a/opengl/libagl/copybit.cpp b/opengl/libagl/copybit.cpp index 427e42aaf292c..a539a2bdd5d7b 100644 --- a/opengl/libagl/copybit.cpp +++ b/opengl/libagl/copybit.cpp @@ -27,23 +27,28 @@ #include "primitives.h" #include "texture.h" #include "BufferObjectManager.h" - #include "TextureObjectManager.h" + #include #include +#include #include "gralloc_priv.h" // ---------------------------------------------------------------------------- namespace android { -static void textureToCopyBitImage(const GGLSurface* surface, int fd, copybit_image_t* img) { +static void textureToCopyBitImage( + const GGLSurface* surface, buffer_handle_t buffer, copybit_image_t* img) +{ + // we know private_handle_t is good here + private_handle_t* hnd = (private_handle_t*)buffer; img->w = surface->stride; img->h = surface->height; img->format = surface->format; - img->offset = 0; + img->offset = hnd->offset; img->base = surface->data; - img->fd = fd; + img->fd = hnd->fd; } struct clipRectRegion : public copybit_region_t { @@ -109,7 +114,7 @@ static inline int fixedToByte(GGLfixed val) { static bool checkContext(ogles_context_t* c) { - // By convenction copybitQuickCheckContext() has already returned true. + // By convention copybitQuickCheckContext() has already returned true. // avoid checking the same information again. if (c->copybits.blitEngine == NULL @@ -118,7 +123,7 @@ static bool checkContext(ogles_context_t* c) { return false; } - // Note: The drawSurfaceFd is only set for destination + // Note: The drawSurfaceBuffer is only set for destination // surfaces types that are supported by the hardware and // do not have an alpha channel. So we don't have to re-check that here. @@ -237,18 +242,20 @@ static bool copybit(GLint x, GLint y, // LOGW("calling copybits"); copybit_device_t* copybit = c->copybits.blitEngine; + copybit_image_t dst; - textureToCopyBitImage(&cbSurface, c->copybits.drawSurfaceFd, &dst); + buffer_handle_t target_hnd = c->copybits.drawSurfaceBuffer; + textureToCopyBitImage(&cbSurface, target_hnd, &dst); copybit_rect_t drect = {x, y, x+w, y+h}; + // we know private_handle_t is good here copybit_image_t src; - textureToCopyBitImage(&textureObject->surface, textureObject->copybits_fd, - &src); + buffer_handle_t source_hnd = textureObject->buffer->handle; + textureToCopyBitImage(&textureObject->surface, source_hnd, &src); copybit_rect_t srect = { Ucr, Vcr + Hcr, Ucr + Wcr, Vcr }; copybit->set_parameter(copybit, COPYBIT_TRANSFORM, transform); copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, planeAlpha); - copybit->set_parameter(copybit, COPYBIT_DITHER, (enables & GGL_ENABLE_DITHER) ? COPYBIT_ENABLE : COPYBIT_DISABLE); diff --git a/opengl/libagl/copybit.h b/opengl/libagl/copybit.h index 1888aee1929ed..401b68c2914a4 100644 --- a/opengl/libagl/copybit.h +++ b/opengl/libagl/copybit.h @@ -32,9 +32,9 @@ bool drawTrangleFanWithCopybit_impl(ogles_context_t* c, GLint first, GLsizei count); inline bool copybitQuickCheckContext(ogles_context_t* c) { - return c->copybits.drawSurfaceFd >= 0 + return c->copybits.drawSurfaceBuffer != 0 && c->rasterizer.state.enabled_tmu == 1 - && c->textures.tmu[0].texture->copybits_fd >= 0; + && c->textures.tmu[0].texture->try_copybit; } /* diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp index 0df2bbaa584f6..c6d50578869aa 100644 --- a/opengl/libagl/egl.cpp +++ b/opengl/libagl/egl.cpp @@ -551,20 +551,20 @@ EGLBoolean egl_window_surface_v2_t::bindDrawSurface(ogles_context_t* gl) gl->rasterizer.procs.colorBuffer(gl, &buffer); if (depth.data != gl->rasterizer.state.buffers.depth.data) gl->rasterizer.procs.depthBuffer(gl, &depth); + #ifdef LIBAGL_USE_GRALLOC_COPYBITS - gl->copybits.drawSurfaceFd = -1; + gl->copybits.drawSurfaceBuffer = 0; if (supportedCopybitsDestinationFormat(buffer.format)) { buffer_handle_t handle = this->buffer->handle; if (handle != NULL) { private_handle_t* hand = private_handle_t::dynamicCast(handle); - if (hand != NULL) { - if (hand->usesPhysicallyContiguousMemory()) { - gl->copybits.drawSurfaceFd = hand->fd; - } + if (hand != NULL && hand->usesPhysicallyContiguousMemory()) { + gl->copybits.drawSurfaceBuffer = handle; } } } #endif // LIBAGL_USE_GRALLOC_COPYBITS + return EGL_TRUE; } EGLBoolean egl_window_surface_v2_t::bindReadSurface(ogles_context_t* gl) diff --git a/opengl/libagl/state.cpp b/opengl/libagl/state.cpp index a00f779d6d35a..a59b3b046e3f5 100644 --- a/opengl/libagl/state.cpp +++ b/opengl/libagl/state.cpp @@ -101,7 +101,7 @@ ogles_context_t *ogles_init(size_t extra) c->copybits.blitEngine = NULL; c->copybits.minScale = 0; c->copybits.maxScale = 0; - c->copybits.drawSurfaceFd = -1; + c->copybits.drawSurfaceBuffer = 0; #ifdef LIBAGL_USE_GRALLOC_COPYBITS hw_module_t const* module; diff --git a/opengl/libagl/texture.cpp b/opengl/libagl/texture.cpp index d675107ca0b12..05fd46e5a2b0c 100644 --- a/opengl/libagl/texture.cpp +++ b/opengl/libagl/texture.cpp @@ -1544,12 +1544,10 @@ void glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image) * */ #ifdef LIBAGL_USE_GRALLOC_COPYBITS - tex->copybits_fd = -1; - private_handle_t* hand; - if ((hand = private_handle_t::dynamicCast(native_buffer->handle)) != NULL) { - if (hand->usesPhysicallyContiguousMemory()) { - tex->copybits_fd = hand->fd; - } + tex->try_copybit = false; + private_handle_t* hnd = private_handle_t::dynamicCast(native_buffer->handle); + if (hnd && hnd->usesPhysicallyContiguousMemory()) { + tex->try_copybit = true; } #endif // LIBAGL_USE_GRALLOC_COPYBITS } diff --git a/opengl/tests/copybits/copybits.cpp b/opengl/tests/copybits/copybits.cpp index d15526c65e948..f8ca9b2e0eeea 100644 --- a/opengl/tests/copybits/copybits.cpp +++ b/opengl/tests/copybits/copybits.cpp @@ -96,13 +96,11 @@ private: status_t initSize(uint32_t w, uint32_t h); ssize_t mInitCheck; - uint32_t mFlags; - uint32_t mVStride; void* mData; }; Buffer::Buffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage) - : SurfaceBuffer(), mInitCheck(NO_INIT), mVStride(0) + : SurfaceBuffer(), mInitCheck(NO_INIT) { this->usage = usage; this->format = format; @@ -137,7 +135,6 @@ status_t Buffer::initSize(uint32_t w, uint32_t h) if (err == NO_ERROR) { width = w; height = h; - mVStride = 0; } } @@ -154,7 +151,6 @@ status_t Buffer::lock(GGLSurface* sur, uint32_t usage) sur->height = height; sur->stride = stride; sur->format = format; - sur->vstride = mVStride; sur->data = static_cast(vaddr); } return res; @@ -355,7 +351,7 @@ void init_scene(void) // #define USE_ALPHA_COLOR #define USE_GL_REPLACE -// #define USE_GL_MODULATE +//#define USE_GL_MODULATE // #define USE_BLEND @@ -479,7 +475,7 @@ static const int SCALE_COUNT = 12; int scale(int base, int factor) { static const float kTable[SCALE_COUNT] = { - 0.1f, 0.25f, 0.5f, 0.75f, 1.0f, + 0.24f, 0.25f, 0.5f, 0.75f, 1.0f, 1.5f, 2.0f, 2.5f, 3.0f, 3.5f, 4.0f, 5.0f }; return base * kTable[factor]; @@ -570,10 +566,10 @@ int testStretch() return -1; } // Need to do a dummy eglSwapBuffers first. Don't know why. - glClearColor(0.4, 1.0, 0.4, 0.4); + glClearColor(0.4, 1.0, 0.4, 1.0); glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); eglSwapBuffers(eglDisplay, eglSurface); - + int cropRect[4] = {0,HEIGHT,WIDTH,-HEIGHT}; // Left bottom width height. Width and Height can be neg to flip. glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, cropRect); @@ -592,6 +588,8 @@ int testStretch() } eglSwapBuffers(eglDisplay, eglSurface); + LOGD("wait 1s"); + usleep(1000000); } return 0; } From e19476214a2fe718c82461f54e6b56cee7faa5f4 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Thu, 11 Jun 2009 17:19:54 -0700 Subject: [PATCH 49/83] protect ANDROID specific egl extension with #define --- libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp index 52b0f685c60fb..3f19c85a54442 100644 --- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp +++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp @@ -199,7 +199,7 @@ void DisplayHardware::init(uint32_t dpy) */ surface = eglCreateWindowSurface(display, config, mNativeWindow.get(), NULL); - checkEGLErrors("eglCreateDisplaySurfaceANDROID"); + checkEGLErrors("eglCreateWindowSurface"); if (eglQuerySurface(display, surface, EGL_SWAP_BEHAVIOR, &dummy) == EGL_TRUE) { if (dummy == EGL_BUFFER_PRESERVED) { @@ -207,9 +207,11 @@ void DisplayHardware::init(uint32_t dpy) } } +#ifdef EGL_ANDROID_swap_rectangle if (strstr(egl_extensions, "EGL_ANDROID_swap_rectangle")) { mFlags |= SWAP_RECTANGLE; } +#endif mDpiX = mNativeWindow->xdpi; mDpiX = mNativeWindow->ydpi; @@ -309,6 +311,7 @@ void DisplayHardware::flip(const Region& dirty) const EGLDisplay dpy = mDisplay; EGLSurface surface = mSurface; +#ifdef EGL_ANDROID_swap_rectangle if (mFlags & SWAP_RECTANGLE) { Region newDirty(dirty); newDirty.andSelf(Rect(mWidth, mHeight)); @@ -316,7 +319,8 @@ void DisplayHardware::flip(const Region& dirty) const eglSetSwapRectangleANDROID(dpy, surface, b.left, b.top, b.width(), b.height()); } - +#endif + if (mFlags & UPDATE_ON_DEMAND) { mNativeWindow->setUpdateRectangle(dirty.bounds()); } From 151e859e0fc3a930bdf6d270d275e69e9eba0cbf Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Mon, 15 Jun 2009 18:24:59 -0700 Subject: [PATCH 50/83] new Permission class used to improve permission checks speed (by caching results) --- include/binder/IServiceManager.h | 2 + include/binder/Permission.h | 68 ++++++++++++++++++++ libs/binder/Android.mk | 1 + libs/binder/IServiceManager.cpp | 15 +++-- libs/binder/Permission.cpp | 88 ++++++++++++++++++++++++++ libs/surfaceflinger/LayerBase.cpp | 23 +++---- libs/surfaceflinger/SurfaceFlinger.cpp | 35 ++++------ libs/surfaceflinger/SurfaceFlinger.h | 7 +- 8 files changed, 197 insertions(+), 42 deletions(-) create mode 100644 include/binder/Permission.h create mode 100644 libs/binder/Permission.cpp diff --git a/include/binder/IServiceManager.h b/include/binder/IServiceManager.h index ea149ddaabeae..24e9e992cc61a 100644 --- a/include/binder/IServiceManager.h +++ b/include/binder/IServiceManager.h @@ -78,6 +78,8 @@ status_t getService(const String16& name, sp* outService) bool checkCallingPermission(const String16& permission); bool checkCallingPermission(const String16& permission, int32_t* outPid, int32_t* outUid); +bool checkPermission(const String16& permission, pid_t pid, uid_t uid); + // ---------------------------------------------------------------------- diff --git a/include/binder/Permission.h b/include/binder/Permission.h new file mode 100644 index 0000000000000..9542d50663331 --- /dev/null +++ b/include/binder/Permission.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2009 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. + */ + +#ifndef BINDER_PERMISSION_H +#define BINDER_PERMISSION_H + +#include +#include + +#include +#include +#include + +namespace android { +// --------------------------------------------------------------------------- + +/* + * Permission caches the result of the permission check for the given + * permission name and the provided uid/pid. It also handles a few + * known cases efficiently (caller is in the same process or is root). + * The package manager does something similar but lives in dalvik world + * and is therefore extremely slow to access. + */ + +class Permission +{ +public: + Permission(char const* name); + Permission(const String16& name); + Permission(const Permission& rhs); + virtual ~Permission(); + + bool operator < (const Permission& rhs) const; + + // checks the current binder call's caller has access to this permission + bool checkCalling() const; + + // checks the specified pid/uid has access to this permission + bool check(pid_t pid, uid_t uid) const; + +protected: + virtual bool doCheckPermission(pid_t pid, uid_t uid) const; + +private: + Permission& operator = (const Permission& rhs) const; + const String16 mPermissionName; + mutable SortedVector mGranted; + const pid_t mPid; + mutable Mutex mLock; +}; + +// --------------------------------------------------------------------------- +}; // namespace android + +#endif /* BINDER_PERMISSION_H */ diff --git a/libs/binder/Android.mk b/libs/binder/Android.mk index c4d695e8d56f8..2df6775205477 100644 --- a/libs/binder/Android.mk +++ b/libs/binder/Android.mk @@ -29,6 +29,7 @@ LOCAL_SRC_FILES:= \ MemoryHeapBase.cpp \ MemoryHeapPmem.cpp \ Parcel.cpp \ + Permission.cpp \ ProcessState.cpp \ Static.cpp diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp index 88774e79b90c4..0cf415860909b 100644 --- a/libs/binder/IServiceManager.cpp +++ b/libs/binder/IServiceManager.cpp @@ -19,8 +19,8 @@ #include #include -#include #include +#include #include #include #include @@ -53,14 +53,19 @@ bool checkCallingPermission(const String16& permission) static String16 _permission("permission"); + bool checkCallingPermission(const String16& permission, int32_t* outPid, int32_t* outUid) { IPCThreadState* ipcState = IPCThreadState::self(); - int32_t pid = ipcState->getCallingPid(); - int32_t uid = ipcState->getCallingUid(); + pid_t pid = ipcState->getCallingPid(); + uid_t uid = ipcState->getCallingUid(); if (outPid) *outPid = pid; - if (outUid) *outUid= uid; - + if (outUid) *outUid = uid; + return checkPermission(permission, pid, uid); +} + +bool checkPermission(const String16& permission, pid_t pid, uid_t uid) +{ sp pc; gDefaultServiceManagerLock.lock(); pc = gPermissionController; diff --git a/libs/binder/Permission.cpp b/libs/binder/Permission.cpp new file mode 100644 index 0000000000000..fd8fe6983d5d9 --- /dev/null +++ b/libs/binder/Permission.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2009 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. + */ + +#include +#include +#include +#include +#include + +namespace android { +// --------------------------------------------------------------------------- + +Permission::Permission(char const* name) + : mPermissionName(name), mPid(getpid()) +{ +} + +Permission::Permission(const String16& name) + : mPermissionName(name), mPid(getpid()) +{ +} + +Permission::Permission(const Permission& rhs) + : mPermissionName(rhs.mPermissionName), + mGranted(rhs.mGranted), + mPid(rhs.mPid) +{ +} + +Permission::~Permission() +{ +} + +bool Permission::operator < (const Permission& rhs) const +{ + return mPermissionName < rhs.mPermissionName; +} + +bool Permission::checkCalling() const +{ + IPCThreadState* ipcState = IPCThreadState::self(); + pid_t pid = ipcState->getCallingPid(); + uid_t uid = ipcState->getCallingUid(); + return doCheckPermission(pid, uid); +} + +bool Permission::check(pid_t pid, uid_t uid) const +{ + return doCheckPermission(pid, uid); +} + +bool Permission::doCheckPermission(pid_t pid, uid_t uid) const +{ + if ((uid == 0) || (pid == mPid)) { + // root and ourselves is always okay + return true; + } else { + // see if we already granted this permission for this uid + Mutex::Autolock _l(mLock); + if (mGranted.indexOf(uid) >= 0) + return true; + } + + bool granted = checkPermission(mPermissionName, pid, uid); + if (granted) { + Mutex::Autolock _l(mLock); + // no need to check again, the old item will be replaced if it is + // already there. + mGranted.add(uid); + } + return granted; +} + +// --------------------------------------------------------------------------- +}; // namespace android diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp index c678711a5439b..b65c983869c45 100644 --- a/libs/surfaceflinger/LayerBase.cpp +++ b/libs/surfaceflinger/LayerBase.cpp @@ -729,27 +729,20 @@ void LayerBaseClient::Surface::getSurfaceData( } status_t LayerBaseClient::Surface::onTransact( - uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) + uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { switch (code) { case REGISTER_BUFFERS: case UNREGISTER_BUFFERS: case CREATE_OVERLAY: { - // codes that require permission check - IPCThreadState* ipc = IPCThreadState::self(); - const int pid = ipc->getCallingPid(); - const int self_pid = getpid(); - if (LIKELY(pid != self_pid)) { - // we're called from a different process, do the real check - if (!checkCallingPermission( - String16("android.permission.ACCESS_SURFACE_FLINGER"))) - { - const int uid = ipc->getCallingUid(); - LOGE("Permission Denial: " - "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); - return PERMISSION_DENIED; - } + if (!mFlinger->mAccessSurfaceFlinger.checkCalling()) { + IPCThreadState* ipc = IPCThreadState::self(); + const int pid = ipc->getCallingPid(); + const int uid = ipc->getCallingUid(); + LOGE("Permission Denial: " + "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); + return PERMISSION_DENIED; } } } diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp index 0d1be2d06c979..a56ecd886e3ee 100644 --- a/libs/surfaceflinger/SurfaceFlinger.cpp +++ b/libs/surfaceflinger/SurfaceFlinger.cpp @@ -175,6 +175,9 @@ SurfaceFlinger::SurfaceFlinger() mTransactionCount(0), mLayersRemoved(false), mBootTime(systemTime()), + mHardwareTest("android.permission.HARDWARE_TEST"), + mAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"), + mDump("android.permission.DUMP"), mLastScheduledBroadcast(NULL), mVisibleRegionsDirty(false), mDeferReleaseConsole(false), @@ -1430,9 +1433,7 @@ status_t SurfaceFlinger::dump(int fd, const Vector& args) const size_t SIZE = 1024; char buffer[SIZE]; String8 result; - if (checkCallingPermission( - String16("android.permission.DUMP")) == false) - { // not allowed + if (!mDump.checkCalling()) { snprintf(buffer, SIZE, "Permission Denial: " "can't dump SurfaceFlinger from pid=%d, uid=%d\n", IPCThreadState::self()->getCallingPid(), @@ -1534,29 +1535,21 @@ status_t SurfaceFlinger::onTransact( IPCThreadState* ipc = IPCThreadState::self(); const int pid = ipc->getCallingPid(); const int uid = ipc->getCallingUid(); - const int self_pid = getpid(); - if (UNLIKELY(pid != self_pid && uid != AID_GRAPHICS)) { - // we're called from a different process, do the real check - if (!checkCallingPermission( - String16("android.permission.ACCESS_SURFACE_FLINGER"))) - { - LOGE("Permission Denial: " - "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); - return PERMISSION_DENIED; - } + if ((uid != AID_GRAPHICS) && !mAccessSurfaceFlinger.check(pid, uid)) { + LOGE("Permission Denial: " + "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); + return PERMISSION_DENIED; } } } - status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags); if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) { - // HARDWARE_TEST stuff... - if (UNLIKELY(checkCallingPermission( - String16("android.permission.HARDWARE_TEST")) == false)) - { // not allowed - LOGE("Permission Denial: pid=%d, uid=%d\n", - IPCThreadState::self()->getCallingPid(), - IPCThreadState::self()->getCallingUid()); + if (UNLIKELY(!mHardwareTest.checkCalling())) { + IPCThreadState* ipc = IPCThreadState::self(); + const int pid = ipc->getCallingPid(); + const int uid = ipc->getCallingUid(); + LOGE("Permission Denial: " + "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); return PERMISSION_DENIED; } int n; diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h index a21e18644be1a..ebe315a450f74 100644 --- a/libs/surfaceflinger/SurfaceFlinger.h +++ b/libs/surfaceflinger/SurfaceFlinger.h @@ -25,9 +25,11 @@ #include #include #include -#include #include +#include +#include + #include #include #include @@ -321,6 +323,9 @@ private: surface_flinger_cblk_t* mServerCblk; GLuint mWormholeTexName; nsecs_t mBootTime; + Permission mHardwareTest; + Permission mAccessSurfaceFlinger; + Permission mDump; // Can only accessed from the main thread, these members // don't need synchronization From 4d63fb113b542f0474c16d8f2c8a1240b44f0ca2 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Tue, 16 Jun 2009 18:08:29 -0700 Subject: [PATCH 51/83] fix a scissor bug in the GLES-on-top-of copybit code --- opengl/libagl/copybit.cpp | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/opengl/libagl/copybit.cpp b/opengl/libagl/copybit.cpp index a539a2bdd5d7b..d57a6e429081d 100644 --- a/opengl/libagl/copybit.cpp +++ b/opengl/libagl/copybit.cpp @@ -52,28 +52,25 @@ static void textureToCopyBitImage( } struct clipRectRegion : public copybit_region_t { - clipRectRegion(ogles_context_t* c) { - next = iterate; - int x = c->viewport.scissor.x; - int y = c->viewport.scissor.y; - r.l = x; - r.t = y; - r.r = x + c->viewport.scissor.w; - r.b = y + c->viewport.scissor.h; - firstTime = true; + clipRectRegion(ogles_context_t* c) + { + scissor_t const* scissor = &c->rasterizer.state.scissor; + r.l = scissor->left; + r.t = scissor->top; + r.r = scissor->right; + r.b = scissor->bottom; + next = iterate; } private: static int iterate(copybit_region_t const * self, copybit_rect_t* rect) { - clipRectRegion* myself = (clipRectRegion*) self; - if (myself->firstTime) { - myself->firstTime = false; - *rect = myself->r; - return 1; - } + *rect = static_cast(self)->r; + const_cast(self)->next = iterate_done; + return 1; + } + static int iterate_done(copybit_region_t const *, copybit_rect_t*) { return 0; } - mutable copybit_rect_t r; - mutable bool firstTime; + copybit_rect_t r; }; static bool supportedCopybitsFormat(int format) { From 03a1b0116b115c214c16fa1a02a46999312fd0f2 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Wed, 17 Jun 2009 21:18:56 -0700 Subject: [PATCH 52/83] s/w OpenGL no detects and handles all any combinations of triangle fans corresponding to a rectangle this allows fallback to faster copybit code in almost all cases. --- opengl/libagl/array.cpp | 2 +- opengl/libagl/copybit.cpp | 191 +++++++++++++++++++++++--------------- opengl/libagl/copybit.h | 10 +- 3 files changed, 124 insertions(+), 79 deletions(-) diff --git a/opengl/libagl/array.cpp b/opengl/libagl/array.cpp index cffe880edd0d9..f414ee5f7c3ad 100644 --- a/opengl/libagl/array.cpp +++ b/opengl/libagl/array.cpp @@ -708,7 +708,7 @@ void drawPrimitivesTriangleStrip(ogles_context_t* c, void drawPrimitivesTriangleFan(ogles_context_t* c, GLint first, GLsizei count) { #ifdef LIBAGL_USE_GRALLOC_COPYBITS - if (drawTrangleFanWithCopybit(c, first, count)) { + if (drawTriangleFanWithCopybit(c, first, count)) { return; } #endif // LIBAGL_USE_GRALLOC_COPYBITS diff --git a/opengl/libagl/copybit.cpp b/opengl/libagl/copybit.cpp index d57a6e429081d..0736b6b7b3740 100644 --- a/opengl/libagl/copybit.cpp +++ b/opengl/libagl/copybit.cpp @@ -34,6 +34,9 @@ #include #include "gralloc_priv.h" + +#define DEBUG_COPYBIT true + // ---------------------------------------------------------------------------- namespace android { @@ -114,9 +117,14 @@ static bool checkContext(ogles_context_t* c) { // By convention copybitQuickCheckContext() has already returned true. // avoid checking the same information again. - if (c->copybits.blitEngine == NULL - || (c->rasterizer.state.enables - & (GGL_ENABLE_DEPTH_TEST|GGL_ENABLE_FOG)) != 0) { + if (c->copybits.blitEngine == NULL) { + LOGD_IF(DEBUG_COPYBIT, "no copybit hal"); + return false; + } + + if (c->rasterizer.state.enables + & (GGL_ENABLE_DEPTH_TEST|GGL_ENABLE_FOG)) { + LOGD_IF(DEBUG_COPYBIT, "depth test and/or fog"); return false; } @@ -129,6 +137,7 @@ static bool checkContext(ogles_context_t* c) { EGLTextureObject* textureObject = u.texture; if (!supportedCopybitsFormat(textureObject->surface.format)) { + LOGD_IF(DEBUG_COPYBIT, "texture format not supported"); return false; } return true; @@ -161,19 +170,25 @@ static bool copybit(GLint x, GLint y, || dtdy < c->copybits.minScale || dtdy > c->copybits.maxScale) { // The requested scale is out of the range the hardware // can support. + LOGD_IF(DEBUG_COPYBIT, + "scale out of range dsdx=%08x, dtdy=%08x", dsdx, dtdy); return false; } + /* int32_t texelArea = gglMulx(dtdy, dsdx); if (texelArea < FIXED_ONE && textureObject->mag_filter != GL_LINEAR) { // Non-linear filtering on a texture enlargement. + LOGD_IF(DEBUG_COPYBIT, "mag filter is not GL_LINEAR"); return false; } if (texelArea > FIXED_ONE && textureObject->min_filter != GL_LINEAR) { // Non-linear filtering on an texture shrink. + LOGD_IF(DEBUG_COPYBIT, "min filter is not GL_LINEAR"); return false; } + */ const uint32_t enables = c->rasterizer.state.enables; int planeAlpha = 255; @@ -192,6 +207,7 @@ static bool copybit(GLint x, GLint y, if (! (c->currentColorClamped.r == FIXED_ONE && c->currentColorClamped.g == FIXED_ONE && c->currentColorClamped.b == FIXED_ONE)) { + LOGD_IF(DEBUG_COPYBIT, "MODULATE and non white color"); return false; } planeAlpha = fixedToByte(c->currentColorClamped.a); @@ -199,6 +215,7 @@ static bool copybit(GLint x, GLint y, default: // Incompatible texture environment. + LOGD_IF(DEBUG_COPYBIT, "incompatible texture environment"); return false; } @@ -220,6 +237,7 @@ static bool copybit(GLint x, GLint y, && c->rasterizer.state.blend.dst == GL_ONE_MINUS_SRC_ALPHA && c->rasterizer.state.blend.alpha_separate == 0)) { // Incompatible blend mode. + LOGD_IF(DEBUG_COPYBIT, "incompatible blend mode"); return false; } blending = true; @@ -227,12 +245,14 @@ static bool copybit(GLint x, GLint y, // No blending is OK if we are not using alpha. if (srcTextureHasAlpha || planeAlpha != 255) { // Incompatible alpha + LOGD_IF(DEBUG_COPYBIT, "incompatible alpha"); return false; } } if (srcTextureHasAlpha && planeAlpha != 255) { // Can't do two types of alpha at once. + LOGD_IF(DEBUG_COPYBIT, "src alpha and plane alpha"); return false; } @@ -264,86 +284,116 @@ static bool copybit(GLint x, GLint y, /* * Try to draw a triangle fan with copybit, return false if we fail. */ -bool drawTrangleFanWithCopybit_impl(ogles_context_t* c, GLint first, GLsizei count) { - if (! checkContext(c)) { +bool drawTriangleFanWithCopybit_impl(ogles_context_t* c, GLint first, GLsizei count) +{ + if (!checkContext(c)) { return false; } c->arrays.compileElements(c, c->vc.vBuffer, 0, 4); - // Is the result a screen aligned rectangle? - int sx[4]; - int sy[4]; - for (int i = 0; i < 4; i++) { - GLfixed x = c->vc.vBuffer[i].window.x; - GLfixed y = c->vc.vBuffer[i].window.y; - if (x < 0 || y < 0 || (x & 0xf) != 0 || (y & 0xf) != 0) { - return false; - } - sx[i] = x >> 4; - sy[i] = y >> 4; - } - /* - * This is the pattern we're looking for: - * (2)--(3) - * |\ | - * | \ | - * | \ | - * | \| - * (1)--(0) - * - */ - int dx[4]; - int dy[4]; - for (int i = 0; i < 4; i++) { - int i1 = (i + 1) & 3; - dx[i] = sx[i] - sx[i1]; - dy[i] = sy[i] - sy[i1]; - } - if (dx[1] | dx[3] | dy[0] | dy[2]) { + // we detect if we're dealing with a rectangle, by comparing the + // rectangles {v0,v2} and {v1,v3} which should be identical. + + const vec4_t& v0 = c->vc.vBuffer[0].window; + const vec4_t& v1 = c->vc.vBuffer[1].window; + const vec4_t& v2 = c->vc.vBuffer[2].window; + const vec4_t& v3 = c->vc.vBuffer[3].window; + int l = min(v0.x, v2.x); + int b = min(v0.y, v2.y); + int r = max(v0.x, v2.x); + int t = max(v0.y, v2.y); + if ((l != min(v1.x, v3.x)) || (b != min(v1.y, v3.y)) || + (r != max(v1.x, v3.x)) || (t != max(v1.y, v3.y))) { + LOGD_IF(DEBUG_COPYBIT, "geometry not a rectangle"); return false; } - if (dx[0] != -dx[2] || dy[1] != -dy[3]) { + + const vec4_t& t0 = c->vc.vBuffer[0].texture[0]; + const vec4_t& t1 = c->vc.vBuffer[1].texture[0]; + const vec4_t& t2 = c->vc.vBuffer[2].texture[0]; + const vec4_t& t3 = c->vc.vBuffer[3].texture[0]; + int txl = min(t0.x, t2.x); + int txb = min(t0.y, t2.y); + int txr = max(t0.x, t2.x); + int txt = max(t0.y, t2.y); + if ((txl != min(t1.x, t3.x)) || (txb != min(t1.y, t3.y)) || + (txr != max(t1.x, t3.x)) || (txt != max(t1.y, t3.y))) { + LOGD_IF(DEBUG_COPYBIT, "texcoord not a rectangle"); + return false; + } + if ((txl != 0) || (txb != 0) || + (txr != FIXED_ONE) || (txt != FIXED_ONE)) { + // we could probably handle this case, if we wanted to + LOGD_IF(DEBUG_COPYBIT, "texture is cropped"); return false; } - int x = sx[1]; - int y = sy[1]; - int w = dx[0]; - int h = dy[3]; - - // We expect the texture coordinates to always be the unit square: - - static const GLfixed kExpectedUV[8] = { - 0, 0, - 0, FIXED_ONE, - FIXED_ONE, FIXED_ONE, - FIXED_ONE, 0 - }; - { - const GLfixed* pExpected = &kExpectedUV[0]; - for (int i = 0; i < 4; i++) { - GLfixed u = c->vc.vBuffer[i].texture[0].x; - GLfixed v = c->vc.vBuffer[i].texture[0].y; - if (u != *pExpected++ || v != *pExpected++) { - return false; - } - } + // at this point, we know we are dealing with a rectangle, so we + // only need to consider 3 vertices for computing the jacobians + + const int dx01 = v1.x - v0.x; + const int dy01 = v1.y - v0.y; + const int dx02 = v2.x - v0.x; + const int dy02 = v2.y - v0.y; + const int ds01 = t1.S - t0.S; + const int dt01 = t1.T - t0.T; + const int ds02 = t2.S - t0.S; + const int dt02 = t2.T - t0.T; + const int area = dx01*dy02 - dy01*dx02; + int dsdx, dsdy, dtdx, dtdy; + if (area >= 0) { + dsdx = ds01*dy02 - ds02*dy01; + dsdy = ds02*dx01 - ds01*dx02; + dtdx = dt01*dy02 - dt02*dy01; + dtdy = dt02*dx01 - dt01*dx02; + } else { + dsdx = ds02*dy01 - ds01*dy02; + dsdy = ds01*dx02 - ds02*dx01; + dtdx = dt02*dy01 - dt01*dy02; + dtdy = dt01*dx02 - dt02*dx01; } - static const int tmu = 0; - texture_unit_t& u(c->textures.tmu[tmu]); + // here we rely on the fact that we know the transform is + // a rigid-body transform AND that it can only rotate in 90 degrees + // increments + + int transform = 0; + if (dsdx == 0) { + // 90 deg rotation case + // [ 0 dtdx ] + // [ dsdx 0 ] + transform |= COPYBIT_TRANSFORM_ROT_90; + // FIXME: not sure if FLIP_H and FLIP_V shouldn't be inverted + if (dtdx > 0) + transform |= COPYBIT_TRANSFORM_FLIP_H; + if (dsdy < 0) + transform |= COPYBIT_TRANSFORM_FLIP_V; + } else { + // [ dsdx 0 ] + // [ 0 dtdy ] + if (dsdx < 0) + transform |= COPYBIT_TRANSFORM_FLIP_H; + if (dtdy < 0) + transform |= COPYBIT_TRANSFORM_FLIP_V; + } + + //LOGD("l=%d, b=%d, w=%d, h=%d, tr=%d", x, y, w, h, transform); + //LOGD("A=%f\tB=%f\nC=%f\tD=%f", + // dsdx/65536.0, dtdx/65536.0, dsdy/65536.0, dtdy/65536.0); + + int x = l >> 4; + int y = b >> 4; + int w = (r-l) >> 4; + int h = (t-b) >> 4; + texture_unit_t& u(c->textures.tmu[0]); EGLTextureObject* textureObject = u.texture; - GLint tWidth = textureObject->surface.width; GLint tHeight = textureObject->surface.height; GLint crop_rect[4] = {0, tHeight, tWidth, -tHeight}; - const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s; y = cbSurface.height - (y + h); - - return copybit(x, y, w, h, textureObject, crop_rect, - COPYBIT_TRANSFORM_ROT_90, c); + return copybit(x, y, w, h, textureObject, crop_rect, transform, c); } /* @@ -357,17 +407,12 @@ bool drawTexiOESWithCopybit_impl(GLint x, GLint y, GLint z, if ((w|h) <= 0) { return true; } - - if (! checkContext(c)) { + if (!checkContext(c)) { return false; } - - static const int tmu = 0; - texture_unit_t& u(c->textures.tmu[tmu]); + texture_unit_t& u(c->textures.tmu[0]); EGLTextureObject* textureObject = u.texture; - - return copybit(x, y, w, h, textureObject, textureObject->crop_rect, - 0, c); + return copybit(x, y, w, h, textureObject, textureObject->crop_rect, 0, c); } } // namespace android diff --git a/opengl/libagl/copybit.h b/opengl/libagl/copybit.h index 401b68c2914a4..b8b5afda2656b 100644 --- a/opengl/libagl/copybit.h +++ b/opengl/libagl/copybit.h @@ -28,7 +28,8 @@ namespace android { bool drawTexiOESWithCopybit_impl(GLint x, GLint y, GLint z, GLint w, GLint h, ogles_context_t* c); -bool drawTrangleFanWithCopybit_impl(ogles_context_t* c, GLint first, + +bool drawTriangleFanWithCopybit_impl(ogles_context_t* c, GLint first, GLsizei count); inline bool copybitQuickCheckContext(ogles_context_t* c) { @@ -54,17 +55,16 @@ inline bool drawTexiOESWithCopybit(GLint x, GLint y, GLint z, * Tries to draw a triangle fan using copybit hardware. * Returns true if successful. */ -inline bool drawTrangleFanWithCopybit(ogles_context_t* c, GLint first, +inline bool drawTriangleFanWithCopybit(ogles_context_t* c, GLint first, GLsizei count) { /* * We are looking for the glDrawArrays call made by SurfaceFlinger. */ - if (!(copybitQuickCheckContext(c) && first == 0 && count == 4)) { + if ((count!=4) || first || !copybitQuickCheckContext(c)) return false; - } - return drawTrangleFanWithCopybit_impl(c, first, count); + return drawTriangleFanWithCopybit_impl(c, first, count); } From 42bf621e801183028066e6947fdd22eae8693a02 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Wed, 17 Jun 2009 21:58:18 -0700 Subject: [PATCH 53/83] fix/add some comments --- opengl/libagl/copybit.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/opengl/libagl/copybit.cpp b/opengl/libagl/copybit.cpp index 0736b6b7b3740..a663f75d34eba 100644 --- a/opengl/libagl/copybit.cpp +++ b/opengl/libagl/copybit.cpp @@ -175,21 +175,24 @@ static bool copybit(GLint x, GLint y, return false; } - /* + // copybit doesn't say anything about filtering, so we can't + // discriminate. On msm7k, copybit will always filter. + // the code below handles min/mag filters, we keep it as a reference. + +#ifdef MIN_MAG_FILTER int32_t texelArea = gglMulx(dtdy, dsdx); if (texelArea < FIXED_ONE && textureObject->mag_filter != GL_LINEAR) { // Non-linear filtering on a texture enlargement. LOGD_IF(DEBUG_COPYBIT, "mag filter is not GL_LINEAR"); return false; } - if (texelArea > FIXED_ONE && textureObject->min_filter != GL_LINEAR) { // Non-linear filtering on an texture shrink. LOGD_IF(DEBUG_COPYBIT, "min filter is not GL_LINEAR"); return false; } - */ - +#endif + const uint32_t enables = c->rasterizer.state.enables; int planeAlpha = 255; static const int tmu = 0; @@ -295,6 +298,11 @@ bool drawTriangleFanWithCopybit_impl(ogles_context_t* c, GLint first, GLsizei co // we detect if we're dealing with a rectangle, by comparing the // rectangles {v0,v2} and {v1,v3} which should be identical. + // NOTE: we should check that the rectangle is window aligned, however + // if we do that, the optimization won't be taken in a lot of cases. + // Since this code is intended to be used with SurfaceFlinger only, + // so it's okay... + const vec4_t& v0 = c->vc.vBuffer[0].window; const vec4_t& v1 = c->vc.vBuffer[1].window; const vec4_t& v2 = c->vc.vBuffer[2].window; From 9cc88529e4cbf54df3eed968666472d3fa658d13 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Thu, 18 Jun 2009 18:48:39 -0700 Subject: [PATCH 54/83] implement dimming with a texture on msm7k so it uses copybit --- libs/surfaceflinger/Android.mk | 4 ++ libs/surfaceflinger/LayerDim.cpp | 96 ++++++++++++++++++++++++++-- libs/surfaceflinger/LayerDim.h | 8 +++ libs/surfaceflinger/SurfaceFlinger.h | 1 + 4 files changed, 104 insertions(+), 5 deletions(-) diff --git a/libs/surfaceflinger/Android.mk b/libs/surfaceflinger/Android.mk index 16936e300a9e5..29b88e9f56404 100644 --- a/libs/surfaceflinger/Android.mk +++ b/libs/surfaceflinger/Android.mk @@ -21,6 +21,10 @@ LOCAL_SRC_FILES:= \ LOCAL_CFLAGS:= -DLOG_TAG=\"SurfaceFlinger\" LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES +ifeq ($(TARGET_BOARD_PLATFORM), msm7k) + LOCAL_CFLAGS += -DDIM_WITH_TEXTURE +endif + # need "-lrt" on Linux simulator to pick up clock_gettime ifeq ($(TARGET_SIMULATOR),true) ifeq ($(HOST_OS),linux) diff --git a/libs/surfaceflinger/LayerDim.cpp b/libs/surfaceflinger/LayerDim.cpp index c1e8ad63cdf94..b95e1844fe684 100644 --- a/libs/surfaceflinger/LayerDim.cpp +++ b/libs/surfaceflinger/LayerDim.cpp @@ -31,16 +31,73 @@ namespace android { const uint32_t LayerDim::typeInfo = LayerBaseClient::typeInfo | 0x10; const char* const LayerDim::typeID = "LayerDim"; +bool LayerDim::sUseTexture; +GLuint LayerDim::sTexId; +EGLImageKHR LayerDim::sImage; +int32_t LayerDim::sWidth; +int32_t LayerDim::sHeight; + // --------------------------------------------------------------------------- LayerDim::LayerDim(SurfaceFlinger* flinger, DisplayID display, Client* client, int32_t i) - : LayerBaseClient(flinger, display, client, i) + : LayerBaseClient(flinger, display, client, i) { } void LayerDim::initDimmer(SurfaceFlinger* flinger, uint32_t w, uint32_t h) { + sTexId = -1; + sImage = EGL_NO_IMAGE_KHR; + sWidth = w; + sHeight = h; + sUseTexture = false; + +#ifdef DIM_WITH_TEXTURE + +#warning "using a texture to implement LayerDim" + + /* On some h/w like msm7K, it is faster to use a texture because the + * software renderer will defer to copybit, for this to work we need to + * use an EGLImage texture so copybit can actually make use of it. + * This burns a full-screen worth of graphic memory. + */ + + const DisplayHardware& hw(flinger->graphicPlane(0).displayHardware()); + uint32_t flags = hw.getFlags(); + + if (LIKELY(flags & DisplayHardware::DIRECT_TEXTURE)) { + // TODO: api to pass the usage flags + sp buffer = new Buffer(w, h, PIXEL_FORMAT_RGB_565); + android_native_buffer_t* clientBuf = buffer->getNativeBuffer(); + + glGenTextures(1, &sTexId); + glBindTexture(GL_TEXTURE_2D, sTexId); + + EGLDisplay dpy = eglGetCurrentDisplay(); + sImage = eglCreateImageKHR(dpy, EGL_NO_CONTEXT, + EGL_NATIVE_BUFFER_ANDROID, (EGLClientBuffer)clientBuf, 0); + if (sImage == EGL_NO_IMAGE_KHR) { + LOGE("eglCreateImageKHR() failed. err=0x%4x", eglGetError()); + return; + } + + glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)sImage); + GLint error = glGetError(); + if (error != GL_NO_ERROR) { + eglDestroyImageKHR(dpy, sImage); + LOGE("glEGLImageTargetTexture2DOES() failed. err=0x%4x", error); + return; + } + + // initialize the texture with zeros + GGLSurface t; + buffer->lock(&t, GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN); + memset(t.data, 0, t.width * t.stride * 2); + buffer->unlock(); + sUseTexture = true; + } +#endif } LayerDim::~LayerDim() @@ -49,8 +106,6 @@ LayerDim::~LayerDim() void LayerDim::onDraw(const Region& clip) const { - // FIXME: on some h/w (like msm7K, it will be faster to use a texture) - const State& s(drawingState()); Region::const_iterator it = clip.begin(); Region::const_iterator const end = clip.end(); @@ -58,12 +113,42 @@ void LayerDim::onDraw(const Region& clip) const const DisplayHardware& hw(graphicPlane(0).displayHardware()); const GGLfixed alpha = (s.alpha << 16)/255; const uint32_t fbHeight = hw.getHeight(); - glDisable(GL_TEXTURE_2D); glDisable(GL_DITHER); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glColor4x(0, 0, 0, alpha); - glVertexPointer(2, GL_FIXED, 0, mVertices); + +#ifdef DIM_WITH_TEXTURE + if (sUseTexture) { + glBindTexture(GL_TEXTURE_2D, sTexId); + glEnable(GL_TEXTURE_2D); + glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + const GLshort texCoords[4][2] = { + { 0, 0 }, + { 0, 1 }, + { 1, 1 }, + { 1, 0 } + }; + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_SHORT, 0, texCoords); + } else +#endif + { + glDisable(GL_TEXTURE_2D); + } + + GLshort w = sWidth; + GLshort h = sHeight; + const GLshort vertices[4][2] = { + { 0, 0 }, + { 0, h }, + { w, h }, + { w, 0 } + }; + glVertexPointer(2, GL_SHORT, 0, vertices); + while (it != end) { const Rect& r = *it++; const GLint sy = fbHeight - (r.top + r.height()); @@ -71,6 +156,7 @@ void LayerDim::onDraw(const Region& clip) const glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } } + glDisableClientState(GL_TEXTURE_COORD_ARRAY); } // --------------------------------------------------------------------------- diff --git a/libs/surfaceflinger/LayerDim.h b/libs/surfaceflinger/LayerDim.h index 0d5bb986cf099..d9b70b4ea83d9 100644 --- a/libs/surfaceflinger/LayerDim.h +++ b/libs/surfaceflinger/LayerDim.h @@ -20,6 +20,9 @@ #include #include +#include +#include + #include "LayerBase.h" #include "LayerBitmap.h" @@ -29,6 +32,11 @@ namespace android { class LayerDim : public LayerBaseClient { + static bool sUseTexture; + static GLuint sTexId; + static EGLImageKHR sImage; + static int32_t sWidth; + static int32_t sHeight; public: static const uint32_t typeInfo; static const char* const typeID; diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h index ebe315a450f74..ac133402788f1 100644 --- a/libs/surfaceflinger/SurfaceFlinger.h +++ b/libs/surfaceflinger/SurfaceFlinger.h @@ -180,6 +180,7 @@ private: friend class LayerBaseClient; friend class Layer; friend class LayerBlur; + friend class LayerDim; sp createSurface(ClientID client, int pid, ISurfaceFlingerClient::surface_data_t* params, From 09cf0ac2e9ec9e18c7099312265f9d51cdbb0f37 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Thu, 18 Jun 2009 19:31:07 -0700 Subject: [PATCH 55/83] we were not fetching the texture coords in the copybit case, so we were using garbage --- opengl/libagl/copybit.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/opengl/libagl/copybit.cpp b/opengl/libagl/copybit.cpp index a663f75d34eba..cde8f8a68af87 100644 --- a/opengl/libagl/copybit.cpp +++ b/opengl/libagl/copybit.cpp @@ -293,6 +293,7 @@ bool drawTriangleFanWithCopybit_impl(ogles_context_t* c, GLint first, GLsizei co return false; } + // FIXME: we should handle culling here c->arrays.compileElements(c, c->vc.vBuffer, 0, 4); // we detect if we're dealing with a rectangle, by comparing the @@ -316,6 +317,18 @@ bool drawTriangleFanWithCopybit_impl(ogles_context_t* c, GLint first, GLsizei co LOGD_IF(DEBUG_COPYBIT, "geometry not a rectangle"); return false; } + + // fetch and transform texture coordinates + // NOTE: maybe it would be better to have a "compileElementsAll" method + // that would ensure all vertex data are fetched and transformed + const transform_t& tr = c->transforms.texture[0].transform; + for (size_t i=0 ; i<4 ; i++) { + const GLubyte* tp = c->arrays.texture[0].element(i); + vertex_t* const v = &c->vc.vBuffer[i]; + c->arrays.texture[0].fetch(c, v->texture[0].v, tp); + // FIXME: we should bail if q!=1 + c->arrays.tex_transform[0](&tr, &v->texture[0], &v->texture[0]); + } const vec4_t& t0 = c->vc.vBuffer[0].texture[0]; const vec4_t& t1 = c->vc.vBuffer[1].texture[0]; @@ -333,7 +346,8 @@ bool drawTriangleFanWithCopybit_impl(ogles_context_t* c, GLint first, GLsizei co if ((txl != 0) || (txb != 0) || (txr != FIXED_ONE) || (txt != FIXED_ONE)) { // we could probably handle this case, if we wanted to - LOGD_IF(DEBUG_COPYBIT, "texture is cropped"); + LOGD_IF(DEBUG_COPYBIT, "texture is cropped: %08x,%08x,%08x,%08x", + txl, txb, txr, txt); return false; } From c8fb5b1979da4829e1486e6a1008c06c979b94b0 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Fri, 19 Jun 2009 16:24:02 -0700 Subject: [PATCH 56/83] release the last reference to surfaces explicitely instead of letting it go implicitely when the message is destroyed --- libs/surfaceflinger/SurfaceFlinger.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp index a56ecd886e3ee..90e0bb56cf861 100644 --- a/libs/surfaceflinger/SurfaceFlinger.cpp +++ b/libs/surfaceflinger/SurfaceFlinger.cpp @@ -1322,6 +1322,8 @@ status_t SurfaceFlinger::destroySurface(const sp& layer) SurfaceFlinger* flinger, const sp& layer) : flinger(flinger), layer(layer) { } virtual bool handler() { + sp l(layer); + layer.clear(); // clear it outside of the lock; Mutex::Autolock _l(flinger->mStateLock); // remove the layer from the current list -- chances are that it's // not in the list anyway, because it should have been removed @@ -1329,7 +1331,7 @@ status_t SurfaceFlinger::destroySurface(const sp& layer) // However, a buggy client could have not done that. // Since we know we don't have any more clients, we don't need // to use the purgatory. - status_t err = flinger->removeLayer_l(layer); + status_t err = flinger->removeLayer_l(l); if (err == NAME_NOT_FOUND) { // The surface wasn't in the current list, which means it was // removed already, which means it is in the purgatory, @@ -1338,9 +1340,9 @@ status_t SurfaceFlinger::destroySurface(const sp& layer) // must run from there (b/c of OpenGL ES). Additionally, we // can't really acquire our internal lock from // destroySurface() -- see postMessage() below. - ssize_t idx = flinger->mLayerPurgatory.remove(layer); + ssize_t idx = flinger->mLayerPurgatory.remove(l); LOGE_IF(idx < 0, - "layer=%p is not in the purgatory list", layer.get()); + "layer=%p is not in the purgatory list", l.get()); } return true; } From 6edf5af578c1ab1fcd44b7c08ca371456e4b7430 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Fri, 19 Jun 2009 17:00:27 -0700 Subject: [PATCH 57/83] fix a memory corruption where a SF Client could be used after it's been destroyed --- libs/surfaceflinger/Layer.cpp | 21 +++++--- libs/surfaceflinger/Layer.h | 6 +-- libs/surfaceflinger/LayerBase.cpp | 18 ++++--- libs/surfaceflinger/LayerBase.h | 4 +- libs/surfaceflinger/LayerBlur.cpp | 2 +- libs/surfaceflinger/LayerBlur.h | 2 +- libs/surfaceflinger/LayerBuffer.cpp | 2 +- libs/surfaceflinger/LayerBuffer.h | 2 +- libs/surfaceflinger/LayerDim.cpp | 2 +- libs/surfaceflinger/LayerDim.h | 2 +- libs/surfaceflinger/SurfaceFlinger.cpp | 75 +++++++++++++------------- libs/surfaceflinger/SurfaceFlinger.h | 20 +++---- 12 files changed, 85 insertions(+), 71 deletions(-) diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp index 5b260c4f95953..218cb39f5be9b 100644 --- a/libs/surfaceflinger/Layer.cpp +++ b/libs/surfaceflinger/Layer.cpp @@ -47,7 +47,7 @@ const char* const Layer::typeID = "Layer"; // --------------------------------------------------------------------------- -Layer::Layer(SurfaceFlinger* flinger, DisplayID display, Client* c, int32_t i) +Layer::Layer(SurfaceFlinger* flinger, DisplayID display, const sp& c, int32_t i) : LayerBaseClient(flinger, display, c, i), mSecure(false), mFrontBufferIndex(1), @@ -100,8 +100,7 @@ status_t Layer::ditch() return NO_ERROR; } -status_t Layer::setBuffers( Client* client, - uint32_t w, uint32_t h, +status_t Layer::setBuffers( uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) { PixelFormatInfo info; @@ -285,6 +284,14 @@ sp Layer::peekBuffer() return buffer; } +void Layer::scheduleBroadcast() +{ + sp ourClient(client.promote()); + if (ourClient != 0) { + mFlinger->scheduleBroadcast(ourClient); + } +} + uint32_t Layer::doTransaction(uint32_t flags) { const Layer::State& front(drawingState()); @@ -380,7 +387,7 @@ uint32_t Layer::doTransaction(uint32_t flags) eResizeBuffer1 : eResizeBuffer0; android_atomic_and(~mask, &(lcblk->swapState)); // since a buffer became available, we can let the client go... - mFlinger->scheduleBroadcast(client); + scheduleBroadcast(); mResizeTransactionDone = true; // we're being resized and there is a freeze display request, @@ -489,7 +496,7 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions) if (UNLIKELY(state & eInvalidSurface)) { // if eInvalidSurface is set, this means the surface // became invalid during a transaction (NO_MEMORY for instance) - mFlinger->scheduleBroadcast(client); + scheduleBroadcast(); return; } @@ -627,7 +634,7 @@ void Layer::unlockPageFlip( // client could be blocked, so signal them so they get a // chance to reevaluate their condition. - mFlinger->scheduleBroadcast(client); + scheduleBroadcast(); } } @@ -638,7 +645,7 @@ void Layer::finishPageFlip() "layer %p wasn't locked!", this); android_atomic_and(~eBusy, &(lcblk->swapState)); } - mFlinger->scheduleBroadcast(client); + scheduleBroadcast(); } // --------------------------------------------------------------------------- diff --git a/libs/surfaceflinger/Layer.h b/libs/surfaceflinger/Layer.h index e16d9f40d9538..a19c171e4f50b 100644 --- a/libs/surfaceflinger/Layer.h +++ b/libs/surfaceflinger/Layer.h @@ -58,7 +58,7 @@ public: virtual uint32_t getTypeInfo() const { return typeInfo; } Layer(SurfaceFlinger* flinger, DisplayID display, - Client* c, int32_t i); + const sp& client, int32_t i); virtual ~Layer(); @@ -66,8 +66,7 @@ public: return frontBuffer().getPixelFormat(); } - status_t setBuffers( Client* client, - uint32_t w, uint32_t h, + status_t setBuffers( uint32_t w, uint32_t h, PixelFormat format, uint32_t flags=0); virtual void onDraw(const Region& clip) const; @@ -105,6 +104,7 @@ private: Region post(uint32_t* oldState, bool& recomputeVisibleRegions); sp peekBuffer(); void destroy(); + void scheduleBroadcast(); class SurfaceLayer : public LayerBaseClient::Surface diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp index b65c983869c45..3b8635066739a 100644 --- a/libs/surfaceflinger/LayerBase.cpp +++ b/libs/surfaceflinger/LayerBase.cpp @@ -640,16 +640,17 @@ regular: // --------------------------------------------------------------------------- LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display, - Client* c, int32_t i) - : LayerBase(flinger, display), client(c), - lcblk( c ? &(c->ctrlblk->layers[i]) : 0 ), + const sp& client, int32_t i) + : LayerBase(flinger, display), client(client), + lcblk( client!=0 ? &(client->ctrlblk->layers[i]) : 0 ), mIndex(i) { } void LayerBaseClient::onFirstRef() { - if (client) { + sp client(this->client.promote()); + if (client != 0) { client->bindLayer(this, mIndex); // Initialize this layer's control block memset(this->lcblk, 0, sizeof(layer_cblk_t)); @@ -661,13 +662,16 @@ void LayerBaseClient::onFirstRef() LayerBaseClient::~LayerBaseClient() { - if (client) { + sp client(this->client.promote()); + if (client != 0) { client->free(mIndex); } } -int32_t LayerBaseClient::serverIndex() const { - if (client) { +int32_t LayerBaseClient::serverIndex() const +{ + sp client(this->client.promote()); + if (client != 0) { return (client->cid<<16)|mIndex; } return 0xFFFF0000 | mIndex; diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h index 509dedd743f17..b5265d2b2b564 100644 --- a/libs/surfaceflinger/LayerBase.h +++ b/libs/surfaceflinger/LayerBase.h @@ -297,11 +297,11 @@ public: virtual uint32_t getTypeInfo() const { return typeInfo; } LayerBaseClient(SurfaceFlinger* flinger, DisplayID display, - Client* client, int32_t i); + const sp& client, int32_t i); virtual ~LayerBaseClient(); virtual void onFirstRef(); - Client* const client; + wp client; layer_cblk_t* const lcblk; inline uint32_t getIdentity() const { return mIdentity; } diff --git a/libs/surfaceflinger/LayerBlur.cpp b/libs/surfaceflinger/LayerBlur.cpp index 3d22e3ab278f0..00abd5a162e50 100644 --- a/libs/surfaceflinger/LayerBlur.cpp +++ b/libs/surfaceflinger/LayerBlur.cpp @@ -38,7 +38,7 @@ const char* const LayerBlur::typeID = "LayerBlur"; // --------------------------------------------------------------------------- LayerBlur::LayerBlur(SurfaceFlinger* flinger, DisplayID display, - Client* client, int32_t i) + const sp& client, int32_t i) : LayerBaseClient(flinger, display, client, i), mCacheDirty(true), mRefreshCache(true), mCacheAge(0), mTextureName(-1U) { diff --git a/libs/surfaceflinger/LayerBlur.h b/libs/surfaceflinger/LayerBlur.h index 24b115657c4c4..0c3e6eb6e8c21 100644 --- a/libs/surfaceflinger/LayerBlur.h +++ b/libs/surfaceflinger/LayerBlur.h @@ -39,7 +39,7 @@ public: virtual uint32_t getTypeInfo() const { return typeInfo; } LayerBlur(SurfaceFlinger* flinger, DisplayID display, - Client* client, int32_t i); + const sp& client, int32_t i); virtual ~LayerBlur(); virtual void onDraw(const Region& clip) const; diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp index 8be91c9febf19..02b3651140c40 100644 --- a/libs/surfaceflinger/LayerBuffer.cpp +++ b/libs/surfaceflinger/LayerBuffer.cpp @@ -40,7 +40,7 @@ const char* const LayerBuffer::typeID = "LayerBuffer"; // --------------------------------------------------------------------------- LayerBuffer::LayerBuffer(SurfaceFlinger* flinger, DisplayID display, - Client* client, int32_t i) + const sp& client, int32_t i) : LayerBaseClient(flinger, display, client, i), mNeedsBlending(false) { diff --git a/libs/surfaceflinger/LayerBuffer.h b/libs/surfaceflinger/LayerBuffer.h index 22af43e87b336..587d31b4ac82c 100644 --- a/libs/surfaceflinger/LayerBuffer.h +++ b/libs/surfaceflinger/LayerBuffer.h @@ -57,7 +57,7 @@ public: virtual uint32_t getTypeInfo() const { return typeInfo; } LayerBuffer(SurfaceFlinger* flinger, DisplayID display, - Client* client, int32_t i); + const sp& client, int32_t i); virtual ~LayerBuffer(); virtual void onFirstRef(); diff --git a/libs/surfaceflinger/LayerDim.cpp b/libs/surfaceflinger/LayerDim.cpp index b95e1844fe684..5cb883c661f22 100644 --- a/libs/surfaceflinger/LayerDim.cpp +++ b/libs/surfaceflinger/LayerDim.cpp @@ -40,7 +40,7 @@ int32_t LayerDim::sHeight; // --------------------------------------------------------------------------- LayerDim::LayerDim(SurfaceFlinger* flinger, DisplayID display, - Client* client, int32_t i) + const sp& client, int32_t i) : LayerBaseClient(flinger, display, client, i) { } diff --git a/libs/surfaceflinger/LayerDim.h b/libs/surfaceflinger/LayerDim.h index d9b70b4ea83d9..33bd49d54d32f 100644 --- a/libs/surfaceflinger/LayerDim.h +++ b/libs/surfaceflinger/LayerDim.h @@ -44,7 +44,7 @@ public: virtual uint32_t getTypeInfo() const { return typeInfo; } LayerDim(SurfaceFlinger* flinger, DisplayID display, - Client* client, int32_t i); + const sp& client, int32_t i); virtual ~LayerDim(); virtual void onDraw(const Region& clip) const; diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp index 90e0bb56cf861..2e7bbeafcf0aa 100644 --- a/libs/surfaceflinger/SurfaceFlinger.cpp +++ b/libs/surfaceflinger/SurfaceFlinger.cpp @@ -227,14 +227,13 @@ sp SurfaceFlinger::createConnection() Mutex::Autolock _l(mStateLock); uint32_t token = mTokens.acquire(); - Client* client = new Client(token, this); - if ((client == 0) || (client->ctrlblk == 0)) { + sp client = new Client(token, this); + if (client->ctrlblk == 0) { mTokens.release(token); return 0; } status_t err = mClientsMap.add(token, client); if (err < 0) { - delete client; mTokens.release(token); return 0; } @@ -246,8 +245,8 @@ sp SurfaceFlinger::createConnection() void SurfaceFlinger::destroyConnection(ClientID cid) { Mutex::Autolock _l(mStateLock); - Client* const client = mClientsMap.valueFor(cid); - if (client) { + sp client = mClientsMap.valueFor(cid); + if (client != 0) { // free all the layers this client owns Vector< wp > layers(client->getLayers()); const size_t count = layers.size(); @@ -876,7 +875,7 @@ void SurfaceFlinger::unlockClients() } } -void SurfaceFlinger::scheduleBroadcast(Client* client) +void SurfaceFlinger::scheduleBroadcast(const sp& client) { if (mLastScheduledBroadcast != client) { mLastScheduledBroadcast = client; @@ -886,19 +885,22 @@ void SurfaceFlinger::scheduleBroadcast(Client* client) void SurfaceFlinger::executeScheduledBroadcasts() { - SortedVector& list = mScheduledBroadcasts; + SortedVector< wp >& list(mScheduledBroadcasts); size_t count = list.size(); while (count--) { - per_client_cblk_t* const cblk = list[count]->ctrlblk; - if (cblk->lock.tryLock() == NO_ERROR) { - cblk->cv.broadcast(); - list.removeAt(count); - cblk->lock.unlock(); - } else { - // schedule another round - LOGW("executeScheduledBroadcasts() skipped, " - "contention on the client. We'll try again later..."); - signalDelayedEvent(ms2ns(4)); + sp client = list[count].promote(); + if (client != 0) { + per_client_cblk_t* const cblk = client->ctrlblk; + if (cblk->lock.tryLock() == NO_ERROR) { + cblk->cv.broadcast(); + list.removeAt(count); + cblk->lock.unlock(); + } else { + // schedule another round + LOGW("executeScheduledBroadcasts() skipped, " + "contention on the client. We'll try again later..."); + signalDelayedEvent(ms2ns(4)); + } } } mLastScheduledBroadcast = 0; @@ -1090,11 +1092,11 @@ void SurfaceFlinger::free_resources_l() mLayersRemoved = false; // free resources associated with disconnected clients - SortedVector& scheduledBroadcasts(mScheduledBroadcasts); - Vector& disconnectedClients(mDisconnectedClients); + SortedVector< wp >& scheduledBroadcasts(mScheduledBroadcasts); + Vector< sp >& disconnectedClients(mDisconnectedClients); const size_t count = disconnectedClients.size(); for (size_t i=0 ; i client = disconnectedClients[i]; // if this client is the scheduled broadcast list, // remove it from there (and we don't need to signal it // since it is dead). @@ -1103,7 +1105,6 @@ void SurfaceFlinger::free_resources_l() scheduledBroadcasts.removeItemsAt(index); } mTokens.release(client->cid); - delete client; } disconnectedClients.clear(); } @@ -1194,14 +1195,14 @@ sp SurfaceFlinger::createSurface(ClientID clientId, int pid, sp layer; sp surfaceHandle; Mutex::Autolock _l(mStateLock); - Client* const c = mClientsMap.valueFor(clientId); - if (UNLIKELY(!c)) { + sp client = mClientsMap.valueFor(clientId); + if (UNLIKELY(client == 0)) { LOGE("createSurface() failed, client not found (id=%d)", clientId); return surfaceHandle; } //LOGD("createSurface for pid %d (%d x %d)", pid, w, h); - int32_t id = c->generateId(pid); + int32_t id = client->generateId(pid); if (uint32_t(id) >= NUM_LAYERS_MAX) { LOGE("createSurface() failed, generateId = %d", id); return surfaceHandle; @@ -1210,16 +1211,16 @@ sp SurfaceFlinger::createSurface(ClientID clientId, int pid, switch (flags & eFXSurfaceMask) { case eFXSurfaceNormal: if (UNLIKELY(flags & ePushBuffers)) { - layer = createPushBuffersSurfaceLocked(c, d, id, w, h, flags); + layer = createPushBuffersSurfaceLocked(client, d, id, w, h, flags); } else { - layer = createNormalSurfaceLocked(c, d, id, w, h, format, flags); + layer = createNormalSurfaceLocked(client, d, id, w, h, format, flags); } break; case eFXSurfaceBlur: - layer = createBlurSurfaceLocked(c, d, id, w, h, flags); + layer = createBlurSurfaceLocked(client, d, id, w, h, flags); break; case eFXSurfaceDim: - layer = createDimSurfaceLocked(c, d, id, w, h, flags); + layer = createDimSurfaceLocked(client, d, id, w, h, flags); break; } @@ -1234,7 +1235,7 @@ sp SurfaceFlinger::createSurface(ClientID clientId, int pid, } sp SurfaceFlinger::createNormalSurfaceLocked( - Client* client, DisplayID display, + const sp& client, DisplayID display, int32_t id, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) { // initialize the surfaces @@ -1249,7 +1250,7 @@ sp SurfaceFlinger::createNormalSurfaceLocked( } sp layer = new Layer(this, display, client, id); - status_t err = layer->setBuffers(client, w, h, format, flags); + status_t err = layer->setBuffers(w, h, format, flags); if (LIKELY(err == NO_ERROR)) { layer->initStates(w, h, flags); addLayer_l(layer); @@ -1261,7 +1262,7 @@ sp SurfaceFlinger::createNormalSurfaceLocked( } sp SurfaceFlinger::createBlurSurfaceLocked( - Client* client, DisplayID display, + const sp& client, DisplayID display, int32_t id, uint32_t w, uint32_t h, uint32_t flags) { sp layer = new LayerBlur(this, display, client, id); @@ -1271,7 +1272,7 @@ sp SurfaceFlinger::createBlurSurfaceLocked( } sp SurfaceFlinger::createDimSurfaceLocked( - Client* client, DisplayID display, + const sp& client, DisplayID display, int32_t id, uint32_t w, uint32_t h, uint32_t flags) { sp layer = new LayerDim(this, display, client, id); @@ -1281,7 +1282,7 @@ sp SurfaceFlinger::createDimSurfaceLocked( } sp SurfaceFlinger::createPushBuffersSurfaceLocked( - Client* client, DisplayID display, + const sp& client, DisplayID display, int32_t id, uint32_t w, uint32_t h, uint32_t flags) { sp layer = new LayerBuffer(this, display, client, id); @@ -1446,7 +1447,7 @@ status_t SurfaceFlinger::dump(int fd, const Vector& args) size_t s = mClientsMap.size(); char name[64]; for (size_t i=0 ; i client = mClientsMap.valueAt(i); sprintf(name, " Client (id=0x%08x)", client->cid); client->dump(name); } @@ -1474,10 +1475,11 @@ status_t SurfaceFlinger::dump(int fd, const Vector& args) sp lbc = LayerBase::dynamicCast< LayerBaseClient* >(layer.get()); if (lbc != 0) { + sp client(lbc->client.promote()); snprintf(buffer, SIZE, " " "id=0x%08x, client=0x%08x, identity=%u\n", - lbc->clientIndex(), lbc->client ? lbc->client->cid : 0, + lbc->clientIndex(), client.get() ? client->cid : 0, lbc->getIdentity()); } result.append(buffer); @@ -1512,7 +1514,8 @@ status_t SurfaceFlinger::dump(int fd, const Vector& args) mFreezeDisplay?"yes":"no", mFreezeCount, mCurrentState.orientation, hw.canDraw()); result.append(buffer); - snprintf(buffer, SIZE, " purgatory size: %d\n", mLayerPurgatory.size()); + snprintf(buffer, SIZE, " purgatory size: %d, client count: %d\n", + mLayerPurgatory.size(), mClientsMap.size()); result.append(buffer); const BufferAllocator& alloc(BufferAllocator::get()); alloc.dump(result); diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h index ac133402788f1..149eef049158e 100644 --- a/libs/surfaceflinger/SurfaceFlinger.h +++ b/libs/surfaceflinger/SurfaceFlinger.h @@ -64,7 +64,7 @@ typedef int32_t ClientID; // --------------------------------------------------------------------------- -class Client +class Client : public RefBase { public: Client(ClientID cid, const sp& flinger); @@ -188,20 +188,20 @@ private: uint32_t flags); sp createNormalSurfaceLocked( - Client* client, DisplayID display, + const sp& client, DisplayID display, int32_t id, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags); sp createBlurSurfaceLocked( - Client* client, DisplayID display, + const sp& client, DisplayID display, int32_t id, uint32_t w, uint32_t h, uint32_t flags); sp createDimSurfaceLocked( - Client* client, DisplayID display, + const sp& client, DisplayID display, int32_t id, uint32_t w, uint32_t h, uint32_t flags); sp createPushBuffersSurfaceLocked( - Client* client, DisplayID display, + const sp& client, DisplayID display, int32_t id, uint32_t w, uint32_t h, uint32_t flags); status_t removeSurface(SurfaceID surface_id); @@ -262,7 +262,7 @@ private: bool lockPageFlip(const LayerVector& currentLayers); void unlockPageFlip(const LayerVector& currentLayers); void handleRepaint(); - void scheduleBroadcast(Client* client); + void scheduleBroadcast(const sp& client); void executeScheduledBroadcasts(); void postFramebuffer(); void composeSurfaces(const Region& dirty); @@ -312,11 +312,11 @@ private: // protected by mStateLock (but we could use another lock) Tokenizer mTokens; - DefaultKeyedVector mClientsMap; + DefaultKeyedVector > mClientsMap; DefaultKeyedVector > mLayerMap; GraphicPlane mGraphicPlanes[1]; bool mLayersRemoved; - Vector mDisconnectedClients; + Vector< sp > mDisconnectedClients; // constant members (no synchronization needed for access) sp mServerHeap; @@ -333,8 +333,8 @@ private: Region mDirtyRegion; Region mInvalidRegion; Region mWormholeRegion; - Client* mLastScheduledBroadcast; - SortedVector mScheduledBroadcasts; + wp mLastScheduledBroadcast; + SortedVector< wp > mScheduledBroadcasts; bool mVisibleRegionsDirty; bool mDeferReleaseConsole; bool mFreezeDisplay; From ab445152f94460281aab87fc123c935b67857e81 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Mon, 22 Jun 2009 01:17:46 -0700 Subject: [PATCH 58/83] improve Vector<> with types that can be trivially moved and remove some unused code. This optimization applies to sp<> and wp<> which should now perform about the same as regular pointers when placed in to Vector<>. --- include/utils/SortedVector.h | 3 +- include/utils/TypeHelpers.h | 135 +++++++++++++++++++---------------- include/utils/Vector.h | 3 +- include/utils/VectorImpl.h | 1 - 4 files changed, 74 insertions(+), 68 deletions(-) diff --git a/include/utils/SortedVector.h b/include/utils/SortedVector.h index c8a61531f4d35..8beec573205ed 100644 --- a/include/utils/SortedVector.h +++ b/include/utils/SortedVector.h @@ -141,8 +141,7 @@ SortedVector::SortedVector() : SortedVectorImpl(sizeof(TYPE), ((traits::has_trivial_ctor ? HAS_TRIVIAL_CTOR : 0) |(traits::has_trivial_dtor ? HAS_TRIVIAL_DTOR : 0) - |(traits::has_trivial_copy ? HAS_TRIVIAL_COPY : 0) - |(traits::has_trivial_assign ? HAS_TRIVIAL_ASSIGN : 0)) + |(traits::has_trivial_copy ? HAS_TRIVIAL_COPY : 0)) ) { } diff --git a/include/utils/TypeHelpers.h b/include/utils/TypeHelpers.h index c04c37fa986a2..2ff2749ba385e 100644 --- a/include/utils/TypeHelpers.h +++ b/include/utils/TypeHelpers.h @@ -29,35 +29,39 @@ namespace android { /* * Types traits */ - -template struct trait_trivial_ctor { enum { value = false }; }; -template struct trait_trivial_dtor { enum { value = false }; }; -template struct trait_trivial_copy { enum { value = false }; }; -template struct trait_trivial_assign{ enum { value = false }; }; -template struct trait_pointer { enum { value = false }; }; -template struct trait_pointer { enum { value = true }; }; +template struct trait_trivial_ctor { enum { value = false }; }; +template struct trait_trivial_dtor { enum { value = false }; }; +template struct trait_trivial_copy { enum { value = false }; }; +template struct trait_trivial_move { enum { value = false }; }; +template struct trait_pointer { enum { value = false }; }; +template struct trait_pointer { enum { value = true }; }; -#define ANDROID_BASIC_TYPES_TRAITS( T ) \ - template<> struct trait_trivial_ctor< T > { enum { value = true }; }; \ - template<> struct trait_trivial_dtor< T > { enum { value = true }; }; \ - template<> struct trait_trivial_copy< T > { enum { value = true }; }; \ - template<> struct trait_trivial_assign< T >{ enum { value = true }; }; +// sp<> can be trivially moved +template class sp; +template struct trait_trivial_move< sp >{ + enum { value = true }; +}; -#define ANDROID_TYPE_TRAITS( T, ctor, dtor, copy, assign ) \ - template<> struct trait_trivial_ctor< T > { enum { value = ctor }; }; \ - template<> struct trait_trivial_dtor< T > { enum { value = dtor }; }; \ - template<> struct trait_trivial_copy< T > { enum { value = copy }; }; \ - template<> struct trait_trivial_assign< T >{ enum { value = assign }; }; +// wp<> can be trivially moved +template class wp; +template struct trait_trivial_move< wp >{ + enum { value = true }; +}; template struct traits { enum { + // whether this type is a pointer is_pointer = trait_pointer::value, + // whether this type's constructor is a no-op has_trivial_ctor = is_pointer || trait_trivial_ctor::value, + // whether this type's destructor is a no-op has_trivial_dtor = is_pointer || trait_trivial_dtor::value, + // whether this type type can be copy-constructed with memcpy has_trivial_copy = is_pointer || trait_trivial_copy::value, - has_trivial_assign = is_pointer || trait_trivial_assign::value + // whether this type can be moved with memmove + has_trivial_move = is_pointer || trait_trivial_move::value }; }; @@ -65,37 +69,47 @@ template struct aggregate_traits { enum { is_pointer = false, - has_trivial_ctor = traits::has_trivial_ctor && traits::has_trivial_ctor, - has_trivial_dtor = traits::has_trivial_dtor && traits::has_trivial_dtor, - has_trivial_copy = traits::has_trivial_copy && traits::has_trivial_copy, - has_trivial_assign = traits::has_trivial_assign && traits::has_trivial_assign + has_trivial_ctor = + traits::has_trivial_ctor && traits::has_trivial_ctor, + has_trivial_dtor = + traits::has_trivial_dtor && traits::has_trivial_dtor, + has_trivial_copy = + traits::has_trivial_copy && traits::has_trivial_copy, + has_trivial_move = + traits::has_trivial_move && traits::has_trivial_move }; }; +#define ANDROID_BASIC_TYPES_TRAITS( T ) \ + template<> struct trait_trivial_ctor< T > { enum { value = true }; }; \ + template<> struct trait_trivial_dtor< T > { enum { value = true }; }; \ + template<> struct trait_trivial_copy< T > { enum { value = true }; }; \ + template<> struct trait_trivial_move< T > { enum { value = true }; }; + // --------------------------------------------------------------------------- /* * basic types traits */ - -ANDROID_BASIC_TYPES_TRAITS( void ); -ANDROID_BASIC_TYPES_TRAITS( bool ); -ANDROID_BASIC_TYPES_TRAITS( char ); -ANDROID_BASIC_TYPES_TRAITS( unsigned char ); -ANDROID_BASIC_TYPES_TRAITS( short ); -ANDROID_BASIC_TYPES_TRAITS( unsigned short ); -ANDROID_BASIC_TYPES_TRAITS( int ); -ANDROID_BASIC_TYPES_TRAITS( unsigned int ); -ANDROID_BASIC_TYPES_TRAITS( long ); -ANDROID_BASIC_TYPES_TRAITS( unsigned long ); -ANDROID_BASIC_TYPES_TRAITS( long long ); -ANDROID_BASIC_TYPES_TRAITS( unsigned long long ); -ANDROID_BASIC_TYPES_TRAITS( float ); -ANDROID_BASIC_TYPES_TRAITS( double ); + +ANDROID_BASIC_TYPES_TRAITS( void ) +ANDROID_BASIC_TYPES_TRAITS( bool ) +ANDROID_BASIC_TYPES_TRAITS( char ) +ANDROID_BASIC_TYPES_TRAITS( unsigned char ) +ANDROID_BASIC_TYPES_TRAITS( short ) +ANDROID_BASIC_TYPES_TRAITS( unsigned short ) +ANDROID_BASIC_TYPES_TRAITS( int ) +ANDROID_BASIC_TYPES_TRAITS( unsigned int ) +ANDROID_BASIC_TYPES_TRAITS( long ) +ANDROID_BASIC_TYPES_TRAITS( unsigned long ) +ANDROID_BASIC_TYPES_TRAITS( long long ) +ANDROID_BASIC_TYPES_TRAITS( unsigned long long ) +ANDROID_BASIC_TYPES_TRAITS( float ) +ANDROID_BASIC_TYPES_TRAITS( double ) // --------------------------------------------------------------------------- - + /* * compare and order types */ @@ -111,9 +125,9 @@ int compare_type(const TYPE& lhs, const TYPE& rhs) { } /* - * create, destroy, copy and assign types... + * create, destroy, copy and move types... */ - + template inline void construct_type(TYPE* p, size_t n) { if (!traits::has_trivial_ctor) { @@ -145,17 +159,6 @@ void copy_type(TYPE* d, const TYPE* s, size_t n) { } } -template inline -void assign_type(TYPE* d, const TYPE* s, size_t n) { - if (!traits::has_trivial_assign) { - while (n--) { - *d++ = *s++; - } - } else { - memcpy(d,s,n*sizeof(TYPE)); - } -} - template inline void splat_type(TYPE* where, const TYPE* what, size_t n) { if (!traits::has_trivial_copy) { @@ -164,15 +167,19 @@ void splat_type(TYPE* where, const TYPE* what, size_t n) { where++; } } else { - while (n--) { - *where++ = *what; + while (n--) { + *where++ = *what; } } } template inline void move_forward_type(TYPE* d, const TYPE* s, size_t n = 1) { - if (!traits::has_trivial_copy || !traits::has_trivial_dtor) { + if ((traits::has_trivial_dtor && traits::has_trivial_copy) + || traits::has_trivial_move) + { + memmove(d,s,n*sizeof(TYPE)); + } else { d += n; s += n; while (n--) { @@ -180,35 +187,37 @@ void move_forward_type(TYPE* d, const TYPE* s, size_t n = 1) { if (!traits::has_trivial_copy) { new(d) TYPE(*s); } else { - *d = *s; + *d = *s; } if (!traits::has_trivial_dtor) { s->~TYPE(); } } - } else { - memmove(d,s,n*sizeof(TYPE)); } } template inline void move_backward_type(TYPE* d, const TYPE* s, size_t n = 1) { - if (!traits::has_trivial_copy || !traits::has_trivial_dtor) { + if ((traits::has_trivial_dtor && traits::has_trivial_copy) + || traits::has_trivial_move) + { + memmove(d,s,n*sizeof(TYPE)); + } else { while (n--) { if (!traits::has_trivial_copy) { new(d) TYPE(*s); } else { - *d = *s; + *d = *s; } if (!traits::has_trivial_dtor) { s->~TYPE(); } d++, s++; } - } else { - memmove(d,s,n*sizeof(TYPE)); } } + + // --------------------------------------------------------------------------- /* @@ -242,8 +251,8 @@ struct trait_trivial_copy< key_value_pair_t > { enum { value = aggregate_traits::has_trivial_copy }; }; template<> template -struct trait_trivial_assign< key_value_pair_t > -{ enum { value = aggregate_traits::has_trivial_assign};}; +struct trait_trivial_move< key_value_pair_t > +{ enum { value = aggregate_traits::has_trivial_move }; }; // --------------------------------------------------------------------------- diff --git a/include/utils/Vector.h b/include/utils/Vector.h index be365d83e18a4..ad59fd63e1004 100644 --- a/include/utils/Vector.h +++ b/include/utils/Vector.h @@ -175,8 +175,7 @@ Vector::Vector() : VectorImpl(sizeof(TYPE), ((traits::has_trivial_ctor ? HAS_TRIVIAL_CTOR : 0) |(traits::has_trivial_dtor ? HAS_TRIVIAL_DTOR : 0) - |(traits::has_trivial_copy ? HAS_TRIVIAL_COPY : 0) - |(traits::has_trivial_assign ? HAS_TRIVIAL_ASSIGN : 0)) + |(traits::has_trivial_copy ? HAS_TRIVIAL_COPY : 0)) ) { } diff --git a/include/utils/VectorImpl.h b/include/utils/VectorImpl.h index 2525229be0a12..49b03f10bdf71 100644 --- a/include/utils/VectorImpl.h +++ b/include/utils/VectorImpl.h @@ -44,7 +44,6 @@ public: HAS_TRIVIAL_CTOR = 0x00000001, HAS_TRIVIAL_DTOR = 0x00000002, HAS_TRIVIAL_COPY = 0x00000004, - HAS_TRIVIAL_ASSIGN = 0x00000008 }; VectorImpl(size_t itemSize, uint32_t flags); From 3142f4f40ba745ecd3cd9f1839adaebc1f20fede Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Mon, 22 Jun 2009 18:01:09 -0700 Subject: [PATCH 59/83] update renderscript to master_gl APIs --- libs/rs/jni/RenderScript_jni.cpp | 1 - libs/rs/rsContext.cpp | 4 ++-- libs/rs/rsContext.h | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/libs/rs/jni/RenderScript_jni.cpp b/libs/rs/jni/RenderScript_jni.cpp index ab17a4a996c71..dcf3850e6c73d 100644 --- a/libs/rs/jni/RenderScript_jni.cpp +++ b/libs/rs/jni/RenderScript_jni.cpp @@ -23,7 +23,6 @@ #include #include -#include #include #include diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp index 7c46c0e9fd006..455c18dd940c5 100644 --- a/libs/rs/rsContext.cpp +++ b/libs/rs/rsContext.cpp @@ -18,6 +18,7 @@ #include "rsContext.h" #include "rsThreadIO.h" #include "utils/String8.h" +#include using namespace android; using namespace android::renderscript; @@ -43,8 +44,7 @@ void Context::initEGL() eglChooseConfig(mDisplay, s_configAttribs, &mConfig, 1, &mNumConfigs); if (mWndSurface) { - mSurface = eglCreateWindowSurface(mDisplay, mConfig, - new EGLNativeWindowSurface(mWndSurface), + mSurface = eglCreateWindowSurface(mDisplay, mConfig, mWndSurface, NULL); } else { mSurface = eglCreateWindowSurface(mDisplay, mConfig, diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h index 334ef3c475b30..e9d75e09b534e 100644 --- a/libs/rs/rsContext.h +++ b/libs/rs/rsContext.h @@ -18,7 +18,6 @@ #define ANDROID_RS_CONTEXT_H #include -#include #include #include "rsType.h" From e8f7c682d2a083742c293a7de59f2282e6fa7a53 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Tue, 23 Jun 2009 14:05:35 -0700 Subject: [PATCH 60/83] Android now has its own EGL extension block (yay) 0x3140-0x314F. EGL_NATIVE_BUFFER_ANDROID now maps to 0x3140 instead of using the staging range --- opengl/include/EGL/eglplatform.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opengl/include/EGL/eglplatform.h b/opengl/include/EGL/eglplatform.h index 956149091d817..11aa4e2f41355 100644 --- a/opengl/include/EGL/eglplatform.h +++ b/opengl/include/EGL/eglplatform.h @@ -99,7 +99,7 @@ typedef void* EGLNativeDisplayType; #ifndef EGL_ANDROID_image_native_buffer #define EGL_ANDROID_image_native_buffer 1 struct android_native_buffer_t; -#define EGL_NATIVE_BUFFER_ANDROID 0x6000 /* eglCreateImageKHR target */ +#define EGL_NATIVE_BUFFER_ANDROID 0x3140 /* eglCreateImageKHR target */ #endif #else From 999543ba26d10ff9879144965d0c0abcb400636a Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Tue, 23 Jun 2009 18:08:22 -0700 Subject: [PATCH 61/83] checkpoint. bring back video/camera --- libs/surfaceflinger/Layer.cpp | 12 +++---- libs/surfaceflinger/Layer.h | 10 ------ libs/surfaceflinger/LayerBase.cpp | 23 +++++++------ libs/surfaceflinger/LayerBase.h | 27 ++++++++++------ libs/surfaceflinger/LayerBuffer.cpp | 50 ++++++++++++++--------------- libs/surfaceflinger/LayerBuffer.h | 14 ++++---- 6 files changed, 68 insertions(+), 68 deletions(-) diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp index 218cb39f5be9b..c40fec16fbc95 100644 --- a/libs/surfaceflinger/Layer.cpp +++ b/libs/surfaceflinger/Layer.cpp @@ -187,7 +187,9 @@ void Layer::reloadTexture(const Region& dirty) mFlags &= ~DisplayHardware::DIRECT_TEXTURE; } else { // Everything went okay! - mTextures[index].dirty = false; + mTextures[index].dirty = false; + mTextures[index].width = clientBuf->width; + mTextures[index].height = clientBuf->height; } } } @@ -200,8 +202,7 @@ void Layer::reloadTexture(const Region& dirty) if (UNLIKELY(mTextures[0].name == -1U)) { mTextures[0].name = createTexture(); } - loadTexture(dirty, mTextures[0].name, t, - mTextures[0].width, mTextures[0].height); + loadTexture(&mTextures[0], mTextures[0].name, dirty, t); buffer->unlock(); } } @@ -222,10 +223,7 @@ void Layer::onDraw(const Region& clip) const clearWithOpenGL(clip); return; } - - GGLSurface t; - sp buffer(frontBuffer().getBuffer()); - drawWithOpenGL(clip, textureName, buffer); + drawWithOpenGL(clip, mTextures[index]); } sp Layer::peekBuffer() diff --git a/libs/surfaceflinger/Layer.h b/libs/surfaceflinger/Layer.h index a19c171e4f50b..54d994facc7d5 100644 --- a/libs/surfaceflinger/Layer.h +++ b/libs/surfaceflinger/Layer.h @@ -123,16 +123,6 @@ private: }; friend class SurfaceLayer; - struct Texture { - Texture() : name(-1U), width(0), height(0), image(EGL_NO_IMAGE_KHR), - dirty(true) { } - GLuint name; - GLuint width; - GLuint height; - EGLImageKHR image; - bool dirty; - }; - sp mSurface; bool mSecure; diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp index 3b8635066739a..5fa14b2c93997 100644 --- a/libs/surfaceflinger/LayerBase.cpp +++ b/libs/surfaceflinger/LayerBase.cpp @@ -380,17 +380,17 @@ void LayerBase::clearWithOpenGL(const Region& clip) const } } -void LayerBase::drawWithOpenGL(const Region& clip, - GLint textureName, const sp& buffer, int transform) const +void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const { const DisplayHardware& hw(graphicPlane(0).displayHardware()); const uint32_t fbHeight = hw.getHeight(); const State& s(drawingState()); - const uint32_t width = buffer->width; - const uint32_t height = buffer->height; // bind our texture - validateTexture(textureName); + validateTexture(texture.name); + uint32_t width = texture.width; + uint32_t height = texture.height; + glEnable(GL_TEXTURE_2D); // Dithering... @@ -457,7 +457,9 @@ void LayerBase::drawWithOpenGL(const Region& clip, glMatrixMode(GL_TEXTURE); glLoadIdentity(); - if (transform == HAL_TRANSFORM_ROT_90) { + // the texture's source is rotated + if (texture.transform == HAL_TRANSFORM_ROT_90) { + // TODO: handle the other orientations glTranslatef(0, 1, 0); glRotatef(-90, 0, 0, 1); } @@ -518,13 +520,16 @@ void LayerBase::validateTexture(GLint textureName) const // this is currently done in loadTexture() below } -void LayerBase::loadTexture(const Region& dirty, - GLint textureName, const GGLSurface& t, - GLuint& textureWidth, GLuint& textureHeight) const +void LayerBase::loadTexture(Texture* texture, GLint textureName, + const Region& dirty, const GGLSurface& t) const { // TODO: defer the actual texture reload until LayerBase::validateTexture // is called. + texture->name = textureName; + GLuint& textureWidth(texture->width); + GLuint& textureHeight(texture->height); + uint32_t flags = mFlags; glBindTexture(GL_TEXTURE_2D, textureName); diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h index b5265d2b2b564..dad3d3d894586 100644 --- a/libs/surfaceflinger/LayerBase.h +++ b/libs/surfaceflinger/LayerBase.h @@ -20,6 +20,9 @@ #include #include +#include +#include + #include #include @@ -238,17 +241,23 @@ protected: GLuint createTexture() const; - void drawWithOpenGL(const Region& clip, - GLint textureName, - const sp& buffer, - int transform = 0) const; - + struct Texture { + Texture() : name(-1U), width(0), height(0), + image(EGL_NO_IMAGE_KHR), transform(0), dirty(true) { } + GLuint name; + GLuint width; + GLuint height; + EGLImageKHR image; + uint32_t transform; + bool dirty; + }; + void clearWithOpenGL(const Region& clip) const; + void drawWithOpenGL(const Region& clip, const Texture& texture) const; + void loadTexture(Texture* texture, GLint textureName, + const Region& dirty, const GGLSurface& t) const; - void loadTexture(const Region& dirty, - GLint textureName, const GGLSurface& t, - GLuint& textureWidth, GLuint& textureHeight) const; - + sp mFlinger; uint32_t mFlags; diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp index 02b3651140c40..3db5434564feb 100644 --- a/libs/surfaceflinger/LayerBuffer.cpp +++ b/libs/surfaceflinger/LayerBuffer.cpp @@ -276,8 +276,7 @@ bool LayerBuffer::Source::transformed() const { LayerBuffer::BufferSource::BufferSource(LayerBuffer& layer, const ISurface::BufferHeap& buffers) - : Source(layer), mStatus(NO_ERROR), - mBufferSize(0), mTextureName(-1U) + : Source(layer), mStatus(NO_ERROR), mBufferSize(0) { if (buffers.heap == NULL) { // this is allowed, but in this case, it is illegal to receive @@ -321,8 +320,8 @@ LayerBuffer::BufferSource::BufferSource(LayerBuffer& layer, LayerBuffer::BufferSource::~BufferSource() { - if (mTextureName != -1U) { - glDeleteTextures(1, &mTextureName); + if (mTexture.name != -1U) { + glDeleteTextures(1, &mTexture.name); } } @@ -380,37 +379,36 @@ bool LayerBuffer::BufferSource::transformed() const void LayerBuffer::BufferSource::onDraw(const Region& clip) const { - // FIXME: we should get a native buffer here - /* - sp ourBbuffer(getBuffer()); - if (UNLIKELY(buffer == 0)) { + sp ourBuffer(getBuffer()); + if (UNLIKELY(ourBuffer == 0)) { // nothing to do, we don't have a buffer mLayer.clearWithOpenGL(clip); return; } - // FIXME: We should model this after the overlay stuff - if (UNLIKELY(mTextureName == -1LU)) { - mTextureName = mLayer.createTexture(); - } + const NativeBuffer& src( ourBuffer->getBuffer() ); - // FIXME: Use EGLImage extension for this - - - - GGLSurface t; - status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_RARELY); - if (res == NO_ERROR) { + //if (!can_use_copybit || err) + { + // OpenGL fall-back + if (UNLIKELY(mTexture.name == -1LU)) { + mTexture.name = mLayer.createTexture(); + } GLuint w = 0; GLuint h = 0; - const Region dirty(Rect(buffer->width, buffer->height)); - mLayer.loadTexture(dirty, mTextureName, t, w, h); - buffer->unlock(); + GGLSurface t; + t.version = sizeof(GGLSurface); + t.width = src.crop.r; + t.height = src.crop.b; + t.stride = src.img.w; + t.vstride= src.img.h; + t.format = src.img.format; + t.data = (GGLubyte*)(intptr_t(src.img.base) + src.img.offset); + const Region dirty(Rect(t.width, t.height)); + mLayer.loadTexture(&mTexture, mTexture.name, dirty, t); + mTexture.transform = mBufferHeap.transform; + mLayer.drawWithOpenGL(clip, mTexture); } - if (res == NO_ERROR) { - mLayer.drawWithOpenGL(clip, mTextureName, buffer, mBufferHeap.transform); - } - */ } diff --git a/libs/surfaceflinger/LayerBuffer.h b/libs/surfaceflinger/LayerBuffer.h index 587d31b4ac82c..e1b3cf8bfe70c 100644 --- a/libs/surfaceflinger/LayerBuffer.h +++ b/libs/surfaceflinger/LayerBuffer.h @@ -121,13 +121,13 @@ private: virtual void unregisterBuffers(); virtual bool transformed() const; private: - mutable Mutex mLock; - sp mBuffer; - status_t mStatus; - ISurface::BufferHeap mBufferHeap; - size_t mBufferSize; - mutable sp mTempBitmap; - mutable GLuint mTextureName; + mutable Mutex mLock; + sp mBuffer; + status_t mStatus; + ISurface::BufferHeap mBufferHeap; + size_t mBufferSize; + mutable sp mTempBitmap; + mutable LayerBase::Texture mTexture; }; class OverlaySource : public Source { From f6c2a1ae60a190951b1c9e93f64f62a000cb51fd Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Tue, 23 Jun 2009 18:31:06 -0700 Subject: [PATCH 62/83] fix a bug where copybit would be rejected in landscape mode --- opengl/libagl/copybit.cpp | 45 ++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/opengl/libagl/copybit.cpp b/opengl/libagl/copybit.cpp index cde8f8a68af87..093a32d6d488a 100644 --- a/opengl/libagl/copybit.cpp +++ b/opengl/libagl/copybit.cpp @@ -163,15 +163,23 @@ static bool copybit(GLint x, GLint y, const GLint Wcr = crop_rect[2]; const GLint Hcr = crop_rect[3]; - int32_t dsdx = (Wcr << 16) / w; // dsdx = ((Wcr/w)/Wt)*Wt - int32_t dtdy = ((-Hcr) << 16) / h; // dtdy = -((Hcr/h)/Ht)*Ht - + int32_t dsdx = (Wcr << 16); // dsdx = ((Wcr/w)/Wt)*Wt + int32_t dtdy = ((-Hcr) << 16); // dtdy = -((Hcr/h)/Ht)*Ht + if (transform & COPYBIT_TRANSFORM_ROT_90) { + dsdx /= h; + dtdy /= w; + } else { + dsdx /= w; + dtdy /= h; + } if (dsdx < c->copybits.minScale || dsdx > c->copybits.maxScale || dtdy < c->copybits.minScale || dtdy > c->copybits.maxScale) { // The requested scale is out of the range the hardware // can support. LOGD_IF(DEBUG_COPYBIT, - "scale out of range dsdx=%08x, dtdy=%08x", dsdx, dtdy); + "scale out of range dsdx=%08x (Wcr=%d / w=%d), " + "dtdy=%08x (Hcr=%d / h=%d), Ucr=%d, Vcr=%d", + dsdx, Wcr, w, dtdy, Hcr, h, Ucr, Vcr); return false; } @@ -198,22 +206,30 @@ static bool copybit(GLint x, GLint y, static const int tmu = 0; texture_t& tev(c->rasterizer.state.texture[tmu]); bool srcTextureHasAlpha = hasAlpha(textureObject->surface.format); + if (!srcTextureHasAlpha) { + planeAlpha = fixedToByte(c->currentColorClamped.a); + } + switch (tev.env) { - case GGL_REPLACE: - if (!srcTextureHasAlpha) { - planeAlpha = fixedToByte(c->currentColorClamped.a); - } break; - case GGL_MODULATE: - if (! (c->currentColorClamped.r == FIXED_ONE - && c->currentColorClamped.g == FIXED_ONE - && c->currentColorClamped.b == FIXED_ONE)) { - LOGD_IF(DEBUG_COPYBIT, "MODULATE and non white color"); + if (! (c->currentColorClamped.r == FIXED_ONE && + c->currentColorClamped.g == FIXED_ONE && + c->currentColorClamped.b == FIXED_ONE)) { + LOGD_IF(DEBUG_COPYBIT, + "MODULATE and non white color (%08x, %08x, %08x)", + c->currentColorClamped.r, + c->currentColorClamped.g, + c->currentColorClamped.b); + return false; + } + if (srcTextureHasAlpha && c->currentColorClamped.a < FIXED_ONE) { + LOGD_IF(DEBUG_COPYBIT, + "MODULATE and texture w/alpha and alpha=%08x)", + c->currentColorClamped.a); return false; } - planeAlpha = fixedToByte(c->currentColorClamped.a); break; default: @@ -223,7 +239,6 @@ static bool copybit(GLint x, GLint y, } bool blending = false; - if ((enables & GGL_ENABLE_BLENDING) && !(c->rasterizer.state.blend.src == GL_ONE && c->rasterizer.state.blend.dst == GL_ZERO)) { From c6603951d45fc9b0d1776fec9444b6f31af92840 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Tue, 23 Jun 2009 20:06:46 -0700 Subject: [PATCH 63/83] fix a bug causing push-buffer surfaces' identity to be garbage, which resulted in some attributes (size/pos) to fail to be set --- libs/surfaceflinger/LayerBase.cpp | 8 ++++---- libs/surfaceflinger/LayerBase.h | 7 +++---- libs/surfaceflinger/LayerBuffer.cpp | 1 + 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp index 5fa14b2c93997..a841ab3348d10 100644 --- a/libs/surfaceflinger/LayerBase.cpp +++ b/libs/surfaceflinger/LayerBase.cpp @@ -53,8 +53,6 @@ const char* const LayerBaseClient::typeID = "LayerBaseClient"; // --------------------------------------------------------------------------- -int32_t LayerBase::sIdentity = 0; - LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display) : dpy(display), contentDirty(false), mFlinger(flinger), @@ -62,7 +60,6 @@ LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display) mOrientation(0), mTransactionFlags(0), mPremultipliedAlpha(true), - mIdentity(uint32_t(android_atomic_inc(&sIdentity))), mInvalidate(0) { const DisplayHardware& hw(flinger->graphicPlane(0).displayHardware()); @@ -644,11 +641,14 @@ regular: // --------------------------------------------------------------------------- +int32_t LayerBaseClient::sIdentity = 0; + LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display, const sp& client, int32_t i) : LayerBase(flinger, display), client(client), lcblk( client!=0 ? &(client->ctrlblk->layers[i]) : 0 ), - mIndex(i) + mIndex(i), + mIdentity(uint32_t(android_atomic_inc(&sIdentity))) { } diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h index dad3d3d894586..6fb1d1c50cabf 100644 --- a/libs/surfaceflinger/LayerBase.h +++ b/libs/surfaceflinger/LayerBase.h @@ -277,9 +277,6 @@ protected: // don't change, don't need a lock bool mPremultipliedAlpha; - // only read - const uint32_t mIdentity; - // atomic volatile int32_t mInvalidate; @@ -290,7 +287,6 @@ protected: private: LayerBase(const LayerBase& rhs); void validateTexture(GLint textureName) const; - static int32_t sIdentity; }; @@ -360,6 +356,9 @@ private: int32_t mIndex; mutable Mutex mLock; mutable wp mClientSurface; + // only read + const uint32_t mIdentity; + static int32_t sIdentity; }; // --------------------------------------------------------------------------- diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp index 3db5434564feb..22fd4994d5a6c 100644 --- a/libs/surfaceflinger/LayerBuffer.cpp +++ b/libs/surfaceflinger/LayerBuffer.cpp @@ -52,6 +52,7 @@ LayerBuffer::~LayerBuffer() void LayerBuffer::onFirstRef() { + LayerBaseClient::onFirstRef(); mSurface = new SurfaceBuffer(mFlinger, clientIndex(), const_cast(this)); } From cbc4c9f8d56317b2fe8964c15c9785ebeef98ca7 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Tue, 23 Jun 2009 21:11:43 -0700 Subject: [PATCH 64/83] hack copybit back in for video playback on msm7k. we have h/w accelerated video again --- include/ui/FramebufferNativeWindow.h | 8 +- .../DisplayHardware/DisplayHardware.cpp | 7 +- .../DisplayHardware/DisplayHardware.h | 6 +- libs/surfaceflinger/LayerBuffer.cpp | 124 +++++++++++++++++- libs/surfaceflinger/LayerBuffer.h | 3 + libs/ui/FramebufferNativeWindow.cpp | 6 + 6 files changed, 142 insertions(+), 12 deletions(-) diff --git a/include/ui/FramebufferNativeWindow.h b/include/ui/FramebufferNativeWindow.h index a7804728c4ea3..03d064cb36b8b 100644 --- a/include/ui/FramebufferNativeWindow.h +++ b/include/ui/FramebufferNativeWindow.h @@ -55,6 +55,9 @@ public: bool isUpdateOnDemand() const { return mUpdateOnDemand; } status_t setUpdateRectangle(const Rect& updateRect); + // FIXME: needed for copybit hack in LayerBuffer + android_native_buffer_t const* getBackbuffer() const; + private: friend class LightRefBase; ~FramebufferNativeWindow(); // this class cannot be overloaded @@ -75,8 +78,11 @@ private: int32_t mNumFreeBuffers; int32_t mBufferHead; bool mUpdateOnDemand; -}; + // FIXME: for getBackbuffer + int32_t mLastDequeued; +}; + // --------------------------------------------------------------------------- }; // namespace android // --------------------------------------------------------------------------- diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp index 784dfa585f556..925f5cc7a7a54 100644 --- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp +++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp @@ -349,10 +349,7 @@ void DisplayHardware::makeCurrent() const eglMakeCurrent(mDisplay, mSurface, mSurface, mContext); } -void DisplayHardware::copyFrontToImage(const copybit_image_t& front) const { - // FIXME: we need to get rid of this +sp DisplayHardware::getFb() const { + return mNativeWindow; } -void DisplayHardware::copyBackToImage(const copybit_image_t& front) const { - // FIXME: we need to get rid of this -} diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h index c3dbff178f290..240c5d148e357 100644 --- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h +++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h @@ -80,13 +80,13 @@ public: EGLDisplay getEGLDisplay() const { return mDisplay; } overlay_control_device_t* getOverlayEngine() const { return mOverlayEngine; } - void copyFrontToImage(const copybit_image_t& front) const; - void copyBackToImage(const copybit_image_t& front) const; - Rect bounds() const { return Rect(mWidth, mHeight); } + // FIXME: needed in LayerBuffer for msm7k/copybit hack + sp getFb() const; + private: void init(uint32_t displayIndex) __attribute__((noinline)); void fini() __attribute__((noinline)); diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp index 22fd4994d5a6c..1baf720b1e7b8 100644 --- a/libs/surfaceflinger/LayerBuffer.cpp +++ b/libs/surfaceflinger/LayerBuffer.cpp @@ -24,6 +24,9 @@ #include #include +#include + +#include #include "LayerBuffer.h" #include "SurfaceFlinger.h" @@ -316,7 +319,12 @@ LayerBuffer::BufferSource::BufferSource(LayerBuffer& layer, mLayer.setNeedsBlending((info.h_alpha - info.l_alpha) > 0); mBufferSize = info.getScanlineSize(buffers.hor_stride)*buffers.ver_stride; mLayer.forceVisibilityTransaction(); - + + hw_module_t const* module; + mBlitEngine = NULL; + if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) { + copybit_open(module, &mBlitEngine); + } } LayerBuffer::BufferSource::~BufferSource() @@ -387,9 +395,119 @@ void LayerBuffer::BufferSource::onDraw(const Region& clip) const return; } - const NativeBuffer& src( ourBuffer->getBuffer() ); + status_t err = NO_ERROR; + NativeBuffer src(ourBuffer->getBuffer()); + const Rect& transformedBounds = mLayer.getTransformedBounds(); + copybit_device_t* copybit = mBlitEngine; - //if (!can_use_copybit || err) + if (copybit) { + const int src_width = src.crop.r - src.crop.l; + const int src_height = src.crop.b - src.crop.t; + int W = transformedBounds.width(); + int H = transformedBounds.height(); + if (mLayer.getOrientation() & Transform::ROT_90) { + int t(W); W=H; H=t; + } + +#if 0 + /* With LayerBuffer, it is likely that we'll have to rescale the + * surface, because this is often used for video playback or + * camera-preview. Since we want these operation as fast as possible + * we make sure we can use the 2D H/W even if it doesn't support + * the requested scale factor, in which case we perform the scaling + * in several passes. */ + + const float min = copybit->get(copybit, COPYBIT_MINIFICATION_LIMIT); + const float mag = copybit->get(copybit, COPYBIT_MAGNIFICATION_LIMIT); + + float xscale = 1.0f; + if (src_width > W*min) xscale = 1.0f / min; + else if (src_width*mag < W) xscale = mag; + + float yscale = 1.0f; + if (src_height > H*min) yscale = 1.0f / min; + else if (src_height*mag < H) yscale = mag; + + if (UNLIKELY(xscale!=1.0f || yscale!=1.0f)) { + if (UNLIKELY(mTemporaryDealer == 0)) { + // allocate a memory-dealer for this the first time + mTemporaryDealer = mLayer.mFlinger->getSurfaceHeapManager() + ->createHeap(ISurfaceComposer::eHardware); + mTempBitmap.init(mTemporaryDealer); + } + + const int tmp_w = floorf(src_width * xscale); + const int tmp_h = floorf(src_height * yscale); + err = mTempBitmap.setBits(tmp_w, tmp_h, 1, src.img.format); + + if (LIKELY(err == NO_ERROR)) { + NativeBuffer tmp; + mTempBitmap.getBitmapSurface(&tmp.img); + tmp.crop.l = 0; + tmp.crop.t = 0; + tmp.crop.r = tmp.img.w; + tmp.crop.b = tmp.img.h; + + region_iterator tmp_it(Region(Rect(tmp.crop.r, tmp.crop.b))); + copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0); + copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF); + copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE); + err = copybit->stretch(copybit, + &tmp.img, &src.img, &tmp.crop, &src.crop, &tmp_it); + src = tmp; + } + } +#endif + + copybit_image_t dst; + const DisplayHardware& hw(mLayer.graphicPlane(0).displayHardware()); + sp fbw = hw.getFb(); + android_native_buffer_t const* nb = fbw->getBackbuffer(); + native_handle_t const* hnd = nb->handle; + + if (hnd->data[1] != 0x3141592) { + LOGE("buffer not compatible with copybit"); + err = -1; + } else { + + dst.w = 320; + dst.h = 480; + dst.format = 4; + dst.offset = hnd->data[4]; + dst.base = 0; + dst.fd = hnd->data[0]; + + const Rect& transformedBounds = mLayer.getTransformedBounds(); + const copybit_rect_t& drect + = reinterpret_cast(transformedBounds); + const State& s(mLayer.drawingState()); + region_iterator it(clip); + + // pick the right orientation for this buffer + int orientation = mLayer.getOrientation(); + if (UNLIKELY(mBufferHeap.transform)) { + Transform rot90; + GraphicPlane::orientationToTransfrom( + ISurfaceComposer::eOrientation90, 0, 0, &rot90); + const Transform& planeTransform(mLayer.graphicPlane(0).transform()); + const Layer::State& s(mLayer.drawingState()); + Transform tr(planeTransform * s.transform * rot90); + orientation = tr.getOrientation(); + } + + copybit->set_parameter(copybit, COPYBIT_TRANSFORM, orientation); + copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, s.alpha); + copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE); + + err = copybit->stretch(copybit, + &dst, &src.img, &drect, &src.crop, &it); + if (err != NO_ERROR) { + LOGE("copybit failed (%s)", strerror(err)); + } + } + } + + if (!copybit || err) { // OpenGL fall-back if (UNLIKELY(mTexture.name == -1LU)) { diff --git a/libs/surfaceflinger/LayerBuffer.h b/libs/surfaceflinger/LayerBuffer.h index e1b3cf8bfe70c..cd541a5130241 100644 --- a/libs/surfaceflinger/LayerBuffer.h +++ b/libs/surfaceflinger/LayerBuffer.h @@ -26,6 +26,8 @@ #include "LayerBase.h" #include "LayerBitmap.h" +struct copybit_device_t; + namespace android { // --------------------------------------------------------------------------- @@ -128,6 +130,7 @@ private: size_t mBufferSize; mutable sp mTempBitmap; mutable LayerBase::Texture mTexture; + copybit_device_t* mBlitEngine; }; class OverlaySource : public Source { diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp index 8c8fd6bb0f9dd..406c0725c0638 100644 --- a/libs/ui/FramebufferNativeWindow.cpp +++ b/libs/ui/FramebufferNativeWindow.cpp @@ -63,6 +63,11 @@ private: }; +android_native_buffer_t const* FramebufferNativeWindow::getBackbuffer() const { + return static_cast(buffers[mLastDequeued].get()); +} + + /* * This implements the (main) framebuffer management. This class is used * mostly by SurfaceFlinger, but also by command line GL application. @@ -165,6 +170,7 @@ int FramebufferNativeWindow::dequeueBuffer(android_native_window_t* window, if (self->mBufferHead >= self->mNumBuffers) self->mBufferHead = 0; + self->mLastDequeued = index; *buffer = self->buffers[index].get(); return 0; From 2eab9d8d7034ef05cead1ee26667a75061b5f0aa Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Wed, 24 Jun 2009 16:55:59 -0700 Subject: [PATCH 65/83] copybit now uses a native_handle_t* instead of a fd/offset --- libs/surfaceflinger/Android.mk | 2 + libs/surfaceflinger/LayerBuffer.cpp | 84 +++++++++++++++-------------- opengl/libagl/copybit.cpp | 7 +-- 3 files changed, 46 insertions(+), 47 deletions(-) diff --git a/libs/surfaceflinger/Android.mk b/libs/surfaceflinger/Android.mk index 29b88e9f56404..f718e7ada692f 100644 --- a/libs/surfaceflinger/Android.mk +++ b/libs/surfaceflinger/Android.mk @@ -47,6 +47,8 @@ LOCAL_SHARED_LIBRARIES := \ LOCAL_C_INCLUDES := \ $(call include-path-for, corecg graphics) +LOCAL_C_INCLUDES += hardware/libhardware/modules/gralloc + LOCAL_MODULE:= libsurfaceflinger include $(BUILD_SHARED_LIBRARY) diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp index 1baf720b1e7b8..58bba44a04598 100644 --- a/libs/surfaceflinger/LayerBuffer.cpp +++ b/libs/surfaceflinger/LayerBuffer.cpp @@ -32,6 +32,7 @@ #include "SurfaceFlinger.h" #include "DisplayHardware/DisplayHardware.h" +#include "gralloc_priv.h" // needed for msm / copybit namespace android { @@ -233,20 +234,28 @@ 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.offset = offset; - src.img.base = buffers.heap->base(); - src.img.fd = buffers.heap->heapID(); + + 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); + + private_handle_t* hnd = new private_handle_t( + buffers.heap->heapID(), buffers.heap->getSize(), 0); + hnd->offset = offset; + src.img.handle = hnd; } LayerBuffer::Buffer::~Buffer() { + NativeBuffer& src(mNativeBuffer); + if (src.img.handle) + delete (private_handle_t*)src.img.handle; } // ============================================================================ @@ -465,45 +474,38 @@ void LayerBuffer::BufferSource::onDraw(const Region& clip) const android_native_buffer_t const* nb = fbw->getBackbuffer(); native_handle_t const* hnd = nb->handle; - if (hnd->data[1] != 0x3141592) { - LOGE("buffer not compatible with copybit"); - err = -1; - } else { + dst.w = 320; + dst.h = 480; + dst.format = 4; + dst.base = 0; + dst.handle = (native_handle_t *)nb->handle; - dst.w = 320; - dst.h = 480; - dst.format = 4; - dst.offset = hnd->data[4]; - dst.base = 0; - dst.fd = hnd->data[0]; - - const Rect& transformedBounds = mLayer.getTransformedBounds(); - const copybit_rect_t& drect + const Rect& transformedBounds = mLayer.getTransformedBounds(); + const copybit_rect_t& drect = reinterpret_cast(transformedBounds); - const State& s(mLayer.drawingState()); - region_iterator it(clip); + const State& s(mLayer.drawingState()); + region_iterator it(clip); - // pick the right orientation for this buffer - int orientation = mLayer.getOrientation(); - if (UNLIKELY(mBufferHeap.transform)) { - Transform rot90; - GraphicPlane::orientationToTransfrom( - ISurfaceComposer::eOrientation90, 0, 0, &rot90); - const Transform& planeTransform(mLayer.graphicPlane(0).transform()); - const Layer::State& s(mLayer.drawingState()); - Transform tr(planeTransform * s.transform * rot90); - orientation = tr.getOrientation(); - } + // pick the right orientation for this buffer + int orientation = mLayer.getOrientation(); + if (UNLIKELY(mBufferHeap.transform)) { + Transform rot90; + GraphicPlane::orientationToTransfrom( + ISurfaceComposer::eOrientation90, 0, 0, &rot90); + const Transform& planeTransform(mLayer.graphicPlane(0).transform()); + const Layer::State& s(mLayer.drawingState()); + Transform tr(planeTransform * s.transform * rot90); + orientation = tr.getOrientation(); + } - copybit->set_parameter(copybit, COPYBIT_TRANSFORM, orientation); - copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, s.alpha); - copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE); + copybit->set_parameter(copybit, COPYBIT_TRANSFORM, orientation); + copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, s.alpha); + copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE); - err = copybit->stretch(copybit, - &dst, &src.img, &drect, &src.crop, &it); - if (err != NO_ERROR) { - LOGE("copybit failed (%s)", strerror(err)); - } + err = copybit->stretch(copybit, + &dst, &src.img, &drect, &src.crop, &it); + if (err != NO_ERROR) { + LOGE("copybit failed (%s)", strerror(err)); } } @@ -522,7 +524,7 @@ void LayerBuffer::BufferSource::onDraw(const Region& clip) const t.stride = src.img.w; t.vstride= src.img.h; t.format = src.img.format; - t.data = (GGLubyte*)(intptr_t(src.img.base) + src.img.offset); + t.data = (GGLubyte*)src.img.base; const Region dirty(Rect(t.width, t.height)); mLayer.loadTexture(&mTexture, mTexture.name, dirty, t); mTexture.transform = mBufferHeap.transform; diff --git a/opengl/libagl/copybit.cpp b/opengl/libagl/copybit.cpp index 093a32d6d488a..b6dedaeb5978d 100644 --- a/opengl/libagl/copybit.cpp +++ b/opengl/libagl/copybit.cpp @@ -32,7 +32,6 @@ #include #include #include -#include "gralloc_priv.h" #define DEBUG_COPYBIT true @@ -44,14 +43,11 @@ namespace android { static void textureToCopyBitImage( const GGLSurface* surface, buffer_handle_t buffer, copybit_image_t* img) { - // we know private_handle_t is good here - private_handle_t* hnd = (private_handle_t*)buffer; img->w = surface->stride; img->h = surface->height; img->format = surface->format; - img->offset = hnd->offset; img->base = surface->data; - img->fd = hnd->fd; + img->handle = (native_handle_t *)buffer; } struct clipRectRegion : public copybit_region_t { @@ -283,7 +279,6 @@ static bool copybit(GLint x, GLint y, textureToCopyBitImage(&cbSurface, target_hnd, &dst); copybit_rect_t drect = {x, y, x+w, y+h}; - // we know private_handle_t is good here copybit_image_t src; buffer_handle_t source_hnd = textureObject->buffer->handle; textureToCopyBitImage(&textureObject->surface, source_hnd, &src); From 3a7e1832ac940cf5b8f92d3c3e8e8e5303c3c34e Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Thu, 25 Jun 2009 00:01:11 -0700 Subject: [PATCH 66/83] fix [1942438] eglGetCurrentSurface() returns bogus value --- opengl/libs/EGL/egl.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp index 77648f280fc73..fec4e5d3a3d3f 100644 --- a/opengl/libs/EGL/egl.cpp +++ b/opengl/libs/EGL/egl.cpp @@ -965,23 +965,25 @@ EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw, if (!validate_display_context(dpy, ctx)) return EGL_FALSE; + EGLSurface impl_draw = EGL_NO_SURFACE; + EGLSurface impl_read = EGL_NO_SURFACE; egl_context_t * const c = get_context(ctx); if (draw != EGL_NO_SURFACE) { egl_surface_t const * d = get_surface(draw); if (!d) return setError(EGL_BAD_SURFACE, EGL_FALSE); if (d->impl != c->impl) return setError(EGL_BAD_MATCH, EGL_FALSE); - draw = d->surface; + impl_draw = d->surface; } if (read != EGL_NO_SURFACE) { egl_surface_t const * r = get_surface(read); if (!r) return setError(EGL_BAD_SURFACE, EGL_FALSE); if (r->impl != c->impl) return setError(EGL_BAD_MATCH, EGL_FALSE); - read = r->surface; + impl_read = r->surface; } EGLBoolean result = c->cnx->hooks->egl.eglMakeCurrent( - dp->dpys[c->impl], draw, read, c->context); + dp->dpys[c->impl], impl_draw, impl_read, c->context); if (result == EGL_TRUE) { setGlThreadSpecific(c->cnx->hooks); From c1e3ec555b79b1e45fccbdf0bbc8ac2d51902860 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Wed, 24 Jun 2009 22:37:39 -0700 Subject: [PATCH 67/83] Add eglGetRenderBufferANDROID() extension, which returns the current render buffer as an android_native_buffer_t* --- opengl/include/EGL/eglext.h | 16 ++++++++-- opengl/include/EGL/eglplatform.h | 6 ---- opengl/libagl/TextureObjectManager.h | 1 + opengl/libagl/egl.cpp | 45 ++++++++++++++++++++++++---- opengl/libs/EGL/egl.cpp | 17 +++++++++++ opengl/libs/EGL/egl_entries.in | 1 + 6 files changed, 72 insertions(+), 14 deletions(-) diff --git a/opengl/include/EGL/eglext.h b/opengl/include/EGL/eglext.h index 335b0b03dabb9..545fd0e980bd2 100644 --- a/opengl/include/EGL/eglext.h +++ b/opengl/include/EGL/eglext.h @@ -132,6 +132,20 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGL #endif +#ifndef EGL_ANDROID_image_native_buffer +#define EGL_ANDROID_image_native_buffer 1 +struct android_native_buffer_t; +#define EGL_NATIVE_BUFFER_ANDROID 0x3140 /* eglCreateImageKHR target */ +#endif + +#ifndef EGL_ANDROID_get_render_buffer +#define EGL_ANDROID_get_render_buffer 1 +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLClientBuffer EGLAPIENTRY eglGetRenderBufferANDROID(EGLDisplay dpy, EGLSurface draw); +#endif +typedef EGLClientBuffer (EGLAPIENTRYP PFNEGLGETRENDERBUFFERANDROIDPROC) (EGLDisplay dpy, EGLSurface draw); +#endif + #ifndef EGL_ANDROID_swap_rectangle #define EGL_ANDROID_swap_rectangle 1 #ifdef EGL_EGLEXT_PROTOTYPES @@ -141,8 +155,6 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLSETSWAPRECTANGLEANDROIDPROC) (EGLDisplay #endif - - #ifdef __cplusplus } #endif diff --git a/opengl/include/EGL/eglplatform.h b/opengl/include/EGL/eglplatform.h index 11aa4e2f41355..53e9e61169b13 100644 --- a/opengl/include/EGL/eglplatform.h +++ b/opengl/include/EGL/eglplatform.h @@ -96,12 +96,6 @@ typedef struct android_native_window_t* EGLNativeWindowType; typedef struct egl_native_pixmap_t* EGLNativePixmapType; typedef void* EGLNativeDisplayType; -#ifndef EGL_ANDROID_image_native_buffer -#define EGL_ANDROID_image_native_buffer 1 -struct android_native_buffer_t; -#define EGL_NATIVE_BUFFER_ANDROID 0x3140 /* eglCreateImageKHR target */ -#endif - #else #error "Platform not recognized" #endif diff --git a/opengl/libagl/TextureObjectManager.h b/opengl/libagl/TextureObjectManager.h index 496e6947d7371..279e0406c2120 100644 --- a/opengl/libagl/TextureObjectManager.h +++ b/opengl/libagl/TextureObjectManager.h @@ -31,6 +31,7 @@ #include #include +#include #include "Tokenizer.h" #include "TokenManager.h" diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp index c6d50578869aa..f6ffc53cfba83 100644 --- a/opengl/libagl/egl.cpp +++ b/opengl/libagl/egl.cpp @@ -158,6 +158,7 @@ struct egl_surface_t virtual EGLint getSwapBehavior() const; virtual EGLBoolean swapBuffers(); virtual EGLBoolean setSwapRectangle(EGLint l, EGLint t, EGLint w, EGLint h); + virtual EGLClientBuffer getRenderBuffer() const; protected: GGLSurface depth; }; @@ -196,6 +197,9 @@ EGLBoolean egl_surface_t::setSwapRectangle( { return EGL_FALSE; } +EGLClientBuffer egl_surface_t::getRenderBuffer() const { + return 0; +} // ---------------------------------------------------------------------------- @@ -221,7 +225,8 @@ struct egl_window_surface_v2_t : public egl_surface_t virtual EGLint getRefreshRate() const; virtual EGLint getSwapBehavior() const; virtual EGLBoolean setSwapRectangle(EGLint l, EGLint t, EGLint w, EGLint h); - + virtual EGLClientBuffer getRenderBuffer() const; + private: status_t lock(android_native_buffer_t* buf, int usage, void** vaddr); status_t unlock(android_native_buffer_t* buf); @@ -524,18 +529,24 @@ EGLBoolean egl_window_surface_v2_t::setSwapRectangle( return EGL_TRUE; } +EGLClientBuffer egl_window_surface_v2_t::getRenderBuffer() const +{ + return buffer; +} + #ifdef LIBAGL_USE_GRALLOC_COPYBITS static bool supportedCopybitsDestinationFormat(int format) { - // Hardware supported and no destination alpha + // Hardware supported switch (format) { case HAL_PIXEL_FORMAT_RGB_565: - case HAL_PIXEL_FORMAT_YCbCr_422_SP: - case HAL_PIXEL_FORMAT_YCbCr_420_SP: + case HAL_PIXEL_FORMAT_RGBA_8888: + case HAL_PIXEL_FORMAT_RGBA_4444: + case HAL_PIXEL_FORMAT_RGBA_5551: + case HAL_PIXEL_FORMAT_BGRA_8888: return true; - default: - return false; } + return false; } #endif @@ -778,6 +789,7 @@ static char const * const gExtensionsString = // "KHR_image_pixmap " "EGL_ANDROID_image_native_buffer " "EGL_ANDROID_swap_rectangle " + "EGL_ANDROID_get_render_buffer " ; // ---------------------------------------------------------------------------- @@ -824,6 +836,14 @@ static const extention_map_t gExtentionMap[] = { (__eglMustCastToProperFunctionPointerType)&glDeleteBuffers }, { "glGenBuffers", (__eglMustCastToProperFunctionPointerType)&glGenBuffers }, + { "eglCreateImageKHR", + (__eglMustCastToProperFunctionPointerType)&eglCreateImageKHR }, + { "eglDestroyImageKHR", + (__eglMustCastToProperFunctionPointerType)&eglDestroyImageKHR }, + { "eglSetSwapRectangleANDROID", + (__eglMustCastToProperFunctionPointerType)&eglSetSwapRectangleANDROID }, + { "eglGetRenderBufferANDROID", + (__eglMustCastToProperFunctionPointerType)&eglGetRenderBufferANDROID }, }; /* @@ -1984,3 +2004,16 @@ EGLBoolean eglSetSwapRectangleANDROID(EGLDisplay dpy, EGLSurface draw, return EGL_TRUE; } + +EGLClientBuffer eglGetRenderBufferANDROID(EGLDisplay dpy, EGLSurface draw) +{ + if (egl_display_t::is_valid(dpy) == EGL_FALSE) + return setError(EGL_BAD_DISPLAY, (EGLClientBuffer)0); + + egl_surface_t* d = static_cast(draw); + if (d->dpy != dpy) + return setError(EGL_BAD_DISPLAY, (EGLClientBuffer)0); + + // post the surface + return d->getRenderBuffer(); +} diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp index fec4e5d3a3d3f..004b74aedd170 100644 --- a/opengl/libs/EGL/egl.cpp +++ b/opengl/libs/EGL/egl.cpp @@ -58,6 +58,7 @@ static char const * const gExtensionString = "EGL_KHR_image_pixmap " "EGL_ANDROID_image_native_buffer " "EGL_ANDROID_swap_rectangle " + "EGL_ANDROID_get_render_buffer " ; // ---------------------------------------------------------------------------- @@ -303,6 +304,10 @@ static const extention_map_t gExtentionMap[] = { (__eglMustCastToProperFunctionPointerType)&eglCreateImageKHR }, { "eglDestroyImageKHR", (__eglMustCastToProperFunctionPointerType)&eglDestroyImageKHR }, + { "eglSetSwapRectangleANDROID", + (__eglMustCastToProperFunctionPointerType)&eglSetSwapRectangleANDROID }, + { "eglGetRenderBufferANDROID", + (__eglMustCastToProperFunctionPointerType)&eglGetRenderBufferANDROID }, }; static extention_map_t gGLExtentionMap[MAX_NUMBER_OF_GL_EXTENSIONS]; @@ -1484,3 +1489,15 @@ EGLBoolean eglSetSwapRectangleANDROID(EGLDisplay dpy, EGLSurface draw, return EGL_FALSE; } +EGLClientBuffer eglGetRenderBufferANDROID(EGLDisplay dpy, EGLSurface draw) +{ + if (!validate_display_surface(dpy, draw)) + return 0; + egl_display_t const * const dp = get_display(dpy); + egl_surface_t const * const s = get_surface(draw); + if (s->cnx->hooks->egl.eglGetRenderBufferANDROID) { + return s->cnx->hooks->egl.eglGetRenderBufferANDROID(dp->dpys[s->impl], + s->surface); + } + return 0; +} diff --git a/opengl/libs/EGL/egl_entries.in b/opengl/libs/EGL/egl_entries.in index 1fe2b5702d349..5d892872806af 100644 --- a/opengl/libs/EGL/egl_entries.in +++ b/opengl/libs/EGL/egl_entries.in @@ -54,3 +54,4 @@ EGL_ENTRY(EGLBoolean, eglDestroyImageKHR, EGLDisplay, EGLImageKHR) /* ANDROID extensions */ EGL_ENTRY(EGLBoolean, eglSetSwapRectangleANDROID, EGLDisplay, EGLSurface, EGLint, EGLint, EGLint, EGLint) +EGL_ENTRY(EGLClientBuffer, eglGetRenderBufferANDROID, EGLDisplay, EGLSurface) From 26c28b16f3464eeb98b091b915ccf494ac31c35f Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Wed, 24 Jun 2009 22:39:26 -0700 Subject: [PATCH 68/83] make use of new eglGetRenderBufferANDROID extension to clean-up a bit a few hacks added recently --- include/ui/FramebufferNativeWindow.h | 6 -- .../DisplayHardware/DisplayHardware.cpp | 5 -- .../DisplayHardware/DisplayHardware.h | 3 - libs/surfaceflinger/LayerBuffer.cpp | 75 ++++++++++--------- libs/ui/FramebufferNativeWindow.cpp | 6 -- 5 files changed, 40 insertions(+), 55 deletions(-) diff --git a/include/ui/FramebufferNativeWindow.h b/include/ui/FramebufferNativeWindow.h index 03d064cb36b8b..e72357a60190d 100644 --- a/include/ui/FramebufferNativeWindow.h +++ b/include/ui/FramebufferNativeWindow.h @@ -55,9 +55,6 @@ public: bool isUpdateOnDemand() const { return mUpdateOnDemand; } status_t setUpdateRectangle(const Rect& updateRect); - // FIXME: needed for copybit hack in LayerBuffer - android_native_buffer_t const* getBackbuffer() const; - private: friend class LightRefBase; ~FramebufferNativeWindow(); // this class cannot be overloaded @@ -78,9 +75,6 @@ private: int32_t mNumFreeBuffers; int32_t mBufferHead; bool mUpdateOnDemand; - - // FIXME: for getBackbuffer - int32_t mLastDequeued; }; // --------------------------------------------------------------------------- diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp index 925f5cc7a7a54..1719b7443b631 100644 --- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp +++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp @@ -348,8 +348,3 @@ void DisplayHardware::makeCurrent() const { eglMakeCurrent(mDisplay, mSurface, mSurface, mContext); } - -sp DisplayHardware::getFb() const { - return mNativeWindow; -} - diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h index 240c5d148e357..8972d513fdaa9 100644 --- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h +++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h @@ -84,9 +84,6 @@ public: return Rect(mWidth, mHeight); } - // FIXME: needed in LayerBuffer for msm7k/copybit hack - sp getFb() const; - private: void init(uint32_t displayIndex) __attribute__((noinline)); void fini() __attribute__((noinline)); diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp index 58bba44a04598..d70a71f4568c5 100644 --- a/libs/surfaceflinger/LayerBuffer.cpp +++ b/libs/surfaceflinger/LayerBuffer.cpp @@ -468,47 +468,52 @@ void LayerBuffer::BufferSource::onDraw(const Region& clip) const } #endif - copybit_image_t dst; - const DisplayHardware& hw(mLayer.graphicPlane(0).displayHardware()); - sp fbw = hw.getFb(); - android_native_buffer_t const* nb = fbw->getBackbuffer(); - native_handle_t const* hnd = nb->handle; +#ifdef EGL_ANDROID_get_render_buffer + EGLDisplay dpy = eglGetCurrentDisplay(); + EGLSurface draw = eglGetCurrentSurface(EGL_DRAW); + EGLClientBuffer clientBuf = eglGetRenderBufferANDROID(dpy, draw); + android_native_buffer_t* nb = (android_native_buffer_t*)clientBuf; + if (nb == 0) { + err = BAD_VALUE; + } else { + copybit_image_t dst; + dst.w = nb->width; + dst.h = nb->height; + dst.format = nb->format; + dst.base = NULL; // unused by copybit on msm7k + dst.handle = (native_handle_t *)nb->handle; - dst.w = 320; - dst.h = 480; - dst.format = 4; - dst.base = 0; - dst.handle = (native_handle_t *)nb->handle; + const Rect& transformedBounds = mLayer.getTransformedBounds(); + const copybit_rect_t& drect + = reinterpret_cast(transformedBounds); + const State& s(mLayer.drawingState()); + region_iterator it(clip); - const Rect& transformedBounds = mLayer.getTransformedBounds(); - const copybit_rect_t& drect - = reinterpret_cast(transformedBounds); - const State& s(mLayer.drawingState()); - region_iterator it(clip); + // pick the right orientation for this buffer + int orientation = mLayer.getOrientation(); + if (UNLIKELY(mBufferHeap.transform)) { + Transform rot90; + GraphicPlane::orientationToTransfrom( + ISurfaceComposer::eOrientation90, 0, 0, &rot90); + const Transform& planeTransform(mLayer.graphicPlane(0).transform()); + const Layer::State& s(mLayer.drawingState()); + Transform tr(planeTransform * s.transform * rot90); + orientation = tr.getOrientation(); + } - // pick the right orientation for this buffer - int orientation = mLayer.getOrientation(); - if (UNLIKELY(mBufferHeap.transform)) { - Transform rot90; - GraphicPlane::orientationToTransfrom( - ISurfaceComposer::eOrientation90, 0, 0, &rot90); - const Transform& planeTransform(mLayer.graphicPlane(0).transform()); - const Layer::State& s(mLayer.drawingState()); - Transform tr(planeTransform * s.transform * rot90); - orientation = tr.getOrientation(); - } + copybit->set_parameter(copybit, COPYBIT_TRANSFORM, orientation); + copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, s.alpha); + copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE); - copybit->set_parameter(copybit, COPYBIT_TRANSFORM, orientation); - copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, s.alpha); - copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE); - - err = copybit->stretch(copybit, - &dst, &src.img, &drect, &src.crop, &it); - if (err != NO_ERROR) { - LOGE("copybit failed (%s)", strerror(err)); + err = copybit->stretch(copybit, + &dst, &src.img, &drect, &src.crop, &it); + if (err != NO_ERROR) { + LOGE("copybit failed (%s)", strerror(err)); + } } } - +#endif + if (!copybit || err) { // OpenGL fall-back diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp index 406c0725c0638..8c8fd6bb0f9dd 100644 --- a/libs/ui/FramebufferNativeWindow.cpp +++ b/libs/ui/FramebufferNativeWindow.cpp @@ -63,11 +63,6 @@ private: }; -android_native_buffer_t const* FramebufferNativeWindow::getBackbuffer() const { - return static_cast(buffers[mLastDequeued].get()); -} - - /* * This implements the (main) framebuffer management. This class is used * mostly by SurfaceFlinger, but also by command line GL application. @@ -170,7 +165,6 @@ int FramebufferNativeWindow::dequeueBuffer(android_native_window_t* window, if (self->mBufferHead >= self->mNumBuffers) self->mBufferHead = 0; - self->mLastDequeued = index; *buffer = self->buffers[index].get(); return 0; From 68eeb80a54f411b9a8c928cc193de731adddb6c3 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Thu, 25 Jun 2009 15:39:25 -0700 Subject: [PATCH 69/83] use copybit for eglSwapBuffers() copy-back operations --- libs/surfaceflinger/LayerBuffer.cpp | 5 +- opengl/libagl/egl.cpp | 161 +++++++++++++++++++--------- 2 files changed, 113 insertions(+), 53 deletions(-) diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp index d70a71f4568c5..1827efad8a784 100644 --- a/libs/surfaceflinger/LayerBuffer.cpp +++ b/libs/surfaceflinger/LayerBuffer.cpp @@ -341,6 +341,9 @@ LayerBuffer::BufferSource::~BufferSource() if (mTexture.name != -1U) { glDeleteTextures(1, &mTexture.name); } + if (mBlitEngine) { + copybit_close(mBlitEngine); + } } void LayerBuffer::BufferSource::postBuffer(ssize_t offset) @@ -485,7 +488,7 @@ void LayerBuffer::BufferSource::onDraw(const Region& clip) const const Rect& transformedBounds = mLayer.getTransformedBounds(); const copybit_rect_t& drect - = reinterpret_cast(transformedBounds); + = reinterpret_cast(transformedBounds); const State& s(mLayer.drawingState()); region_iterator it(clip); diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp index f6ffc53cfba83..0fc934f0d5fab 100644 --- a/opengl/libagl/egl.cpp +++ b/opengl/libagl/egl.cpp @@ -41,6 +41,8 @@ #include +#include + #include "context.h" #include "state.h" #include "texture.h" @@ -234,6 +236,7 @@ private: android_native_buffer_t* buffer; android_native_buffer_t* previousBuffer; gralloc_module_t const* module; + copybit_device_t* blitengine; int width; int height; void* bits; @@ -268,6 +271,9 @@ private: struct Region { inline Region() : count(0) { } + typedef Rect const* const_iterator; + const_iterator begin() const { return storage; } + const_iterator end() const { return storage+count; } static Region subtract(const Rect& lhs, const Rect& rhs) { Region reg; Rect* storage = reg.storage; @@ -276,26 +282,30 @@ private: storage->left = lhs.left; storage->top = lhs.top; storage->right = lhs.right; - storage->bottom = max(lhs.top, rhs.top); + storage->bottom = rhs.top; storage++; } - if (lhs.left < rhs.left) { // left-side rect - storage->left = lhs.left; - storage->top = max(lhs.top, rhs.top); - storage->right = max(lhs.left, rhs.left); - storage->bottom = min(lhs.bottom, rhs.bottom); - storage++; - } - if (lhs.right > rhs.right) { // right-side rect - storage->left = min(lhs.right, rhs.right); - storage->top = max(lhs.top, rhs.top); - storage->right = lhs.right; - storage->bottom = min(lhs.bottom, rhs.bottom); - storage++; + const int32_t top = max(lhs.top, rhs.top); + const int32_t bot = min(lhs.bottom, rhs.bottom); + if (top < bot) { + if (lhs.left < rhs.left) { // left-side rect + storage->left = lhs.left; + storage->top = top; + storage->right = rhs.left; + storage->bottom = bot; + storage++; + } + if (lhs.right > rhs.right) { // right-side rect + storage->left = rhs.right; + storage->top = top; + storage->right = lhs.right; + storage->bottom = bot; + storage++; + } } if (lhs.bottom > rhs.bottom) { // bottom rect storage->left = lhs.left; - storage->top = min(lhs.bottom, rhs.bottom); + storage->top = rhs.bottom; storage->right = lhs.right; storage->bottom = lhs.bottom; storage++; @@ -307,19 +317,33 @@ private: bool isEmpty() const { return count<=0; } - ssize_t getRects(Rect const* * rects) const { - *rects = storage; - return count; - } private: Rect storage[4]; ssize_t count; }; + struct region_iterator : public copybit_region_t { + region_iterator(const Region& region) + : b(region.begin()), e(region.end()) { + this->next = iterate; + } + private: + static int iterate(copybit_region_t const * self, copybit_rect_t* rect) { + region_iterator const* me = static_cast(self); + if (me->b != me->e) { + *reinterpret_cast(rect) = *me->b++; + return 1; + } + return 0; + } + mutable Region::const_iterator b; + Region::const_iterator const e; + }; + void copyBlt( android_native_buffer_t* dst, void* dst_vaddr, android_native_buffer_t* src, void const* src_vaddr, - const Rect* reg, ssize_t count); + const Region& clip); Rect dirtyRegion; Rect oldDirtyRegion; @@ -331,12 +355,16 @@ egl_window_surface_v2_t::egl_window_surface_v2_t(EGLDisplay dpy, android_native_window_t* window) : egl_surface_t(dpy, config, depthFormat), nativeWindow(window), buffer(0), previousBuffer(0), module(0), - bits(NULL) + blitengine(0), bits(NULL) { hw_module_t const* pModule; hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule); module = reinterpret_cast(pModule); + if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &pModule) == 0) { + copybit_open(pModule, &blitengine); + } + pixelFormatTable = gglGetPixelFormatTable(); // keep a reference on the window @@ -371,6 +399,9 @@ egl_window_surface_v2_t::~egl_window_surface_v2_t() { previousBuffer->common.decRef(&previousBuffer->common); } nativeWindow->common.decRef(&nativeWindow->common); + if (blitengine) { + copybit_close(blitengine); + } } void egl_window_surface_v2_t::connect() @@ -380,7 +411,7 @@ void egl_window_surface_v2_t::connect() // pin the buffer down if (lock(buffer, GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, &bits) != NO_ERROR) { - LOGE("eglSwapBuffers() failed to lock buffer %p (%ux%u)", + LOGE("connect() failed to lock buffer %p (%ux%u)", buffer, buffer->width, buffer->height); setError(EGL_BAD_ACCESS, EGL_NO_SURFACE); // FIXME: we should make sure we're not accessing the buffer anymore @@ -412,36 +443,65 @@ status_t egl_window_surface_v2_t::unlock(android_native_buffer_t* buf) void egl_window_surface_v2_t::copyBlt( android_native_buffer_t* dst, void* dst_vaddr, android_native_buffer_t* src, void const* src_vaddr, - const Rect* reg, ssize_t count) + const Region& clip) { // FIXME: use copybit if possible // NOTE: dst and src must be the same format - Rect r; - const size_t bpp = pixelFormatTable[src->format].size; - const size_t dbpr = dst->stride * bpp; - const size_t sbpr = src->stride * bpp; + status_t err = NO_ERROR; + copybit_device_t* const copybit = blitengine; + if (copybit) { + copybit_image_t simg; + simg.w = src->width; + simg.h = src->height; + simg.format = src->format; + simg.handle = const_cast(src->handle); - uint8_t const * const src_bits = (uint8_t const *)src_vaddr; - uint8_t * const dst_bits = (uint8_t *)dst_vaddr; - - for (int i= 0 ; istride * r.top) * bpp; - uint8_t * d = dst_bits + (r.left + dst->stride * r.top) * bpp; - if (dbpr==sbpr && size==sbpr) { - size *= h; - h = 1; + copybit_image_t dimg; + dimg.w = dst->width; + dimg.h = dst->height; + dimg.format = dst->format; + dimg.handle = const_cast(dst->handle); + + copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0); + copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 255); + copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE); + region_iterator it(clip); + err = copybit->blit(copybit, &dimg, &simg, &it); + if (err != NO_ERROR) { + LOGE("copybit failed (%s)", strerror(err)); + } + } + + if (!copybit || err) { + Region::const_iterator cur = clip.begin(); + Region::const_iterator end = clip.end(); + + const size_t bpp = pixelFormatTable[src->format].size; + const size_t dbpr = dst->stride * bpp; + const size_t sbpr = src->stride * bpp; + + uint8_t const * const src_bits = (uint8_t const *)src_vaddr; + uint8_t * const dst_bits = (uint8_t *)dst_vaddr; + + while (cur != end) { + const Rect& r(*cur++); + ssize_t w = r.right - r.left; + ssize_t h = r.bottom - r.top; + if (w <= 0 || h<=0) continue; + size_t size = w * bpp; + uint8_t const * s = src_bits + (r.left + src->stride * r.top) * bpp; + uint8_t * d = dst_bits + (r.left + dst->stride * r.top) * bpp; + if (dbpr==sbpr && size==sbpr) { + size *= h; + h = 1; + } + do { + memcpy(d, s, size); + d += dbpr; + s += sbpr; + } while (--h > 0); } - do { - memcpy(d, s, size); - d += dbpr; - s += sbpr; - } while (--h > 0); } } @@ -456,14 +516,11 @@ EGLBoolean egl_window_surface_v2_t::swapBuffers() if (previousBuffer) { const Region copyBack(Region::subtract(oldDirtyRegion, dirtyRegion)); if (!copyBack.isEmpty()) { - Rect const* list; - ssize_t count = copyBack.getRects(&list); - // copy from previousBuffer to buffer void* prevBits; if (lock(previousBuffer, - GRALLOC_USAGE_SW_READ_OFTEN, &prevBits) == NO_ERROR) - { - copyBlt(buffer, bits, previousBuffer, prevBits, list, count); + GRALLOC_USAGE_SW_READ_OFTEN, &prevBits) == NO_ERROR) { + // copy from previousBuffer to buffer + copyBlt(buffer, bits, previousBuffer, prevBits, copyBack); unlock(previousBuffer); } } From dafb08dcd5c02ad18e91597187d90a1ba90e8096 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Thu, 25 Jun 2009 16:21:32 -0700 Subject: [PATCH 70/83] use 1/16 the size (20KB) for the dim texture in the copybit/msm case --- libs/surfaceflinger/LayerDim.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libs/surfaceflinger/LayerDim.cpp b/libs/surfaceflinger/LayerDim.cpp index 5cb883c661f22..4114a42bd5b16 100644 --- a/libs/surfaceflinger/LayerDim.cpp +++ b/libs/surfaceflinger/LayerDim.cpp @@ -63,6 +63,12 @@ void LayerDim::initDimmer(SurfaceFlinger* flinger, uint32_t w, uint32_t h) * This burns a full-screen worth of graphic memory. */ + // copybit supports 4x scaling, so we only need to allocate 1/16 of the + // buffer. + // FIXME: we have to add 1px because the mdp fails + w = w/4 + 1; + h = h/4 + 1; + const DisplayHardware& hw(flinger->graphicPlane(0).displayHardware()); uint32_t flags = hw.getFlags(); @@ -93,7 +99,7 @@ void LayerDim::initDimmer(SurfaceFlinger* flinger, uint32_t w, uint32_t h) // initialize the texture with zeros GGLSurface t; buffer->lock(&t, GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN); - memset(t.data, 0, t.width * t.stride * 2); + memset(t.data, 0, t.stride * t.height * 2); buffer->unlock(); sUseTexture = true; } From 8f78faa1ef7e2436d11e4c04be67b5a95bf126b9 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Thu, 25 Jun 2009 17:41:12 -0700 Subject: [PATCH 71/83] add support for out-of-range copybit scaling. camera capture is in color again --- libs/surfaceflinger/LayerBuffer.cpp | 107 ++++++++++++++-------------- 1 file changed, 55 insertions(+), 52 deletions(-) diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp index 1827efad8a784..a088b0acd06b4 100644 --- a/libs/surfaceflinger/LayerBuffer.cpp +++ b/libs/surfaceflinger/LayerBuffer.cpp @@ -245,6 +245,8 @@ LayerBuffer::Buffer::Buffer(const ISurface::BufferHeap& buffers, ssize_t offset) src.img.format = buffers.format; src.img.base = (void*)(intptr_t(buffers.heap->base()) + offset); + // 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; @@ -421,56 +423,6 @@ void LayerBuffer::BufferSource::onDraw(const Region& clip) const int t(W); W=H; H=t; } -#if 0 - /* With LayerBuffer, it is likely that we'll have to rescale the - * surface, because this is often used for video playback or - * camera-preview. Since we want these operation as fast as possible - * we make sure we can use the 2D H/W even if it doesn't support - * the requested scale factor, in which case we perform the scaling - * in several passes. */ - - const float min = copybit->get(copybit, COPYBIT_MINIFICATION_LIMIT); - const float mag = copybit->get(copybit, COPYBIT_MAGNIFICATION_LIMIT); - - float xscale = 1.0f; - if (src_width > W*min) xscale = 1.0f / min; - else if (src_width*mag < W) xscale = mag; - - float yscale = 1.0f; - if (src_height > H*min) yscale = 1.0f / min; - else if (src_height*mag < H) yscale = mag; - - if (UNLIKELY(xscale!=1.0f || yscale!=1.0f)) { - if (UNLIKELY(mTemporaryDealer == 0)) { - // allocate a memory-dealer for this the first time - mTemporaryDealer = mLayer.mFlinger->getSurfaceHeapManager() - ->createHeap(ISurfaceComposer::eHardware); - mTempBitmap.init(mTemporaryDealer); - } - - const int tmp_w = floorf(src_width * xscale); - const int tmp_h = floorf(src_height * yscale); - err = mTempBitmap.setBits(tmp_w, tmp_h, 1, src.img.format); - - if (LIKELY(err == NO_ERROR)) { - NativeBuffer tmp; - mTempBitmap.getBitmapSurface(&tmp.img); - tmp.crop.l = 0; - tmp.crop.t = 0; - tmp.crop.r = tmp.img.w; - tmp.crop.b = tmp.img.h; - - region_iterator tmp_it(Region(Rect(tmp.crop.r, tmp.crop.b))); - copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0); - copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF); - copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE); - err = copybit->stretch(copybit, - &tmp.img, &src.img, &tmp.crop, &src.crop, &tmp_it); - src = tmp; - } - } -#endif - #ifdef EGL_ANDROID_get_render_buffer EGLDisplay dpy = eglGetCurrentDisplay(); EGLSurface draw = eglGetCurrentSurface(EGL_DRAW); @@ -486,9 +438,60 @@ void LayerBuffer::BufferSource::onDraw(const Region& clip) const dst.base = NULL; // unused by copybit on msm7k dst.handle = (native_handle_t *)nb->handle; + /* With LayerBuffer, it is likely that we'll have to rescale the + * surface, because this is often used for video playback or + * camera-preview. Since we want these operation as fast as possible + * we make sure we can use the 2D H/W even if it doesn't support + * the requested scale factor, in which case we perform the scaling + * in several passes. */ + + const float min = copybit->get(copybit, COPYBIT_MINIFICATION_LIMIT); + const float mag = copybit->get(copybit, COPYBIT_MAGNIFICATION_LIMIT); + + float xscale = 1.0f; + if (src_width > W*min) xscale = 1.0f / min; + else if (src_width*mag < W) xscale = mag; + + float yscale = 1.0f; + if (src_height > H*min) yscale = 1.0f / min; + else if (src_height*mag < H) yscale = mag; + + if (UNLIKELY(xscale!=1.0f || yscale!=1.0f)) { + const int tmp_w = floorf(src_width * xscale); + const int tmp_h = floorf(src_height * yscale); + + if (mTempBitmap==0 || + mTempBitmap->getWidth() < tmp_w || + mTempBitmap->getHeight() < tmp_h) { + mTempBitmap.clear(); + mTempBitmap = new android::Buffer(tmp_w, tmp_h, src.img.format); + err = mTempBitmap->initCheck(); + } + + if (LIKELY(err == NO_ERROR)) { + NativeBuffer tmp; + tmp.img.w = tmp_w; + tmp.img.h = tmp_h; + tmp.img.format = src.img.format; + tmp.img.handle = (native_handle_t*)mTempBitmap->getNativeBuffer()->handle; + tmp.crop.l = 0; + tmp.crop.t = 0; + tmp.crop.r = tmp.img.w; + tmp.crop.b = tmp.img.h; + + region_iterator tmp_it(Region(Rect(tmp.crop.r, tmp.crop.b))); + copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0); + copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF); + copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE); + err = copybit->stretch(copybit, + &tmp.img, &src.img, &tmp.crop, &src.crop, &tmp_it); + src = tmp; + } + } + const Rect& transformedBounds = mLayer.getTransformedBounds(); - const copybit_rect_t& drect - = reinterpret_cast(transformedBounds); + const copybit_rect_t& drect = + reinterpret_cast(transformedBounds); const State& s(mLayer.drawingState()); region_iterator it(clip); From 5a8d6f44b2ec9132848aee5f608447ff801951b2 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Fri, 26 Jun 2009 19:02:40 -0700 Subject: [PATCH 72/83] return bounds Rect by value --- include/ui/Region.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/ui/Region.h b/include/ui/Region.h index 4299ea5a97872..df455a96b16d6 100644 --- a/include/ui/Region.h +++ b/include/ui/Region.h @@ -48,8 +48,8 @@ public: inline bool isEmpty() const { return mBounds.isEmpty(); } inline bool isRect() const { return mStorage.isEmpty(); } - inline const Rect& getBounds() const { return mBounds; } - inline const Rect& bounds() const { return getBounds(); } + inline Rect getBounds() const { return mBounds; } + inline Rect bounds() const { return getBounds(); } void clear(); void set(const Rect& r); From 8c9687ae291a1e0a63d4236069066284f56192cd Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Fri, 26 Jun 2009 19:06:36 -0700 Subject: [PATCH 73/83] fix an update bug with SHOW_UPDATE debug feature. Fix a problem with the debug binder codes too --- .../DisplayHardware/DisplayHardware.cpp | 5 ++-- libs/surfaceflinger/SurfaceFlinger.cpp | 25 +++++++++++++------ 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp index 1719b7443b631..b981319b2ba04 100644 --- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp +++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp @@ -318,9 +318,8 @@ void DisplayHardware::flip(const Region& dirty) const #ifdef EGL_ANDROID_swap_rectangle if (mFlags & SWAP_RECTANGLE) { - Region newDirty(dirty); - newDirty.andSelf(Rect(mWidth, mHeight)); - const Rect& b(newDirty.bounds()); + const Region newDirty(dirty.intersect(bounds())); + const Rect b(newDirty.getBounds()); eglSetSwapRectangleANDROID(dpy, surface, b.left, b.top, b.width(), b.height()); } diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp index 2e7bbeafcf0aa..106af3f8bcf9c 100644 --- a/libs/surfaceflinger/SurfaceFlinger.cpp +++ b/libs/surfaceflinger/SurfaceFlinger.cpp @@ -803,19 +803,24 @@ void SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers) } } + void SurfaceFlinger::handleRepaint() { - // set the frame buffer - const DisplayHardware& hw(graphicPlane(0).displayHardware()); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); + // compute the invalid region + mInvalidRegion.orSelf(mDirtyRegion); + if (mInvalidRegion.isEmpty()) { + // nothing to do + return; + } if (UNLIKELY(mDebugRegion)) { debugFlashRegions(); } - // compute the invalid region - mInvalidRegion.orSelf(mDirtyRegion); + // set the frame buffer + const DisplayHardware& hw(graphicPlane(0).displayHardware()); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); uint32_t flags = hw.getFlags(); if ((flags & DisplayHardware::SWAP_RECTANGLE) || @@ -945,8 +950,11 @@ void SurfaceFlinger::debugFlashRegions() glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } - hw.flip(mDirtyRegion.merge(mInvalidRegion)); - mInvalidRegion.clear(); + if (mInvalidRegion.isEmpty()) { + mDirtyRegion.dump("mDirtyRegion"); + mInvalidRegion.dump("mInvalidRegion"); + } + hw.flip(mInvalidRegion); if (mDebugRegion > 1) usleep(mDebugRegion * 1000); @@ -1549,6 +1557,7 @@ status_t SurfaceFlinger::onTransact( } status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags); if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) { + CHECK_INTERFACE(ISurfaceComposer, data, reply); if (UNLIKELY(!mHardwareTest.checkCalling())) { IPCThreadState* ipc = IPCThreadState::self(); const int pid = ipc->getCallingPid(); From 0aed7e97a3efbeec23a4aa301df03036a67f8ea3 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Sun, 28 Jun 2009 02:54:16 -0700 Subject: [PATCH 74/83] fix [1947273] the DimLayer causes the whole screen to update during transactions --- libs/surfaceflinger/SurfaceFlinger.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp index 106af3f8bcf9c..17cff553f9635 100644 --- a/libs/surfaceflinger/SurfaceFlinger.cpp +++ b/libs/surfaceflinger/SurfaceFlinger.cpp @@ -725,10 +725,11 @@ void SurfaceFlinger::computeVisibleRegions( dirty.orSelf(layer->visibleRegionScreen); layer->contentDirty = false; } else { - // compute the exposed region - // dirty = what's visible now - what's wasn't covered before - // = what's visible now & what's was covered before - dirty = visibleRegion.intersect(layer->coveredRegionScreen); + /* compute the exposed region: + * exposed = what's VISIBLE and NOT COVERED now + * but was COVERED before + */ + dirty = (visibleRegion - coveredRegion) & layer->coveredRegionScreen; } dirty.subtractSelf(aboveOpaqueLayers); @@ -737,7 +738,7 @@ void SurfaceFlinger::computeVisibleRegions( // Update aboveOpaqueLayers/aboveCoveredLayers for next (lower) layer aboveOpaqueLayers.orSelf(opaqueRegion); - aboveCoveredLayers.orSelf(bounds); + aboveCoveredLayers.orSelf(visibleRegion); // Store the visible region is screen space layer->setVisibleRegion(visibleRegion); From 0f53af13b783eafa566722eb118aabcb84d88da5 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Mon, 29 Jun 2009 16:36:49 -0700 Subject: [PATCH 75/83] fix a bug where gl didn't always fallback to software when copybit failed. minor optimizations to copybit codepath. --- opengl/libagl/copybit.cpp | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/opengl/libagl/copybit.cpp b/opengl/libagl/copybit.cpp index b6dedaeb5978d..3331026f66b97 100644 --- a/opengl/libagl/copybit.cpp +++ b/opengl/libagl/copybit.cpp @@ -159,15 +159,19 @@ static bool copybit(GLint x, GLint y, const GLint Wcr = crop_rect[2]; const GLint Hcr = crop_rect[3]; - int32_t dsdx = (Wcr << 16); // dsdx = ((Wcr/w)/Wt)*Wt - int32_t dtdy = ((-Hcr) << 16); // dtdy = -((Hcr/h)/Ht)*Ht + GLint screen_w = w; + GLint screen_h = h; + int32_t dsdx = Wcr << 16; // dsdx = ((Wcr/screen_w)/Wt)*Wt + int32_t dtdy = Hcr << 16; // dtdy = -((Hcr/screen_h)/Ht)*Ht if (transform & COPYBIT_TRANSFORM_ROT_90) { - dsdx /= h; - dtdy /= w; - } else { - dsdx /= w; - dtdy /= h; + swap(screen_w, screen_h); } + if (dsdx!=screen_w || dtdy!=screen_h) { + // in most cases the divide is not needed + dsdx /= screen_w; + dtdy /= screen_h; + } + dtdy = -dtdy; // see equation of dtdy above if (dsdx < c->copybits.minScale || dsdx > c->copybits.maxScale || dtdy < c->copybits.minScale || dtdy > c->copybits.maxScale) { // The requested scale is out of the range the hardware @@ -290,8 +294,8 @@ static bool copybit(GLint x, GLint y, (enables & GGL_ENABLE_DITHER) ? COPYBIT_ENABLE : COPYBIT_DISABLE); clipRectRegion it(c); - copybit->stretch(copybit, &dst, &src, &drect, &srect, &it); - return true; + status_t err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it); + return err == NO_ERROR ? true : false; } /* @@ -365,24 +369,24 @@ bool drawTriangleFanWithCopybit_impl(ogles_context_t* c, GLint first, GLsizei co // only need to consider 3 vertices for computing the jacobians const int dx01 = v1.x - v0.x; - const int dy01 = v1.y - v0.y; const int dx02 = v2.x - v0.x; + const int dy01 = v1.y - v0.y; const int dy02 = v2.y - v0.y; const int ds01 = t1.S - t0.S; - const int dt01 = t1.T - t0.T; const int ds02 = t2.S - t0.S; + const int dt01 = t1.T - t0.T; const int dt02 = t2.T - t0.T; const int area = dx01*dy02 - dy01*dx02; int dsdx, dsdy, dtdx, dtdy; if (area >= 0) { dsdx = ds01*dy02 - ds02*dy01; - dsdy = ds02*dx01 - ds01*dx02; dtdx = dt01*dy02 - dt02*dy01; + dsdy = ds02*dx01 - ds01*dx02; dtdy = dt02*dx01 - dt01*dx02; } else { dsdx = ds02*dy01 - ds01*dy02; - dsdy = ds01*dx02 - ds02*dx01; dtdx = dt02*dy01 - dt01*dy02; + dsdy = ds01*dx02 - ds02*dx01; dtdy = dt01*dx02 - dt02*dx01; } From 5fc1b60e7f8b19d7d7a2244c0e1e005c7ed91659 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Mon, 29 Jun 2009 17:32:20 -0700 Subject: [PATCH 76/83] don't use a 1/4th of the screen size texture for the dim layer we can't use a texture of 1/4th of the screen for the dim layer, because the mdp internal input resultion is alwyas integers and for very small blits of a couple pixels the scale factor can get way out of range, for instance for a 7 pixels source, the scale factor would be either 7 (7/1) or 3.5 (7/2) instead of 4 (7/1.75). This caused the mdp to fail in some cases and revert to software. we now always use a texture of the actual screen size, so the problem will never happen. This burns 300KB of pmem instead of 21KB. On devices with a larger screen we might want to use a smaller texture and tile it by hand. --- libs/surfaceflinger/LayerDim.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/libs/surfaceflinger/LayerDim.cpp b/libs/surfaceflinger/LayerDim.cpp index 4114a42bd5b16..8e9df9cc9bcc3 100644 --- a/libs/surfaceflinger/LayerDim.cpp +++ b/libs/surfaceflinger/LayerDim.cpp @@ -63,12 +63,6 @@ void LayerDim::initDimmer(SurfaceFlinger* flinger, uint32_t w, uint32_t h) * This burns a full-screen worth of graphic memory. */ - // copybit supports 4x scaling, so we only need to allocate 1/16 of the - // buffer. - // FIXME: we have to add 1px because the mdp fails - w = w/4 + 1; - h = h/4 + 1; - const DisplayHardware& hw(flinger->graphicPlane(0).displayHardware()); uint32_t flags = hw.getFlags(); From 276826bae2eb6d25c4abb1c5f665d2876c65e50c Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Mon, 29 Jun 2009 18:46:37 -0700 Subject: [PATCH 77/83] Region::makeBoundsSelf() efficiently turns a region to its bounds --- include/ui/Region.h | 3 +++ libs/ui/Region.cpp | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/include/ui/Region.h b/include/ui/Region.h index df455a96b16d6..2bcad5b9ea480 100644 --- a/include/ui/Region.h +++ b/include/ui/Region.h @@ -51,6 +51,9 @@ public: inline Rect getBounds() const { return mBounds; } inline Rect bounds() const { return getBounds(); } + // the region becomes its bounds + Region& makeBoundsSelf(); + void clear(); void set(const Rect& r); void set(uint32_t w, uint32_t h); diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp index 2e6b241a310dd..b400a92d0632c 100644 --- a/libs/ui/Region.cpp +++ b/libs/ui/Region.cpp @@ -87,6 +87,12 @@ Region& Region::operator = (const Region& rhs) return *this; } +Region& Region::makeBoundsSelf() +{ + mStorage.clear(); + return *this; +} + void Region::clear() { mBounds.clear(); From ecfa7ccd4fc3066a4cfd4d84d7de286d95581c78 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Mon, 29 Jun 2009 18:49:56 -0700 Subject: [PATCH 78/83] fix a bug that caused artifacts when SWAP_RECTANGLE was enabled --- .../DisplayHardware/DisplayHardware.cpp | 2 +- libs/surfaceflinger/SurfaceFlinger.cpp | 26 ++++++++++++++----- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp index b981319b2ba04..3ce93c05d474b 100644 --- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp +++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp @@ -326,7 +326,7 @@ void DisplayHardware::flip(const Region& dirty) const #endif if (mFlags & UPDATE_ON_DEMAND) { - mNativeWindow->setUpdateRectangle(dirty.bounds()); + mNativeWindow->setUpdateRectangle(dirty.getBounds()); } mPageFlipCount++; diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp index 17cff553f9635..e74e0009232d2 100644 --- a/libs/surfaceflinger/SurfaceFlinger.cpp +++ b/libs/surfaceflinger/SurfaceFlinger.cpp @@ -827,14 +827,28 @@ void SurfaceFlinger::handleRepaint() if ((flags & DisplayHardware::SWAP_RECTANGLE) || (flags & DisplayHardware::BUFFER_PRESERVED)) { - // we can redraw only what's dirty - } else { - if (flags & DisplayHardware::UPDATE_ON_DEMAND) { - // we need to redraw the rectangle that will be updated - // (pushed to the framebuffer). + // we can redraw only what's dirty, but since SWAP_RECTANGLE only + // takes a rectangle, we must make sure to update that whole + // rectangle in that case + if (flags & DisplayHardware::SWAP_RECTANGLE) { + // FIXME: we really should be able to pass a region to + // SWAP_RECTANGLE so that we don't have to redraw all this. mDirtyRegion.set(mInvalidRegion.bounds()); } else { - // we need to redraw everything + // in the BUFFER_PRESERVED case, obviously, we can update only + // what's needed and nothing more. + // NOTE: this is NOT a common case, as preserving the backbuffer + // is costly and usually involves copying the whole update back. + } + } else { + if (flags & DisplayHardware::UPDATE_ON_DEMAND) { + // We need to redraw the rectangle that will be updated + // (pushed to the framebuffer). + // This is needed because UPDATE_ON_DEMAND only takes one + // rectangle instead of a region (see DisplayHardware::flip()) + mDirtyRegion.set(mInvalidRegion.bounds()); + } else { + // we need to redraw everything (the whole screen) mDirtyRegion.set(hw.bounds()); mInvalidRegion = mDirtyRegion; } From 3a6b160a3b52cd96fb383d5ee93c22e5e938e0e2 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Mon, 29 Jun 2009 18:53:53 -0700 Subject: [PATCH 79/83] when there is a choice between UPDATE_ON_DEMAND and SWAP_BUFFER optimizations, choose UPDATE_ON_DEMAND which is often more efficient. --- libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp index 3ce93c05d474b..5c522c5453ef8 100644 --- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp +++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp @@ -211,7 +211,12 @@ void DisplayHardware::init(uint32_t dpy) if (strstr(egl_extensions, "EGL_ANDROID_swap_rectangle")) { mFlags |= SWAP_RECTANGLE; } + // when we have the choice between UPDATE_ON_DEMAND and SWAP_RECTANGLE + // choose UPDATE_ON_DEMAND, which is more efficient + if (mFlags & UPDATE_ON_DEMAND) + mFlags &= ~SWAP_RECTANGLE; #endif + mDpiX = mNativeWindow->xdpi; mDpiX = mNativeWindow->ydpi; From 359140c171f67b9b29a1beae9743b49d0759414b Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Thu, 2 Jul 2009 17:33:40 -0700 Subject: [PATCH 80/83] free gralloc buffers as soon as possible (when a surface is not visible any longer), client who have the buffers still mapped won't crash, btu may see garbage data --- libs/surfaceflinger/Layer.cpp | 3 +- libs/surfaceflinger/LayerBitmap.cpp | 14 +++++--- libs/surfaceflinger/LayerBitmap.h | 3 +- libs/surfaceflinger/SurfaceFlinger.cpp | 44 ++++++++------------------ libs/surfaceflinger/SurfaceFlinger.h | 2 -- 5 files changed, 28 insertions(+), 38 deletions(-) diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp index c40fec16fbc95..991615800da45 100644 --- a/libs/surfaceflinger/Layer.cpp +++ b/libs/surfaceflinger/Layer.cpp @@ -76,7 +76,9 @@ void Layer::destroy() eglDestroyImageKHR(dpy, mTextures[i].image); mTextures[i].image = EGL_NO_IMAGE_KHR; } + mBuffers[i].free(); } + mSurface.clear(); } void Layer::initStates(uint32_t w, uint32_t h, uint32_t flags) @@ -95,7 +97,6 @@ sp Layer::createSurface() const status_t Layer::ditch() { // the layer is not on screen anymore. free as much resources as possible - mSurface.clear(); destroy(); return NO_ERROR; } diff --git a/libs/surfaceflinger/LayerBitmap.cpp b/libs/surfaceflinger/LayerBitmap.cpp index a368ca93aaa6d..e0984fe48c7ce 100644 --- a/libs/surfaceflinger/LayerBitmap.cpp +++ b/libs/surfaceflinger/LayerBitmap.cpp @@ -130,13 +130,10 @@ status_t Buffer::lock(GGLSurface* sur, uint32_t usage) return res; } - - // =========================================================================== // LayerBitmap // =========================================================================== - LayerBitmap::LayerBitmap() : mInfo(0), mWidth(0), mHeight(0) { @@ -184,7 +181,7 @@ sp LayerBitmap::allocate() sp buffer(mBuffer); const uint32_t w = mWidth; const uint32_t h = mHeight; - if (w != buffer->getWidth() || h != buffer->getHeight()) { + if (buffer!=0 && (w != buffer->getWidth() || h != buffer->getHeight())) { surface_info_t* info = mInfo; buffer = new Buffer(w, h, mFormat, mFlags); status_t err = buffer->initCheck(); @@ -200,6 +197,15 @@ sp LayerBitmap::allocate() return buffer; } +status_t LayerBitmap::free() +{ + mBuffer.clear(); + mWidth = 0; + mHeight = 0; + return NO_ERROR; +} + + // --------------------------------------------------------------------------- }; // namespace android diff --git a/libs/surfaceflinger/LayerBitmap.h b/libs/surfaceflinger/LayerBitmap.h index 824e0f2b311b8..f3636c03e03bc 100644 --- a/libs/surfaceflinger/LayerBitmap.h +++ b/libs/surfaceflinger/LayerBitmap.h @@ -110,7 +110,8 @@ public: status_t setSize(uint32_t w, uint32_t h); sp allocate(); - + status_t free(); + sp getBuffer() const { return mBuffer; } sp getBuffer() { return mBuffer; } diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp index e74e0009232d2..c38668113213e 100644 --- a/libs/surfaceflinger/SurfaceFlinger.cpp +++ b/libs/surfaceflinger/SurfaceFlinger.cpp @@ -1095,12 +1095,9 @@ status_t SurfaceFlinger::removeLayer_l(const sp& layerBase) status_t SurfaceFlinger::purgatorizeLayer_l(const sp& layerBase) { - // First add the layer to the purgatory list, which makes sure it won't - // go away, then remove it from the main list (through a transaction). + // remove the layer from the main list (through a transaction). ssize_t err = removeLayer_l(layerBase); - if (err >= 0) { - mLayerPurgatory.add(layerBase); - } + // it's possible that we don't find a layer, because it might // have been destroyed already -- this is not technically an error // from the user because there is a race between BClient::destroySurface(), @@ -1336,7 +1333,7 @@ status_t SurfaceFlinger::removeSurface(SurfaceID index) status_t SurfaceFlinger::destroySurface(const sp& layer) { - /* called by ~ISurface() when all references are gone */ + // called by ~ISurface() when all references are gone class MessageDestroySurface : public MessageBase { SurfaceFlinger* flinger; @@ -1349,33 +1346,21 @@ status_t SurfaceFlinger::destroySurface(const sp& layer) sp l(layer); layer.clear(); // clear it outside of the lock; Mutex::Autolock _l(flinger->mStateLock); - // remove the layer from the current list -- chances are that it's - // not in the list anyway, because it should have been removed - // already upon request of the client (eg: window manager). - // However, a buggy client could have not done that. - // Since we know we don't have any more clients, we don't need - // to use the purgatory. + /* + * remove the layer from the current list -- chances are that it's + * not in the list anyway, because it should have been removed + * already upon request of the client (eg: window manager). + * However, a buggy client could have not done that. + * Since we know we don't have any more clients, we don't need + * to use the purgatory. + */ status_t err = flinger->removeLayer_l(l); - if (err == NAME_NOT_FOUND) { - // The surface wasn't in the current list, which means it was - // removed already, which means it is in the purgatory, - // and need to be removed from there. - // This needs to happen from the main thread since its dtor - // must run from there (b/c of OpenGL ES). Additionally, we - // can't really acquire our internal lock from - // destroySurface() -- see postMessage() below. - ssize_t idx = flinger->mLayerPurgatory.remove(l); - LOGE_IF(idx < 0, - "layer=%p is not in the purgatory list", l.get()); - } + LOGE_IF(err<0 && err != NAME_NOT_FOUND, + "error removing layer=%p (%s)", l.get(), strerror(-err)); return true; } }; - // It's better to not acquire our internal lock here, because it's hard - // to predict that it's not going to be already taken when ~Surface() - // is called. - mEventQueue.postMessage( new MessageDestroySurface(this, layer) ); return NO_ERROR; } @@ -1537,8 +1522,7 @@ status_t SurfaceFlinger::dump(int fd, const Vector& args) mFreezeDisplay?"yes":"no", mFreezeCount, mCurrentState.orientation, hw.canDraw()); result.append(buffer); - snprintf(buffer, SIZE, " purgatory size: %d, client count: %d\n", - mLayerPurgatory.size(), mClientsMap.size()); + snprintf(buffer, SIZE, " client count: %d\n", mClientsMap.size()); result.append(buffer); const BufferAllocator& alloc(BufferAllocator::get()); alloc.dump(result); diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h index 149eef049158e..b7b008d9ff069 100644 --- a/libs/surfaceflinger/SurfaceFlinger.h +++ b/libs/surfaceflinger/SurfaceFlinger.h @@ -307,8 +307,6 @@ private: volatile int32_t mTransactionFlags; volatile int32_t mTransactionCount; Condition mTransactionCV; - SortedVector< sp > mLayerPurgatory; - // protected by mStateLock (but we could use another lock) Tokenizer mTokens; From 0926b6184adb9bd1d4a432c7d4de0be58c602cc2 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Thu, 2 Jul 2009 17:36:04 -0700 Subject: [PATCH 81/83] forgot to remove those files --- libs/surfaceflinger/VRamHeap.cpp | 182 ------------------------------- libs/surfaceflinger/VRamHeap.h | 78 ------------- 2 files changed, 260 deletions(-) delete mode 100644 libs/surfaceflinger/VRamHeap.cpp delete mode 100644 libs/surfaceflinger/VRamHeap.h diff --git a/libs/surfaceflinger/VRamHeap.cpp b/libs/surfaceflinger/VRamHeap.cpp deleted file mode 100644 index 3b1b152b949e2..0000000000000 --- a/libs/surfaceflinger/VRamHeap.cpp +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright (C) 2008 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. - */ - -#define LOG_TAG "SurfaceFlinger" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include - -#include "GPUHardware/GPUHardware.h" -#include "SurfaceFlinger.h" -#include "VRamHeap.h" - -#if HAVE_ANDROID_OS -#include -#endif - - -namespace android { - -// --------------------------------------------------------------------------- - -/* - * Amount of memory we reserve for surface, per client in PMEM - * (PMEM is used for 2D acceleration) - * 8 MB of address space per client should be enough. - */ -static const int PMEM_SIZE = int(16 * 1024 * 1024); - -int SurfaceHeapManager::global_pmem_heap = 0; - -// --------------------------------------------------------------------------- - -SurfaceHeapManager::SurfaceHeapManager(const sp& flinger, - size_t clientHeapSize) - : mFlinger(flinger), mClientHeapSize(clientHeapSize) -{ - SurfaceHeapManager::global_pmem_heap = 1; -} - -SurfaceHeapManager::~SurfaceHeapManager() -{ -} - -void SurfaceHeapManager::onFirstRef() -{ - if (global_pmem_heap) { - const char* device = "/dev/pmem"; - mPMemHeap = new PMemHeap(device, PMEM_SIZE); - if (mPMemHeap->base() == MAP_FAILED) { - mPMemHeap.clear(); - mPMemHeap = new PMemHeap(device, PMEM_SIZE/2); - if (mPMemHeap->base() == MAP_FAILED) { - mPMemHeap.clear(); - global_pmem_heap = 0; - } - } - } -} - -sp SurfaceHeapManager::createHeap( - uint32_t flags, - pid_t client_pid, - const sp& defaultAllocator) -{ - sp dealer; - - if (flags & ISurfaceComposer::eGPU) { - // don't grant GPU memory if GPU is disabled - char value[PROPERTY_VALUE_MAX]; - property_get("debug.egl.hw", value, "1"); - if (atoi(value) == 0) { - flags &= ~ISurfaceComposer::eGPU; - } - } - - if ((flags & ISurfaceComposer::eGPU) && (mFlinger->getGPU() != 0)) { - // FIXME: this is msm7201A specific, where gpu surfaces may not be secure - if (!(flags & ISurfaceComposer::eSecure)) { - // if GPU doesn't work, we try eHardware - flags |= ISurfaceComposer::eHardware; - // asked for GPU memory, try that first - dealer = mFlinger->getGPU()->request(client_pid); - } - } - - if (dealer == NULL) { - if (defaultAllocator != NULL) - // if a default allocator is given, use that - dealer = defaultAllocator; - } - - if (dealer == NULL) { - // always try h/w accelerated memory first - if (global_pmem_heap) { - const sp& heap(mPMemHeap); - if (dealer == NULL && heap != NULL) { - dealer = new MemoryDealer( - heap->createClientHeap(), - heap->getAllocator()); - } - } - } - - if (dealer == NULL) { - // return the ashmem allocator (software rendering) - dealer = new MemoryDealer(mClientHeapSize, 0, "SFNativeHeap"); - } - return dealer; -} - -sp SurfaceHeapManager::getAllocator(int type) const -{ - Mutex::Autolock _l(mLock); - sp allocator; - - // this is only used for debugging - switch (type) { - case NATIVE_MEMORY_TYPE_PMEM: - if (mPMemHeap != 0) { - allocator = mPMemHeap->getAllocator(); - } - break; - } - return allocator; -} - -// --------------------------------------------------------------------------- - -PMemHeap::PMemHeap(const char* const device, size_t size, size_t reserved) - : MemoryHeapBase(device, size) -{ - //LOGD("%s, %p, mFD=%d", __PRETTY_FUNCTION__, this, heapID()); - if (base() != MAP_FAILED) { - //LOGD("%s, %u bytes", device, virtualSize()); - if (reserved == 0) - reserved = virtualSize(); - mAllocator = new SimpleBestFitAllocator(reserved); - } -} - -PMemHeap::~PMemHeap() { - //LOGD("%s, %p, mFD=%d", __PRETTY_FUNCTION__, this, heapID()); -} - -sp PMemHeap::createClientHeap() { - sp parentHeap(this); - return new MemoryHeapPmem(parentHeap); -} - -// --------------------------------------------------------------------------- -}; // namespace android diff --git a/libs/surfaceflinger/VRamHeap.h b/libs/surfaceflinger/VRamHeap.h deleted file mode 100644 index 780a1bc56dce8..0000000000000 --- a/libs/surfaceflinger/VRamHeap.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2008 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. - */ - -#ifndef ANDROID_VRAM_HEAP_H -#define ANDROID_VRAM_HEAP_H - -#include -#include -#include - -namespace android { - -// --------------------------------------------------------------------------- - -class PMemHeap; -class MemoryHeapPmem; -class SurfaceFlinger; - -// --------------------------------------------------------------------------- - -class SurfaceHeapManager : public RefBase -{ -public: - SurfaceHeapManager(const sp& flinger, size_t clientHeapSize); - virtual ~SurfaceHeapManager(); - virtual void onFirstRef(); - /* use ISurfaceComposer flags eGPU|eHArdware|eSecure */ - sp createHeap(uint32_t flags=0, pid_t client_pid = 0, - const sp& defaultAllocator = 0); - - // used for debugging only... - sp getAllocator(int type) const; - -private: - sp getHeap(int type) const; - - sp mFlinger; - mutable Mutex mLock; - size_t mClientHeapSize; - sp mPMemHeap; - static int global_pmem_heap; -}; - -// --------------------------------------------------------------------------- - -class PMemHeap : public MemoryHeapBase -{ -public: - PMemHeap(const char* const vram, - size_t size=0, size_t reserved=0); - virtual ~PMemHeap(); - - virtual const sp& getAllocator() const { - return mAllocator; - } - virtual sp createClientHeap(); - -private: - sp mAllocator; -}; - -// --------------------------------------------------------------------------- -}; // namespace android - -#endif // ANDROID_VRAM_HEAP_H From d763b5d9197e01662cafa376e1227e53e0463a3c Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Thu, 2 Jul 2009 18:11:53 -0700 Subject: [PATCH 82/83] get rid of references to MemoryDealer in SurfaceFlinger --- include/ui/ISurfaceComposer.h | 2 +- include/ui/ISurfaceFlingerClient.h | 2 +- include/ui/SurfaceComposerClient.h | 2 +- libs/surfaceflinger/Layer.h | 1 - libs/surfaceflinger/LayerBitmap.cpp | 1 - libs/surfaceflinger/LayerBitmap.h | 1 - libs/surfaceflinger/LayerBuffer.h | 1 - libs/surfaceflinger/SurfaceFlinger.cpp | 54 +++++++++++++------------- libs/surfaceflinger/SurfaceFlinger.h | 28 +++++++------ libs/ui/ISurfaceComposer.cpp | 4 +- libs/ui/ISurfaceFlingerClient.cpp | 7 ++-- libs/ui/SurfaceComposerClient.cpp | 10 ++--- 12 files changed, 55 insertions(+), 58 deletions(-) diff --git a/include/ui/ISurfaceComposer.h b/include/ui/ISurfaceComposer.h index ce2b94c3e1601..1788265b58407 100644 --- a/include/ui/ISurfaceComposer.h +++ b/include/ui/ISurfaceComposer.h @@ -92,7 +92,7 @@ public: virtual sp createConnection() = 0; /* retrieve the control block */ - virtual sp getCblk() const = 0; + virtual sp getCblk() const = 0; /* open/close transactions. recquires ACCESS_SURFACE_FLINGER permission */ virtual void openGlobalTransaction() = 0; diff --git a/include/ui/ISurfaceFlingerClient.h b/include/ui/ISurfaceFlingerClient.h index e93a4fafe2811..932a70a854a1c 100644 --- a/include/ui/ISurfaceFlingerClient.h +++ b/include/ui/ISurfaceFlingerClient.h @@ -56,7 +56,7 @@ public: status_t writeToParcel(Parcel* parcel) const; }; - virtual void getControlBlocks(sp* ctl) const = 0; + virtual sp getControlBlock() const = 0; virtual sp createSurface( surface_data_t* data, int pid, diff --git a/include/ui/SurfaceComposerClient.h b/include/ui/SurfaceComposerClient.h index 2a35256d28892..286f8850fd93c 100644 --- a/include/ui/SurfaceComposerClient.h +++ b/include/ui/SurfaceComposerClient.h @@ -149,7 +149,7 @@ private: // after assignment status_t mStatus; per_client_cblk_t* mControl; - sp mControlMemory; + sp mControlMemory; sp mClient; SurfaceFlingerSynchro* mSignalServer; }; diff --git a/libs/surfaceflinger/Layer.h b/libs/surfaceflinger/Layer.h index 54d994facc7d5..4c13d6ea2887c 100644 --- a/libs/surfaceflinger/Layer.h +++ b/libs/surfaceflinger/Layer.h @@ -42,7 +42,6 @@ namespace android { class Client; class LayerBitmap; -class MemoryDealer; class FreezeLock; // --------------------------------------------------------------------------- diff --git a/libs/surfaceflinger/LayerBitmap.cpp b/libs/surfaceflinger/LayerBitmap.cpp index e0984fe48c7ce..9fffbbfbb9fff 100644 --- a/libs/surfaceflinger/LayerBitmap.cpp +++ b/libs/surfaceflinger/LayerBitmap.cpp @@ -20,7 +20,6 @@ #include #include -#include #include #include diff --git a/libs/surfaceflinger/LayerBitmap.h b/libs/surfaceflinger/LayerBitmap.h index f3636c03e03bc..22525cebdfc51 100644 --- a/libs/surfaceflinger/LayerBitmap.h +++ b/libs/surfaceflinger/LayerBitmap.h @@ -40,7 +40,6 @@ namespace android { // --------------------------------------------------------------------------- class IMemory; -class MemoryDealer; class LayerBitmap; // =========================================================================== diff --git a/libs/surfaceflinger/LayerBuffer.h b/libs/surfaceflinger/LayerBuffer.h index cd541a5130241..fe879ebd976e2 100644 --- a/libs/surfaceflinger/LayerBuffer.h +++ b/libs/surfaceflinger/LayerBuffer.h @@ -32,7 +32,6 @@ namespace android { // --------------------------------------------------------------------------- -class MemoryDealer; class Region; class OverlayRef; diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp index c38668113213e..5ac1cfd932c99 100644 --- a/libs/surfaceflinger/SurfaceFlinger.cpp +++ b/libs/surfaceflinger/SurfaceFlinger.cpp @@ -31,8 +31,8 @@ #include #include -#include -#include +#include + #include #include #include @@ -217,9 +217,9 @@ overlay_control_device_t* SurfaceFlinger::getOverlayEngine() const return graphicPlane(0).displayHardware().getOverlayEngine(); } -sp SurfaceFlinger::getCblk() const +sp SurfaceFlinger::getCblk() const { - return mServerCblkMemory; + return mServerHeap; } sp SurfaceFlinger::createConnection() @@ -238,7 +238,7 @@ sp SurfaceFlinger::createConnection() return 0; } sp bclient = - new BClient(this, token, client->controlBlockMemory()); + new BClient(this, token, client->getControlBlockMemory()); return bclient; } @@ -301,7 +301,6 @@ void SurfaceFlinger::onFirstRef() mReadyToRunBarrier.wait(); } - static inline uint16_t pack565(int r, int g, int b) { return (r<<11)|(g<<5)|b; } @@ -311,17 +310,6 @@ status_t SurfaceFlinger::readyToRun() LOGI( "SurfaceFlinger's main thread ready to run. " "Initializing graphics H/W..."); - // create the shared control-block - mServerHeap = new MemoryDealer(4096, MemoryDealer::READ_ONLY); - LOGE_IF(mServerHeap==0, "can't create shared memory dealer"); - - mServerCblkMemory = mServerHeap->allocate(4096); - LOGE_IF(mServerCblkMemory==0, "can't create shared control block"); - - mServerCblk = static_cast(mServerCblkMemory->pointer()); - LOGE_IF(mServerCblk==0, "can't get to shared control block's address"); - new(mServerCblk) surface_flinger_cblk_t; - // we only support one display currently int dpy = 0; @@ -332,6 +320,16 @@ status_t SurfaceFlinger::readyToRun() plane.setDisplayHardware(hw); } + // create the shared control-block + mServerHeap = new MemoryHeapBase(4096, + MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap"); + LOGE_IF(mServerHeap==0, "can't create shared memory dealer"); + + mServerCblk = static_cast(mServerHeap->getBase()); + LOGE_IF(mServerCblk==0, "can't get to shared control block's address"); + + new(mServerCblk) surface_flinger_cblk_t; + // initialize primary screen // (other display should be initialized in the same manner, but // asynchronously, as they could come and go. None of this is supported @@ -1615,14 +1613,14 @@ Client::Client(ClientID clientID, const sp& flinger) : ctrlblk(0), cid(clientID), mPid(0), mBitmap(0), mFlinger(flinger) { const int pgsize = getpagesize(); - const int cblksize=((sizeof(per_client_cblk_t)+(pgsize-1))&~(pgsize-1)); - mCblkHeap = new MemoryDealer(cblksize); - mCblkMemory = mCblkHeap->allocate(cblksize); - if (mCblkMemory != 0) { - ctrlblk = static_cast(mCblkMemory->pointer()); - if (ctrlblk) { // construct the shared structure in-place. - new(ctrlblk) per_client_cblk_t; - } + const int cblksize = ((sizeof(per_client_cblk_t)+(pgsize-1))&~(pgsize-1)); + + mCblkHeap = new MemoryHeapBase(cblksize, 0, + "SurfaceFlinger Client control-block"); + + ctrlblk = static_cast(mCblkHeap->getBase()); + if (ctrlblk) { // construct the shared structure in-place. + new(ctrlblk) per_client_cblk_t; } } @@ -1685,7 +1683,7 @@ void Client::dump(const char* what) #pragma mark - #endif -BClient::BClient(SurfaceFlinger *flinger, ClientID cid, const sp& cblk) +BClient::BClient(SurfaceFlinger *flinger, ClientID cid, const sp& cblk) : mId(cid), mFlinger(flinger), mCblk(cblk) { } @@ -1695,8 +1693,8 @@ BClient::~BClient() { mFlinger->destroyConnection(mId); } -void BClient::getControlBlocks(sp* ctrl) const { - *ctrl = mCblk; +sp BClient::getControlBlock() const { + return mCblk; } sp BClient::createSurface( diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h index b7b008d9ff069..d0095a2bdfeb0 100644 --- a/libs/surfaceflinger/SurfaceFlinger.h +++ b/libs/surfaceflinger/SurfaceFlinger.h @@ -27,7 +27,7 @@ #include #include -#include +#include #include #include @@ -76,25 +76,30 @@ public: inline bool isValid(int32_t i) const; sp getLayerUser(int32_t i) const; - const Vector< wp >& getLayers() const { return mLayers; } - const sp& controlBlockMemory() const { return mCblkMemory; } void dump(const char* what); + const Vector< wp >& getLayers() const { + return mLayers; + } + + const sp& getControlBlockMemory() const { + return mCblkHeap; + } + // pointer to this client's control block per_client_cblk_t* ctrlblk; ClientID cid; private: - int getClientPid() const { return mPid; } + int getClientPid() const { return mPid; } int mPid; uint32_t mBitmap; SortedVector mInUse; Vector< wp > mLayers; - sp mCblkHeap; + sp mCblkHeap; sp mFlinger; - sp mCblkMemory; }; // --------------------------------------------------------------------------- @@ -154,7 +159,7 @@ public: // ISurfaceComposer interface virtual sp createConnection(); - virtual sp getCblk() const; + virtual sp getCblk() const; virtual void bootFinished(); virtual void openGlobalTransaction(); virtual void closeGlobalTransaction(); @@ -317,8 +322,7 @@ private: Vector< sp > mDisconnectedClients; // constant members (no synchronization needed for access) - sp mServerHeap; - sp mServerCblkMemory; + sp mServerHeap; surface_flinger_cblk_t* mServerCblk; GLuint mWormholeTexName; nsecs_t mBootTime; @@ -377,11 +381,11 @@ class BClient : public BnSurfaceFlingerClient { public: BClient(SurfaceFlinger *flinger, ClientID cid, - const sp& cblk); + const sp& cblk); ~BClient(); // ISurfaceFlingerClient interface - virtual void getControlBlocks(sp* ctrl) const; + virtual sp getControlBlock() const; virtual sp createSurface( surface_data_t* params, int pid, @@ -394,7 +398,7 @@ public: private: ClientID mId; SurfaceFlinger* mFlinger; - sp mCblk; + sp mCblk; }; // --------------------------------------------------------------------------- diff --git a/libs/ui/ISurfaceComposer.cpp b/libs/ui/ISurfaceComposer.cpp index 2aa1405b0c759..fd2a590caff65 100644 --- a/libs/ui/ISurfaceComposer.cpp +++ b/libs/ui/ISurfaceComposer.cpp @@ -54,12 +54,12 @@ public: return interface_cast(reply.readStrongBinder()); } - virtual sp getCblk() const + virtual sp getCblk() const { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); remote()->transact(BnSurfaceComposer::GET_CBLK, data, &reply); - return interface_cast(reply.readStrongBinder()); + return interface_cast(reply.readStrongBinder()); } virtual void openGlobalTransaction() diff --git a/libs/ui/ISurfaceFlingerClient.cpp b/libs/ui/ISurfaceFlingerClient.cpp index 46c12afe898d5..51e8422606f9e 100644 --- a/libs/ui/ISurfaceFlingerClient.cpp +++ b/libs/ui/ISurfaceFlingerClient.cpp @@ -64,12 +64,12 @@ public: { } - virtual void getControlBlocks(sp* ctl) const + virtual sp getControlBlock() const { Parcel data, reply; data.writeInterfaceToken(ISurfaceFlingerClient::getInterfaceDescriptor()); remote()->transact(GET_CBLK, data, &reply); - *ctl = interface_cast(reply.readStrongBinder()); + return interface_cast(reply.readStrongBinder()); } virtual sp createSurface( surface_data_t* params, @@ -126,8 +126,7 @@ status_t BnSurfaceFlingerClient::onTransact( switch(code) { case GET_CBLK: { CHECK_INTERFACE(ISurfaceFlingerClient, data, reply); - sp ctl; - getControlBlocks(&ctl); + sp ctl(getControlBlock()); reply->writeStrongBinder(ctl->asBinder()); return NO_ERROR; } break; diff --git a/libs/ui/SurfaceComposerClient.cpp b/libs/ui/SurfaceComposerClient.cpp index 025bf6e385b0f..d2cef785778ac 100644 --- a/libs/ui/SurfaceComposerClient.cpp +++ b/libs/ui/SurfaceComposerClient.cpp @@ -59,7 +59,7 @@ static Mutex gLock; static sp gSurfaceManager; static DefaultKeyedVector< sp, sp > gActiveConnections; static SortedVector > gOpenTransactions; -static sp gServerCblkMemory; +static sp gServerCblkMemory; static volatile surface_flinger_cblk_t* gServerCblk; const sp& _get_surface_manager() @@ -94,7 +94,7 @@ static volatile surface_flinger_cblk_t const * get_cblk() if (gServerCblk == 0) { gServerCblkMemory = sm->getCblk(); LOGE_IF(gServerCblkMemory==0, "Can't get server control block"); - gServerCblk = (surface_flinger_cblk_t *)gServerCblkMemory->pointer(); + gServerCblk = (surface_flinger_cblk_t *)gServerCblkMemory->getBase(); LOGE_IF(gServerCblk==0, "Can't get server control block address"); } } @@ -313,9 +313,9 @@ void SurfaceComposerClient::_init( return; } - mClient->getControlBlocks(&mControlMemory); + mControlMemory = mClient->getControlBlock(); mSignalServer = new SurfaceFlingerSynchro(sm); - mControl = static_cast(mControlMemory->pointer()); + mControl = static_cast(mControlMemory->getBase()); } SurfaceComposerClient::~SurfaceComposerClient() @@ -364,7 +364,7 @@ void SurfaceComposerClient::dispose() { // this can be called more than once. - sp controlMemory; + sp controlMemory; sp client; { From f780d32fc2081fbf10a5bec19a654465361fc538 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Thu, 2 Jul 2009 19:04:39 -0700 Subject: [PATCH 83/83] don't need to link against libsgl --- libs/surfaceflinger/Android.mk | 11 +++++------ .../{ => purgatory}/GPUHardware/GPUHardware.cpp | 0 .../{ => purgatory}/GPUHardware/GPUHardware.h | 0 3 files changed, 5 insertions(+), 6 deletions(-) rename libs/surfaceflinger/{ => purgatory}/GPUHardware/GPUHardware.cpp (100%) rename libs/surfaceflinger/{ => purgatory}/GPUHardware/GPUHardware.h (100%) diff --git a/libs/surfaceflinger/Android.mk b/libs/surfaceflinger/Android.mk index f718e7ada692f..dca368c874b2f 100644 --- a/libs/surfaceflinger/Android.mk +++ b/libs/surfaceflinger/Android.mk @@ -33,16 +33,15 @@ ifeq ($(TARGET_SIMULATOR),true) endif LOCAL_SHARED_LIBRARIES := \ + libcutils \ + libpixelflinger \ libhardware \ libutils \ - libbinder \ - libcutils \ - libui \ libcorecg \ - libsgl \ - libpixelflinger \ libEGL \ - libGLESv1_CM + libGLESv1_CM \ + libbinder \ + libui LOCAL_C_INCLUDES := \ $(call include-path-for, corecg graphics) diff --git a/libs/surfaceflinger/GPUHardware/GPUHardware.cpp b/libs/surfaceflinger/purgatory/GPUHardware/GPUHardware.cpp similarity index 100% rename from libs/surfaceflinger/GPUHardware/GPUHardware.cpp rename to libs/surfaceflinger/purgatory/GPUHardware/GPUHardware.cpp diff --git a/libs/surfaceflinger/GPUHardware/GPUHardware.h b/libs/surfaceflinger/purgatory/GPUHardware/GPUHardware.h similarity index 100% rename from libs/surfaceflinger/GPUHardware/GPUHardware.h rename to libs/surfaceflinger/purgatory/GPUHardware/GPUHardware.h