diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/private/opengles/gl_context.h | 43 | ||||
-rw-r--r-- | include/private/ui/SharedState.h | 17 | ||||
-rw-r--r-- | include/ui/BufferMapper.h | 57 | ||||
-rw-r--r-- | include/ui/EGLNativeWindowSurface.h | 100 | ||||
-rw-r--r-- | include/ui/ISurface.h | 8 | ||||
-rw-r--r-- | include/ui/ISurfaceComposer.h | 37 | ||||
-rw-r--r-- | include/ui/ISurfaceFlingerClient.h | 1 | ||||
-rw-r--r-- | include/ui/PixelFormat.h | 36 | ||||
-rw-r--r-- | include/ui/Surface.h | 84 | ||||
-rw-r--r-- | include/ui/SurfaceComposerClient.h | 22 | ||||
-rw-r--r-- | include/utils/Parcel.h | 18 | ||||
-rw-r--r-- | include/utils/Singleton.h | 59 |
12 files changed, 349 insertions, 133 deletions
diff --git a/include/private/opengles/gl_context.h b/include/private/opengles/gl_context.h index 0c7ad46..641961f 100644 --- a/include/private/opengles/gl_context.h +++ b/include/private/opengles/gl_context.h @@ -26,6 +26,7 @@ #endif #include <private/pixelflinger/ggl_context.h> +#include <hardware/copybit.h> #include <GLES/gl.h> #include <GLES/glext.h> @@ -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 546d0ad..646cc10 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 0000000..8a33b2e --- /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 <stdint.h> +#include <sys/types.h> +#include <utils/threads.h> +#include <utils/Singleton.h> + +#include <hardware/gralloc.h> + + +struct gralloc_module_t; + +namespace android { + +// --------------------------------------------------------------------------- + +class Rect; + +class BufferMapper : public Singleton<BufferMapper> +{ +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>; + 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 3494234..4b25655 100644 --- a/include/ui/EGLNativeWindowSurface.h +++ b/include/ui/EGLNativeWindowSurface.h @@ -19,8 +19,17 @@ #include <stdint.h> #include <sys/types.h> -#include <ui/EGLNativeSurface.h> + #include <EGL/egl.h> +#include <EGL/android_natives.h> + +#include <utils/threads.h> +#include <ui/Rect.h> + +#include <pixelflinger/pixelflinger.h> + + +extern "C" EGLNativeWindowType android_createDisplaySurface(void); // --------------------------------------------------------------------------- namespace android { @@ -28,27 +37,84 @@ namespace android { class Surface; -class EGLNativeWindowSurface : public EGLNativeSurface<EGLNativeWindowSurface> + +class NativeBuffer + : public EGLNativeBase< + android_native_buffer_t, + NativeBuffer, + LightRefBase<NativeBuffer> > { public: - EGLNativeWindowSurface(const sp<Surface>& 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>; + ~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<FramebufferNativeWindow> > +{ +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); - - uint32_t swapBuffers(); - void connect(); - void disconnect(); - - sp<Surface> mSurface; - bool mConnected; + friend class LightRefBase<FramebufferNativeWindow>; + ~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<FramebufferNativeWindow*>(window); + return self; + } + + static inline FramebufferNativeWindow* getSelf( + android_native_base_t* window) { + return getSelf(reinterpret_cast<android_native_window_t*>(window)); + } + + + framebuffer_device_t* fbDev; + alloc_device_t* grDev; + + sp<NativeBuffer> buffers[2]; + sp<NativeBuffer> 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 87b320f..1a78872 100644 --- a/include/ui/ISurface.h +++ b/include/ui/ISurface.h @@ -20,12 +20,15 @@ #include <stdint.h> #include <sys/types.h> +#include <EGL/android_natives.h> + #include <utils/Errors.h> #include <utils/IInterface.h> #include <utils/RefBase.h> #include <ui/PixelFormat.h> #include <hardware/hardware.h> +#include <hardware/gralloc.h> 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<SurfaceBuffer> 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<OverlayRef> createOverlay( diff --git a/include/ui/ISurfaceComposer.h b/include/ui/ISurfaceComposer.h index 5c64b22..fd5a473 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<IMemory> region; - size_t reserved; - }; - sp<IMemory> regs; - size_t count; - gpu_region_t regions[2]; - }; - virtual status_t requestGPU( - const sp<IGPUCallback>& 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<ISurfaceComposer> @@ -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<IGPUCallback> -{ -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 5b9361d..8515e2e 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<IMemoryHeap> 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 14af823..6d87321b 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 33953a9..d92da49 100644 --- a/include/ui/Surface.h +++ b/include/ui/Surface.h @@ -28,24 +28,65 @@ #include <ui/Region.h> #include <ui/ISurfaceFlingerClient.h> +#include <EGL/android_natives.h> + 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<SurfaceBuffer> > { +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>; + + 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<android_native_window_t, Surface, RefBase> +{ 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<Surface> dup() const; static sp<Surface> readFromParcel(Parcel* parcel); @@ -95,6 +133,8 @@ private: friend class Test; const sp<ISurface>& 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<SurfaceComposerClient> mClient; sp<ISurface> mSurface; - sp<IMemoryHeap> mHeap[2]; + sp<SurfaceBuffer> 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 76a3b55..86de6ea 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<ISurfaceComposer>& sm, const sp<ISurfaceFlingerClient>& 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>& surface); layer_state_t* _lockLayerState(const sp<Surface>& surface); inline void _unlockLayerState(); - status_t validateSurface( - per_client_cblk_t const* cblk, Surface const * surface); - - void pinHeap(const sp<IMemoryHeap>& heap); - mutable Mutex mLock; layer_state_t* mPrebuiltLayerState; SortedVector<layer_state_t> mStates; @@ -167,9 +150,6 @@ private: per_client_cblk_t* mControl; sp<IMemory> mControlMemory; sp<ISurfaceFlingerClient> mClient; - sp<IMemoryHeap> mSurfaceHeap; - uint8_t* mSurfaceHeapBase; - void* mGL; SurfaceFlingerSynchro* mSignalServer; }; diff --git a/include/utils/Parcel.h b/include/utils/Parcel.h index 9087c44..af1490a 100644 --- a/include/utils/Parcel.h +++ b/include/utils/Parcel.h @@ -80,8 +80,11 @@ public: status_t writeStrongBinder(const sp<IBinder>& val); status_t writeWeakBinder(const wp<IBinder>& 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<IBinder> 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 0000000..776f93b --- /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 <stdint.h> +#include <sys/types.h> +#include <utils/threads.h> + +namespace android { +// --------------------------------------------------------------------------- + +template <typename TYPE> +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<class TYPE> Mutex Singleton<TYPE>::sLock; +template<class TYPE> TYPE* Singleton<TYPE>::sInstance(0); + +// --------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_UTILS_SINGLETON_H + |