diff options
Diffstat (limited to 'emulator')
21 files changed, 467 insertions, 358 deletions
diff --git a/emulator/opengl/Android.mk b/emulator/opengl/Android.mk index d0434fc..da29214 100644 --- a/emulator/opengl/Android.mk +++ b/emulator/opengl/Android.mk @@ -16,7 +16,9 @@ EMUGL_PATH := $(call my-dir) # This is always set to a module's LOCAL_C_INCLUDES # See the definition of emugl-begin-module in common.mk # -EMUGL_COMMON_INCLUDES := $(EMUGL_PATH)/host/include/libOpenglRender +EMUGL_COMMON_INCLUDES := \ + $(EMUGL_PATH)/host/include/libOpenglRender \ + $(EMUGL_PATH)/shared ifeq ($(BUILD_STANDALONE_EMULATOR),true) EMUGL_COMMON_INCLUDES := $(EMUGL_PATH)/host/libs/Translator/include @@ -57,6 +59,7 @@ include $(EMUGL_PATH)/common.mk # source files (see all emugl-gen-decoder/encoder in common.mk) # include $(EMUGL_PATH)/host/tools/emugen/Android.mk +include $(EMUGL_PATH)/shared/emugl/common/Android.mk include $(EMUGL_PATH)/shared/OpenglOsUtils/Android.mk include $(EMUGL_PATH)/shared/OpenglCodecCommon/Android.mk diff --git a/emulator/opengl/host/libs/Translator/EGL/EglContext.h b/emulator/opengl/host/libs/Translator/EGL/EglContext.h index e4917c6..d8eb05e 100644 --- a/emulator/opengl/host/libs/Translator/EGL/EglContext.h +++ b/emulator/opengl/host/libs/Translator/EGL/EglContext.h @@ -19,10 +19,10 @@ #include <map> #include <EGL/egl.h> #include <GLcommon/GLutils.h> -#include <GLcommon/SmartPtr.h> #include <GLcommon/TranslatorIfaces.h> #include <GLcommon/objectNameManager.h> +#include "emugl/common/smart_ptr.h" #include "EglConfig.h" #include "EglSurface.h" @@ -30,7 +30,7 @@ class EglContext; -typedef SmartPtr<EglContext> ContextPtr; +typedef emugl::SmartPtr<EglContext> ContextPtr; class EglDisplay; diff --git a/emulator/opengl/host/libs/Translator/EGL/EglDisplay.h b/emulator/opengl/host/libs/Translator/EGL/EglDisplay.h index 587e92a..889a84f 100644 --- a/emulator/opengl/host/libs/Translator/EGL/EglDisplay.h +++ b/emulator/opengl/host/libs/Translator/EGL/EglDisplay.h @@ -21,7 +21,7 @@ #include <EGL/egl.h> #include <EGL/eglext.h> #include <utils/threads.h> -#include <GLcommon/SmartPtr.h> +#include "emugl/common/smart_ptr.h" #include "EglConfig.h" #include "EglContext.h" @@ -30,6 +30,7 @@ + typedef std::list<EglConfig*> ConfigsList; typedef std::map< unsigned int, ContextPtr> ContextsHndlMap; typedef std::map< unsigned int, SurfacePtr> SurfacesHndlMap; diff --git a/emulator/opengl/host/libs/Translator/EGL/EglSurface.h b/emulator/opengl/host/libs/Translator/EGL/EglSurface.h index d65f480..ba28ae8 100644 --- a/emulator/opengl/host/libs/Translator/EGL/EglSurface.h +++ b/emulator/opengl/host/libs/Translator/EGL/EglSurface.h @@ -16,14 +16,15 @@ #ifndef EGL_SURFACE_H #define EGL_SURFACE_H +#include <map> + #include <EGL/egl.h> #include <EGL/eglinternalplatform.h> -#include <map> -#include <GLcommon/SmartPtr.h> +#include "emugl/common/smart_ptr.h" #include "EglConfig.h" class EglSurface; -typedef SmartPtr<EglSurface> SurfacePtr; +typedef emugl::SmartPtr<EglSurface> SurfacePtr; class EglDisplay; diff --git a/emulator/opengl/host/libs/Translator/GLcommon/Android.mk b/emulator/opengl/host/libs/Translator/GLcommon/Android.mk index 1236566..2c16878 100644 --- a/emulator/opengl/host/libs/Translator/GLcommon/Android.mk +++ b/emulator/opengl/host/libs/Translator/GLcommon/Android.mk @@ -41,7 +41,7 @@ LOCAL_SRC_FILES := $(host_common_SRC_FILES) $(call emugl-export,LDLIBS,$(host_common_LDLIBS)) $(call emugl-export,LDFLAGS,$(host_common_LDFLAGS)) $(call emugl-export,C_INCLUDES,$(LOCAL_PATH)/../include $(EMUGL_PATH)/shared) -$(call emugl-export,STATIC_LIBRARIES, libcutils libutils liblog) +$(call emugl-export,STATIC_LIBRARIES, libemugl_common libutils libcutils liblog) $(call emugl-end-module) @@ -56,6 +56,6 @@ LOCAL_SRC_FILES := $(host_common_SRC_FILES) $(call emugl-export,LDLIBS,$(host_common_LDLIBS)) $(call emugl-export,LDFLAGS,$(host_common_LDFLAGS)) $(call emugl-export,C_INCLUDES,$(LOCAL_PATH)/../include $(EMUGL_PATH)/shared) -$(call emugl-export,STATIC_LIBRARIES, lib64cutils lib64utils lib64log) +$(call emugl-export,STATIC_LIBRARIES, lib64emugl_common lib64utils lib64cutils lib64log) $(call emugl-end-module) diff --git a/emulator/opengl/host/libs/Translator/include/GLcommon/GLESbuffer.h b/emulator/opengl/host/libs/Translator/include/GLcommon/GLESbuffer.h index 3353ec1..38429d1 100644 --- a/emulator/opengl/host/libs/Translator/include/GLcommon/GLESbuffer.h +++ b/emulator/opengl/host/libs/Translator/include/GLcommon/GLESbuffer.h @@ -43,5 +43,5 @@ private: bool m_wasBound; }; -typedef SmartPtr<GLESbuffer> GLESbufferPtr; +typedef emugl::SmartPtr<GLESbuffer> GLESbufferPtr; #endif diff --git a/emulator/opengl/host/libs/Translator/include/GLcommon/SmartPtr.h b/emulator/opengl/host/libs/Translator/include/GLcommon/SmartPtr.h deleted file mode 100644 index 8ac93fb..0000000 --- a/emulator/opengl/host/libs/Translator/include/GLcommon/SmartPtr.h +++ /dev/null @@ -1,163 +0,0 @@ -/* -* Copyright (C) 2011 The Android Open Source Project -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -#ifndef __SMART_PTR_H -#define __SMART_PTR_H - -#include <cutils/threads.h> -#include <cutils/atomic.h> - -template <class T, bool threadSafe = false> -class SmartPtr -{ -public: - explicit SmartPtr(T* ptr = (T*)NULL) { - if (threadSafe) { - m_lock = new mutex_t; - mutex_init(m_lock); - } - else m_lock = NULL; - - m_ptr = ptr; - if (ptr) - m_pRefCount = new int32_t(1); - else - m_pRefCount = NULL; - } - - SmartPtr<T,threadSafe>(const SmartPtr<T,false>& rhs) { - if (threadSafe) { - m_lock = new mutex_t; - mutex_init(m_lock); - } - else m_lock = NULL; - - m_pRefCount = rhs.m_pRefCount; - m_ptr = rhs.m_ptr; - use(); - } - - SmartPtr<T,threadSafe>(SmartPtr<T,true>& rhs) { - if (threadSafe) { - m_lock = new mutex_t; - mutex_init(m_lock); - } - else m_lock = NULL; - - if (rhs.m_lock) mutex_lock(rhs.m_lock); - m_pRefCount = rhs.m_pRefCount; - m_ptr = rhs.m_ptr; - use(); - if (rhs.m_lock) mutex_unlock(rhs.m_lock); - } - - ~SmartPtr() { - if (m_lock) mutex_lock(m_lock); - release(); - if (m_lock) - { - mutex_unlock(m_lock); - mutex_destroy(m_lock); - delete m_lock; - } - } - - T* Ptr() const { - return m_ptr; - } - - const T* constPtr() const - { - return m_ptr; - } - - T* operator->() const { - return m_ptr; - } - - T& operator*() const { - return *m_ptr; - } - - // This gives STL lists something to compare. - bool operator <(const SmartPtr<T>& t1) const { - return m_ptr < t1.m_ptr; - } - - SmartPtr<T,threadSafe>& operator=(const SmartPtr<T,false>& rhs) - { - if (m_ptr == rhs.m_ptr) - return *this; - - if (m_lock) mutex_lock(m_lock); - release(); - m_pRefCount = rhs.m_pRefCount; - m_ptr = rhs.m_ptr; - use(); - if (m_lock) mutex_unlock(m_lock); - - return *this; - } - - SmartPtr<T,threadSafe>& operator=(SmartPtr<T,true>& rhs) - { - if (m_ptr == rhs.m_ptr) - return *this; - - if (m_lock) mutex_lock(m_lock); - release(); - if (rhs.m_lock) mutex_lock(rhs.m_lock); - m_pRefCount = rhs.m_pRefCount; - m_ptr = rhs.m_ptr; - use(); - if (rhs.m_lock) mutex_unlock(rhs.m_lock); - if (m_lock) mutex_unlock(m_lock); - - return *this; - } - -private: - int32_t *m_pRefCount; - mutex_t *m_lock; - T* m_ptr; - - // Increment the reference count on this pointer by 1. - int use() { - if (!m_pRefCount) return 0; - return android_atomic_inc(m_pRefCount) + 1; - } - - // Decrement the reference count on the pointer by 1. - // If the reference count goes to (or below) 0, the pointer is deleted. - int release() { - if (!m_pRefCount) return 0; - - int iVal = android_atomic_dec(m_pRefCount); - if (iVal > 1) - return iVal - 1; - - delete m_pRefCount; - m_pRefCount = NULL; - - if (m_ptr) { - delete m_ptr; - m_ptr = NULL; - } - return 0; - } - -}; - -#endif // of __SMART_PTR_H diff --git a/emulator/opengl/host/libs/Translator/include/GLcommon/TranslatorIfaces.h b/emulator/opengl/host/libs/Translator/include/GLcommon/TranslatorIfaces.h index 3c5e15a..e0d1bfb 100644 --- a/emulator/opengl/host/libs/Translator/include/GLcommon/TranslatorIfaces.h +++ b/emulator/opengl/host/libs/Translator/include/GLcommon/TranslatorIfaces.h @@ -74,8 +74,8 @@ struct EglImage unsigned int border; }; -typedef SmartPtr<EglImage> ImagePtr; -typedef std::map< unsigned int, ImagePtr> ImagesHndlMap; +typedef emugl::SmartPtr<EglImage> ImagePtr; +typedef std::map< unsigned int, ImagePtr> ImagesHndlMap; class GLEScontext; diff --git a/emulator/opengl/host/libs/Translator/include/GLcommon/objectNameManager.h b/emulator/opengl/host/libs/Translator/include/GLcommon/objectNameManager.h index 605fd29..0a00644 100644 --- a/emulator/opengl/host/libs/Translator/include/GLcommon/objectNameManager.h +++ b/emulator/opengl/host/libs/Translator/include/GLcommon/objectNameManager.h @@ -18,7 +18,7 @@ #include <cutils/threads.h> #include <map> -#include "SmartPtr.h" +#include "emugl/common/smart_ptr.h" enum NamedObjectType { VERTEXBUFFER = 0, @@ -47,7 +47,7 @@ public: private: ObjectDataType m_dataType; }; -typedef SmartPtr<ObjectData> ObjectDataPtr; +typedef emugl::SmartPtr<ObjectData> ObjectDataPtr; typedef unsigned long long ObjectLocalName; typedef std::map<ObjectLocalName, unsigned int> NamesMap; @@ -143,7 +143,7 @@ private: class ShareGroup { friend class ObjectNameManager; - friend class SmartPtr<ShareGroup>; // to allow destructing when ShareGroupPtr refcount reaches zero + friend class emugl::SmartPtr<ShareGroup>; // to allow destructing when ShareGroupPtr refcount reaches zero public: @@ -209,7 +209,7 @@ private: void *m_objectsData; }; -typedef SmartPtr<ShareGroup> ShareGroupPtr; +typedef emugl::SmartPtr<ShareGroup> ShareGroupPtr; typedef std::multimap<void *, ShareGroupPtr> ShareGroupsMap; // diff --git a/emulator/opengl/host/libs/libOpenglRender/Android.mk b/emulator/opengl/host/libs/libOpenglRender/Android.mk index 1d923b4..8b8ba79 100644 --- a/emulator/opengl/host/libs/libOpenglRender/Android.mk +++ b/emulator/opengl/host/libs/libOpenglRender/Android.mk @@ -54,7 +54,7 @@ $(call emugl-export,C_INCLUDES,$(LOCAL_PATH)) # use Translator's egl/gles headers LOCAL_C_INCLUDES += $(EMUGL_PATH)/host/libs/Translator/include -LOCAL_STATIC_LIBRARIES += libutils liblog +LOCAL_STATIC_LIBRARIES += libemugl_common libutils libcutils liblog $(call emugl-export,CFLAGS,$(host_common_CFLAGS)) @@ -76,7 +76,7 @@ $(call emugl-export,C_INCLUDES,$(LOCAL_PATH)) # use Translator's egl/gles headers LOCAL_C_INCLUDES += $(EMUGL_PATH)/host/libs/Translator/include -LOCAL_STATIC_LIBRARIES += lib64utils lib64log +LOCAL_STATIC_LIBRARIES += lib64emugl_common lib64utils lib64cutils lib64log $(call emugl-export,CFLAGS,$(host_common_CFLAGS) -m64) diff --git a/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.h b/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.h index 883162b..9a919c3 100644 --- a/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.h +++ b/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.h @@ -19,7 +19,7 @@ #include <EGL/egl.h> #include <EGL/eglext.h> #include <GLES/gl.h> -#include <SmartPtr.h> +#include "emugl/common/smart_ptr.h" class ColorBuffer { @@ -55,6 +55,6 @@ private: GLenum m_internalFormat; }; -typedef SmartPtr<ColorBuffer> ColorBufferPtr; +typedef emugl::SmartPtr<ColorBuffer> ColorBufferPtr; #endif diff --git a/emulator/opengl/host/libs/libOpenglRender/RenderContext.h b/emulator/opengl/host/libs/libOpenglRender/RenderContext.h index 9cbb5fc..80ac43f 100644 --- a/emulator/opengl/host/libs/libOpenglRender/RenderContext.h +++ b/emulator/opengl/host/libs/libOpenglRender/RenderContext.h @@ -16,12 +16,12 @@ #ifndef _LIBRENDER_RENDERCONTEXT_H #define _LIBRENDER_RENDERCONTEXT_H -#include "SmartPtr.h" +#include "emugl/common/smart_ptr.h" #include <EGL/egl.h> #include "GLDecoderContextData.h" class RenderContext; -typedef SmartPtr<RenderContext> RenderContextPtr; +typedef emugl::SmartPtr<RenderContext> RenderContextPtr; class RenderContext { diff --git a/emulator/opengl/host/libs/libOpenglRender/WindowSurface.h b/emulator/opengl/host/libs/libOpenglRender/WindowSurface.h index e9f1f7d..fe35a94 100644 --- a/emulator/opengl/host/libs/libOpenglRender/WindowSurface.h +++ b/emulator/opengl/host/libs/libOpenglRender/WindowSurface.h @@ -19,7 +19,7 @@ #include "ColorBuffer.h" #include "RenderContext.h" #include "FBConfig.h" -#include "SmartPtr.h" +#include "emugl/common/smart_ptr.h" #include "FixedBuffer.h" #include <EGL/egl.h> #include <GLES/gl.h> @@ -66,6 +66,6 @@ private: const FBConfig *m_fbconf; }; -typedef SmartPtr<WindowSurface> WindowSurfacePtr; +typedef emugl::SmartPtr<WindowSurface> WindowSurfacePtr; #endif diff --git a/emulator/opengl/shared/OpenglCodecCommon/ErrorLog.h b/emulator/opengl/shared/OpenglCodecCommon/ErrorLog.h index 6f41fd7..43577d4 100644 --- a/emulator/opengl/shared/OpenglCodecCommon/ErrorLog.h +++ b/emulator/opengl/shared/OpenglCodecCommon/ErrorLog.h @@ -16,7 +16,7 @@ #ifndef _ERROR_LOG_H_ #define _ERROR_LOG_H_ -#if (HAVE_ANDROID_OS == 1) +#ifdef __ANDROID__ # include <cutils/log.h> # define ERR(...) ALOGE(__VA_ARGS__) # ifdef EMUGL_DEBUG diff --git a/emulator/opengl/shared/OpenglCodecCommon/GLClientState.cpp b/emulator/opengl/shared/OpenglCodecCommon/GLClientState.cpp index 9795490..b02131c 100644 --- a/emulator/opengl/shared/OpenglCodecCommon/GLClientState.cpp +++ b/emulator/opengl/shared/OpenglCodecCommon/GLClientState.cpp @@ -19,7 +19,6 @@ #include <stdlib.h> #include <string.h> #include "glUtils.h" -#include <cutils/log.h> #ifndef MAX #define MAX(a, b) ((a) < (b) ? (b) : (a)) diff --git a/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.h b/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.h index 61b8f00..e7341dc 100644 --- a/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.h +++ b/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.h @@ -35,7 +35,7 @@ #include <utils/String8.h> #include <utils/threads.h> #include "FixedBuffer.h" -#include "SmartPtr.h" +#include "emugl/common/smart_ptr.h" struct BufferData { BufferData(); @@ -138,6 +138,6 @@ public: void unrefShaderData(GLuint shader); }; -typedef SmartPtr<GLSharedGroup> GLSharedGroupPtr; +typedef emugl::SmartPtr<GLSharedGroup> GLSharedGroupPtr; #endif //_GL_SHARED_GROUP_H_ diff --git a/emulator/opengl/shared/OpenglCodecCommon/SmartPtr.h b/emulator/opengl/shared/OpenglCodecCommon/SmartPtr.h deleted file mode 100644 index 4bdfbe4..0000000 --- a/emulator/opengl/shared/OpenglCodecCommon/SmartPtr.h +++ /dev/null @@ -1,167 +0,0 @@ -/* -* Copyright (C) 2011 The Android Open Source Project -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -#ifndef __SMART_PTR_H -#define __SMART_PTR_H - -#include <cutils/threads.h> -#include <cutils/atomic.h> - -template <class T, bool threadSafe = false> -class SmartPtr -{ -public: - explicit SmartPtr(T* ptr = (T*)NULL) { - if (threadSafe) { - m_lock = new mutex_t; - mutex_init(m_lock); - } - else m_lock = NULL; - - m_ptr = ptr; - if (ptr) - m_pRefCount = new int32_t(1); - else - m_pRefCount = NULL; - } - - SmartPtr<T,threadSafe>(const SmartPtr<T,false>& rhs) { - if (threadSafe) { - m_lock = new mutex_t; - mutex_init(m_lock); - } - else m_lock = NULL; - - m_pRefCount = rhs.m_pRefCount; - m_ptr = rhs.m_ptr; - use(); - } - - SmartPtr<T,threadSafe>(SmartPtr<T,true>& rhs) { - if (threadSafe) { - m_lock = new mutex_t; - mutex_init(m_lock); - } - else m_lock = NULL; - - if (rhs.m_lock) mutex_lock(rhs.m_lock); - m_pRefCount = rhs.m_pRefCount; - m_ptr = rhs.m_ptr; - use(); - if (rhs.m_lock) mutex_unlock(rhs.m_lock); - } - - ~SmartPtr() { - if (m_lock) mutex_lock(m_lock); - release(); - if (m_lock) - { - mutex_unlock(m_lock); - mutex_destroy(m_lock); - delete m_lock; - } - } - - T* Ptr() const { - return m_ptr; - } - - const T* constPtr() const - { - return m_ptr; - } - - T* operator->() const { - return m_ptr; - } - - T& operator*() const { - return *m_ptr; - } - - operator void*() const { - return (void *)m_ptr; - } - - // This gives STL lists something to compare. - bool operator <(const SmartPtr<T>& t1) const { - return m_ptr < t1.m_ptr; - } - - SmartPtr<T,threadSafe>& operator=(const SmartPtr<T,false>& rhs) - { - if (m_ptr == rhs.m_ptr) - return *this; - - if (m_lock) mutex_lock(m_lock); - release(); - m_pRefCount = rhs.m_pRefCount; - m_ptr = rhs.m_ptr; - use(); - if (m_lock) mutex_unlock(m_lock); - - return *this; - } - - SmartPtr<T,threadSafe>& operator=(SmartPtr<T,true>& rhs) - { - if (m_ptr == rhs.m_ptr) - return *this; - - if (m_lock) mutex_lock(m_lock); - release(); - if (rhs.m_lock) mutex_lock(rhs.m_lock); - m_pRefCount = rhs.m_pRefCount; - m_ptr = rhs.m_ptr; - use(); - if (rhs.m_lock) mutex_unlock(rhs.m_lock); - if (m_lock) mutex_unlock(m_lock); - - return *this; - } - -private: - int32_t *m_pRefCount; - mutex_t *m_lock; - T* m_ptr; - - // Increment the reference count on this pointer by 1. - int use() { - if (!m_pRefCount) return 0; - return android_atomic_inc(m_pRefCount) + 1; - } - - // Decrement the reference count on the pointer by 1. - // If the reference count goes to (or below) 0, the pointer is deleted. - int release() { - if (!m_pRefCount) return 0; - - int iVal = android_atomic_dec(m_pRefCount); - if (iVal > 1) - return iVal - 1; - - delete m_pRefCount; - m_pRefCount = NULL; - - if (m_ptr) { - delete m_ptr; - m_ptr = NULL; - } - return 0; - } - -}; - -#endif // of __SMART_PTR_H diff --git a/emulator/opengl/shared/emugl/common/Android.mk b/emulator/opengl/shared/emugl/common/Android.mk new file mode 100644 index 0000000..0af670c --- /dev/null +++ b/emulator/opengl/shared/emugl/common/Android.mk @@ -0,0 +1,34 @@ +# This build script corresponds to a library containing many definitions +# common to both the guest and the host. They relate to +# +LOCAL_PATH := $(call my-dir) + +### emugl_common host library ########################################### + +commonSources := \ + smart_ptr.cpp \ + +host_commonSources := $(commonSources) + +$(call emugl-begin-host-static-library,libemugl_common) +LOCAL_SRC_FILES := $(host_commonSources) +$(call emugl-end-module) + +$(call emugl-begin-host-static-library,lib64emugl_common) +LOCAL_SRC_FILES := $(host_commonSources) +$(call emugl-export,CFLAGS,-m64) +$(call emugl-end-module) + + +### emugl_common_unittests ############################################## + +host_commonSources := \ + smart_ptr_unittest.cpp + +$(call emugl-begin-host-executable,emugl_common_host_unittests) +LOCAL_SRC_FILES := $(host_commonSources) +LOCAL_C_INCLUDES += external/gtest/include +$(call emugl-export,STATIC_LIBRARIES, libemugl_common libgtest_host libgtest_main_host) +$(call emugl-end-module) + +# TODO(digit): 64-bit version, once we have 64-bit gtest. diff --git a/emulator/opengl/shared/emugl/common/smart_ptr.cpp b/emulator/opengl/shared/emugl/common/smart_ptr.cpp new file mode 100644 index 0000000..9ac7339 --- /dev/null +++ b/emulator/opengl/shared/emugl/common/smart_ptr.cpp @@ -0,0 +1,111 @@ +// Copyright (C) 2014 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 "emugl/common/smart_ptr.h" + +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#endif + +namespace emugl { + +// Thread-safe atomic reference-counting type. +class RefCount { +public: + RefCount() : mCount(1) {} + ~RefCount() {} + + // Technically not thread-safe, use only for testing. + int count() const { return (int)mCount; } + + void increment() { +#ifdef _WIN32 + InterlockedIncrement(&mCount); +#else + __sync_fetch_and_add(&mCount, 1); +#endif + } + + bool decrement() { +#ifdef _WIN32 + return InterlockedDecrement(&mCount) == 0; +#else + return __sync_add_and_fetch(&mCount, -1) == 0; +#endif + } + +private: +#ifdef _WIN32 + LONG mCount; +#else + int mCount; +#endif +}; + + +// SmartPtrBase implementation. + +SmartPtrBase::SmartPtrBase(void* ptr) : mPtr(ptr), mRefCount(NULL) { + if (mPtr) + mRefCount = new RefCount(); +} + + +SmartPtrBase::SmartPtrBase(const SmartPtrBase& other) + : mPtr(other.mPtr), mRefCount(other.mRefCount) { + if (mRefCount) + mRefCount->increment(); +} + + +int SmartPtrBase::getRefCount() const { + return mRefCount ? mRefCount->count() : 0; +} + + +void SmartPtrBase::addRef() { + if (mRefCount) + mRefCount->increment(); +} + + +void* SmartPtrBase::copyFrom(const SmartPtrBase& other) { + void* old_ptr = release(); + + mPtr = other.mPtr; + mRefCount = other.mRefCount; + if (mRefCount) + mRefCount->increment(); + + return old_ptr; +} + + +void* SmartPtrBase::release() { + void* old_ptr = mPtr; + RefCount* old_refcount = mRefCount; + + if (old_refcount) { + mPtr = NULL; + mRefCount = NULL; + + if (old_refcount->decrement()) + return old_ptr; + } + + return NULL; +} + +} // namespace emugl diff --git a/emulator/opengl/shared/emugl/common/smart_ptr.h b/emulator/opengl/shared/emugl/common/smart_ptr.h new file mode 100644 index 0000000..2d7db5b --- /dev/null +++ b/emulator/opengl/shared/emugl/common/smart_ptr.h @@ -0,0 +1,150 @@ +// Copyright (C) 2014 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 EMUGL_SMART_PTR_H +#define EMUGL_SMART_PTR_H + +#include <stddef.h> + +namespace emugl { + +// Hidden atomic ref-counting implementation. +class RefCount; + +// Base class for all templated SmartPtr<> instances. Reduces +// template expansion and code. Consider this to be an implementation +// detail of SmartPtr<>, so don't rely on anything here. +class SmartPtrBase { +public: + // Defrault constructor. + SmartPtrBase() : mPtr(NULL), mRefCount(NULL) {} + + // Normal constructor. This takes ownership of |ptr|, though only + // template instances are capable of destroying the object. + explicit SmartPtrBase(void* ptr); + + // Copy-constructor, this increments the reference count. + SmartPtrBase(const SmartPtrBase& other); + + // Assignment operator, also increments the reference count. + SmartPtrBase& operator=(const SmartPtrBase& other); + + // Nothing happens in this constructor, the real work must be performed + // in subclasses. + ~SmartPtrBase() {} + + + // Used to enable 'if (smart_ptr) { ... }' properly. + operator void*() const { + return mPtr; + } + + // Return internal reference count value, only use for unit testing. + int getRefCount() const; + +protected: + // Used internally to increment the reference count. + void addRef(); + + // Copy the |other| into this instance, returns the old pointer value + // if it needs to be destroyed by the caller, or NULL otherwise. + void* copyFrom(const SmartPtrBase& other); + + // Used internally to decrement the reference count, if it reaches 0, + // returns the pointer to be destroyed, NULL otherwise. + void* release(); + + void* mPtr; + RefCount* mRefCount; +}; + + +// The real template class to be used for smart pointers. +// Typical uses: +// +// SmartPtr<Foo> ptr(new Foo()); // takes ownership. +// SmartPtr<Foo> ptr2; // empty pointer. +// ptr2 = ptr; // copies pointer + increment reference count. +// Foo* obj = ptr.Ptr(); // access pointed object. +// ptr->DoStuff(); // operate directly on pointed object. +// (*ptr)->DoStuff(); // same here. +// +// On scope exit, the internal reference count is decremented and the +// object is deleted automatically when it reaches 0, indicating that +// there are no more owners. +// +// IMPORTANT: You need to be sure that only one 'chain' of smart pointers +// own a given object. I.e. the following is incorrect: +// +// Foo* foo = new Foo(); // create new instance. +// SmartPtr<Foo> ptr(foo); // |ptr| takes ownership of |foo|. +// SmartPtr<Foo> ptr2(foo); // |ptr2| takes also ownership of |foo|. +// +// The problem is that |ptr| and |ptr2| don't know anything about each +// other, and will not share the same reference count. Once a smart pointer +// owns an object, only use other smart pointers that are copy-constructed +// or assigned with the initial one to keep everything consistent. +template <class T> +class SmartPtr : public emugl::SmartPtrBase { +public: + // Default constructor. The instance holds a NULL pointer. + SmartPtr() : SmartPtrBase() {} + + // Regular constructor, takes ownership of |ptr|. + explicit SmartPtr(T* ptr) : SmartPtrBase(ptr) {} + + // Copy-constructor, |this| and |other| will share the same internal + // reference count, which is incremented by 1. + SmartPtr(const SmartPtr& other) + : SmartPtrBase(reinterpret_cast<const SmartPtrBase&>(other)) {} + + // Assignment operator, same semantics as copy-constructor. + SmartPtr& operator=(const SmartPtr& other) { + void* old_ptr = copyFrom(static_cast<const SmartPtrBase&>(other)); + if (old_ptr) + delete reinterpret_cast<T*>(old_ptr); + return *this; + } + + // Destructor, decrements reference count and destroys the object + // if it reaches 0 (indicating this was the last owning smart pointer). + ~SmartPtr() { + void* ptr = release(); + if (ptr) + delete reinterpret_cast<T*>(ptr); + } + + // Return owned object instance, or NULL. + T* Ptr() const { + return reinterpret_cast<T*>(mPtr); + } + + // Return owned object instance, or NULL + const T* constPtr() const { + return reinterpret_cast<const T*>(mPtr); + } + + // Operate directly on owned object. + T* operator->() const { + return Ptr(); + } + + // Return reference to owned object. + T& operator*() const { + return *Ptr(); + } +}; + +} // namespace emugl + +#endif // EMUGL_SMART_PTR_H diff --git a/emulator/opengl/shared/emugl/common/smart_ptr_unittest.cpp b/emulator/opengl/shared/emugl/common/smart_ptr_unittest.cpp new file mode 100644 index 0000000..db9e5f2 --- /dev/null +++ b/emulator/opengl/shared/emugl/common/smart_ptr_unittest.cpp @@ -0,0 +1,140 @@ +// Copyright (C) 2014 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 "emugl/common/smart_ptr.h" + +#include <gtest/gtest.h> + +namespace emugl { + +// This Test sub-class is used to track allocations and deallocations of +// the MyTestClass instances that are created through newInstance(). +// See below for typical usage. +class SmartPtrTest : public testing::Test { +public: + SmartPtrTest() : mNewCount(0), mDeleteCount(0), mDoCount(0) {} + + ~SmartPtrTest() { + mNewCount = 0; + mDoCount = 0; + mDeleteCount = 0; + } + + class MyClass; + + MyClass* newInstance() { + return new MyClass(this); + } + + class MyClass { + public: + MyClass(SmartPtrTest* test) : mTest(test) { + mTest->mNewCount++; + } + + void doStuff() { + mTest->mDoCount++; + } + + ~MyClass() { + mTest->mDeleteCount++; + } + private: + SmartPtrTest* mTest; + }; + + int mNewCount; + int mDeleteCount; + int mDoCount; +}; + + +TEST_F(SmartPtrTest, Empty) { + SmartPtr<MyClass> ptr; + EXPECT_FALSE(ptr.Ptr()); + + EXPECT_EQ(0, mNewCount); + EXPECT_EQ(0, mDeleteCount); + EXPECT_EQ(0, mDoCount); +} + + +TEST_F(SmartPtrTest, SingleRef) { + MyClass* obj = newInstance(); + EXPECT_EQ(1, mNewCount); + + { + SmartPtr<MyClass> ptr(obj); + EXPECT_EQ(obj, ptr.Ptr()); + + EXPECT_EQ(1, mNewCount); + EXPECT_EQ(0, mDeleteCount); + EXPECT_EQ(0, mDoCount); + } + // Check that the object was deleted. + EXPECT_EQ(1, mDeleteCount); +} + + +TEST_F(SmartPtrTest, CopyConstructor) { + MyClass* obj = newInstance(); + EXPECT_EQ(1, mNewCount); + + { + SmartPtr<MyClass> ptr1(obj); + { + SmartPtr<MyClass> ptr2(ptr1); + EXPECT_EQ(2, ptr1.getRefCount()); + EXPECT_EQ(2, ptr2.getRefCount()); + EXPECT_EQ(1, mNewCount); + EXPECT_EQ(0, mDeleteCount); + EXPECT_EQ(0, mDoCount); + } + EXPECT_EQ(1, mNewCount); + EXPECT_EQ(0, mDeleteCount); + EXPECT_EQ(0, mDoCount); + } + EXPECT_EQ(1, mNewCount); + EXPECT_EQ(1, mDeleteCount); + EXPECT_EQ(0, mDoCount); +} + + +TEST_F(SmartPtrTest, AssignmentOperator) { + SmartPtr<MyClass> ptr1(newInstance()); + SmartPtr<MyClass> ptr2(newInstance()); + EXPECT_EQ(2, mNewCount); + EXPECT_EQ(0, mDeleteCount); + EXPECT_EQ(0, mDoCount); + + ptr2 = ptr1; + EXPECT_EQ(2, mNewCount); + EXPECT_EQ(1, mDeleteCount); + + EXPECT_EQ(ptr1.Ptr(), ptr2.Ptr()); + EXPECT_EQ(2, ptr1.getRefCount()); + EXPECT_EQ(2, ptr2.getRefCount()); +} + + +TEST_F(SmartPtrTest, ArrowOperator) { + SmartPtr<MyClass> ptr(newInstance()); + ptr->doStuff(); + EXPECT_EQ(1, mDoCount); + + (*ptr).doStuff(); + EXPECT_EQ(2, mDoCount); +} + +} // namespace emugl |