aboutsummaryrefslogtreecommitdiffstats
path: root/emulator/opengl
diff options
context:
space:
mode:
Diffstat (limited to 'emulator/opengl')
-rw-r--r--emulator/opengl/Android.mk37
-rw-r--r--emulator/opengl/common.mk26
-rwxr-xr-xemulator/opengl/gen-encoder.sh9
-rw-r--r--emulator/opengl/googletest.mk43
-rw-r--r--emulator/opengl/host/libs/GLESv1_dec/Android.mk18
-rw-r--r--emulator/opengl/host/libs/GLESv1_dec/GLDecoder.cpp20
-rw-r--r--emulator/opengl/host/libs/GLESv2_dec/Android.mk18
-rw-r--r--emulator/opengl/host/libs/GLESv2_dec/GL2Decoder.cpp7
-rw-r--r--emulator/opengl/host/libs/Translator/EGL/Android.mk13
-rw-r--r--emulator/opengl/host/libs/Translator/EGL/EglContext.h4
-rw-r--r--emulator/opengl/host/libs/Translator/EGL/EglDisplay.cpp51
-rw-r--r--emulator/opengl/host/libs/Translator/EGL/EglDisplay.h7
-rw-r--r--emulator/opengl/host/libs/Translator/EGL/EglGlobalInfo.cpp10
-rw-r--r--emulator/opengl/host/libs/Translator/EGL/EglGlobalInfo.h11
-rw-r--r--emulator/opengl/host/libs/Translator/EGL/EglImp.cpp54
-rw-r--r--emulator/opengl/host/libs/Translator/EGL/EglSurface.h7
-rw-r--r--emulator/opengl/host/libs/Translator/EGL/EglThreadInfo.cpp31
-rw-r--r--emulator/opengl/host/libs/Translator/EGL/EglWindowsApi.cpp24
-rw-r--r--emulator/opengl/host/libs/Translator/EGL/EglX11Api.cpp17
-rw-r--r--emulator/opengl/host/libs/Translator/EGL/ThreadInfo.cpp58
-rw-r--r--emulator/opengl/host/libs/Translator/GLES_CM/Android.mk13
-rw-r--r--emulator/opengl/host/libs/Translator/GLES_CM/GLDispatch.cpp2
-rw-r--r--emulator/opengl/host/libs/Translator/GLES_CM/GLDispatch.h6
-rw-r--r--emulator/opengl/host/libs/Translator/GLES_CM/GLEScmContext.cpp2
-rw-r--r--emulator/opengl/host/libs/Translator/GLES_CM/GLEScmContext.h1
-rw-r--r--emulator/opengl/host/libs/Translator/GLES_CM/GLEScmImp.cpp26
-rw-r--r--emulator/opengl/host/libs/Translator/GLES_V2/Android.mk12
-rw-r--r--emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Context.cpp5
-rw-r--r--emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Context.h1
-rw-r--r--emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Imp.cpp19
-rw-r--r--emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Validate.cpp1
-rw-r--r--emulator/opengl/host/libs/Translator/GLES_V2/ShaderParser.cpp4
-rw-r--r--emulator/opengl/host/libs/Translator/GLcommon/Android.mk28
-rw-r--r--emulator/opengl/host/libs/Translator/GLcommon/GLDispatch.cpp41
-rw-r--r--emulator/opengl/host/libs/Translator/GLcommon/GLEScontext.cpp12
-rw-r--r--emulator/opengl/host/libs/Translator/GLcommon/objectNameManager.cpp174
-rw-r--r--emulator/opengl/host/libs/Translator/include/ETC1/etc1.h106
-rw-r--r--emulator/opengl/host/libs/Translator/include/GLcommon/GLDispatch.h6
-rw-r--r--emulator/opengl/host/libs/Translator/include/GLcommon/GLESbuffer.h2
-rw-r--r--emulator/opengl/host/libs/Translator/include/GLcommon/GLEScontext.h4
-rw-r--r--emulator/opengl/host/libs/Translator/include/GLcommon/GLutils.h41
-rw-r--r--emulator/opengl/host/libs/Translator/include/GLcommon/SmartPtr.h163
-rw-r--r--emulator/opengl/host/libs/Translator/include/GLcommon/TranslatorIfaces.h4
-rw-r--r--emulator/opengl/host/libs/Translator/include/GLcommon/objectNameManager.h16
-rw-r--r--emulator/opengl/host/libs/Translator/include/KHR/khrplatform.h282
-rw-r--r--emulator/opengl/host/libs/libOpenglRender/Android.mk28
-rw-r--r--emulator/opengl/host/libs/libOpenglRender/ColorBuffer.cpp28
-rw-r--r--emulator/opengl/host/libs/libOpenglRender/ColorBuffer.h4
-rw-r--r--emulator/opengl/host/libs/libOpenglRender/FBConfig.cpp1
-rw-r--r--emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp38
-rw-r--r--emulator/opengl/host/libs/libOpenglRender/FrameBuffer.h7
-rw-r--r--emulator/opengl/host/libs/libOpenglRender/RenderContext.h4
-rw-r--r--emulator/opengl/host/libs/libOpenglRender/RenderControl.cpp14
-rw-r--r--emulator/opengl/host/libs/libOpenglRender/RenderThread.cpp2
-rw-r--r--emulator/opengl/host/libs/libOpenglRender/ThreadInfo.cpp19
-rw-r--r--emulator/opengl/host/libs/libOpenglRender/WindowSurface.cpp5
-rw-r--r--emulator/opengl/host/libs/libOpenglRender/WindowSurface.h4
-rw-r--r--emulator/opengl/host/libs/renderControl_dec/Android.mk16
-rw-r--r--emulator/opengl/host/libs/renderControl_dec/renderControl.in1
-rw-r--r--emulator/opengl/host/renderer/main.cpp2
-rw-r--r--emulator/opengl/host/tools/emugen/Android.mk36
-rw-r--r--emulator/opengl/host/tools/emugen/ApiGen.cpp40
-rw-r--r--emulator/opengl/host/tools/emugen/ApiGen.h2
-rw-r--r--emulator/opengl/host/tools/emugen/getopt.c76
-rw-r--r--emulator/opengl/host/tools/emugen/getopt.h18
-rw-r--r--emulator/opengl/host/tools/emugen/main.cpp1
-rw-r--r--emulator/opengl/sdl.mk25
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/Android.mk22
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/ErrorLog.h22
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/GLClientState.cpp1
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/GLDecoderContextData.h4
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.cpp294
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.h30
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/SmartPtr.h167
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/SocketStream.cpp5
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/TcpStream.cpp72
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/UnixStream.cpp8
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/Win32PipeStream.cpp2
-rw-r--r--emulator/opengl/shared/OpenglOsUtils/Android.mk19
-rw-r--r--emulator/opengl/shared/OpenglOsUtils/osThreadUnix.cpp10
-rw-r--r--emulator/opengl/shared/OpenglOsUtils/osThreadWin.cpp3
-rw-r--r--emulator/opengl/shared/emugl/common/Android.mk54
-rw-r--r--emulator/opengl/shared/emugl/common/id_to_object_map.cpp236
-rw-r--r--emulator/opengl/shared/emugl/common/id_to_object_map.h176
-rw-r--r--emulator/opengl/shared/emugl/common/id_to_object_map_unittest.cpp116
-rw-r--r--emulator/opengl/shared/emugl/common/lazy_instance.cpp101
-rw-r--r--emulator/opengl/shared/emugl/common/lazy_instance.h156
-rw-r--r--emulator/opengl/shared/emugl/common/lazy_instance_unittest.cpp146
-rw-r--r--emulator/opengl/shared/emugl/common/mutex.h92
-rw-r--r--emulator/opengl/shared/emugl/common/mutex_unittest.cpp108
-rw-r--r--emulator/opengl/shared/emugl/common/pod_vector.cpp150
-rw-r--r--emulator/opengl/shared/emugl/common/pod_vector.h265
-rw-r--r--emulator/opengl/shared/emugl/common/pod_vector_unittest.cpp127
-rw-r--r--emulator/opengl/shared/emugl/common/scoped_pointer_vector.h27
-rw-r--r--emulator/opengl/shared/emugl/common/smart_ptr.cpp113
-rw-r--r--emulator/opengl/shared/emugl/common/smart_ptr.h150
-rw-r--r--emulator/opengl/shared/emugl/common/smart_ptr_unittest.cpp140
-rw-r--r--emulator/opengl/shared/emugl/common/sockets.cpp222
-rw-r--r--emulator/opengl/shared/emugl/common/sockets.h57
-rw-r--r--emulator/opengl/shared/emugl/common/testing/test_thread.h78
-rw-r--r--emulator/opengl/shared/emugl/common/thread_store.cpp242
-rw-r--r--emulator/opengl/shared/emugl/common/thread_store.h110
-rw-r--r--emulator/opengl/shared/emugl/common/thread_store_unittest.cpp146
-rw-r--r--emulator/opengl/tests/emulator_test_renderer/Android.mk13
-rw-r--r--emulator/opengl/tests/event_injector/sockets.c4
-rw-r--r--emulator/opengl/tests/translator_tests/GLES_CM/Android.mk13
-rw-r--r--emulator/opengl/tests/translator_tests/GLES_CM/triangleCM.cpp11
-rw-r--r--emulator/opengl/tests/translator_tests/GLES_V2/Android.mk12
-rw-r--r--emulator/opengl/tests/translator_tests/GLES_V2/triangleV2.cpp16
-rw-r--r--emulator/opengl/tests/ut_renderer/Android.mk2
-rw-r--r--emulator/opengl/tests/ut_renderer/Renderer.cpp12
-rw-r--r--emulator/opengl/tests/ut_renderer/Renderer.h4
112 files changed, 4401 insertions, 1164 deletions
diff --git a/emulator/opengl/Android.mk b/emulator/opengl/Android.mk
index a349b96..856826a 100644
--- a/emulator/opengl/Android.mk
+++ b/emulator/opengl/Android.mk
@@ -1,13 +1,10 @@
# This is the top-level build file for the Android HW OpenGL ES emulation
# in Android.
#
-# You must define BUILD_EMULATOR_OPENGL to 'true' in your environment to
+# You must define BUILD_EMULATOR_HOST_OPENGL to 'true' in your environment to
# build the following files.
#
-# Also define BUILD_EMULATOR_OPENGL_DRIVER to 'true' to build the gralloc
-# stuff as well.
-#
-ifeq (true,$(BUILD_EMULATOR_OPENGL))
+ifeq (true,$(BUILD_EMULATOR_HOST_OPENGL))
# Top-level for all modules
EMUGL_PATH := $(call my-dir)
@@ -16,7 +13,19 @@ 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
+endif
+
+ifeq ($(BUILD_STANDALONE_EMULATOR),true)
+EMUGL_BUILD_64BITS := $(strip $(EMULATOR_BUILD_64BITS))
+else
+EMUGL_BUILD_64BITS := true
+endif
# common cflags used by several modules
# This is always set to a module's LOCAL_CFLAGS
@@ -24,6 +33,12 @@ EMUGL_COMMON_INCLUDES := $(EMUGL_PATH)/host/include/libOpenglRender
#
EMUGL_COMMON_CFLAGS := -DWITH_GLES2
+# Define EMUGL_BUILD_DEBUG=1 in your environment to build a
+# debug version of the EmuGL host binaries.
+ifneq (,$(strip $(EMUGL_BUILD_DEBUG)))
+EMUGL_COMMON_CFLAGS += -O0 -g -DEMUGL_DEBUG=1
+endif
+
# Uncomment the following line if you want to enable debug traces
# in the GLES emulation libraries.
# EMUGL_COMMON_CFLAGS += -DEMUGL_DEBUG=1
@@ -53,6 +68,11 @@ include $(EMUGL_PATH)/common.mk
# source files (see all emugl-gen-decoder/encoder in common.mk)
#
include $(EMUGL_PATH)/host/tools/emugen/Android.mk
+
+# Required by our units test.
+include $(EMUGL_PATH)/googletest.mk
+
+include $(EMUGL_PATH)/shared/emugl/common/Android.mk
include $(EMUGL_PATH)/shared/OpenglOsUtils/Android.mk
include $(EMUGL_PATH)/shared/OpenglCodecCommon/Android.mk
@@ -66,6 +86,9 @@ include $(EMUGL_PATH)/host/libs/Translator/GLES_CM/Android.mk
include $(EMUGL_PATH)/host/libs/Translator/GLES_V2/Android.mk
include $(EMUGL_PATH)/host/libs/Translator/EGL/Android.mk
+# Required to declare SDL-related flags for some host tests.
+include $(EMUGL_PATH)/sdl.mk
+
# Host shared libraries
include $(EMUGL_PATH)/host/libs/libOpenglRender/Android.mk
@@ -78,4 +101,4 @@ include $(EMUGL_PATH)/tests/translator_tests/MacCommon/Android.mk
include $(EMUGL_PATH)/tests/translator_tests/GLES_CM/Android.mk
include $(EMUGL_PATH)/tests/translator_tests/GLES_V2/Android.mk
-endif # BUILD_EMULATOR_OPENGL == true
+endif # BUILD_EMULATOR_HOST_OPENGL == true
diff --git a/emulator/opengl/common.mk b/emulator/opengl/common.mk
index be5eaf5..255b9e3 100644
--- a/emulator/opengl/common.mk
+++ b/emulator/opengl/common.mk
@@ -24,10 +24,20 @@ emugl-begin-host-static-library = $(call emugl-begin-module,$1,HOST_STATIC_LIBRA
emugl-begin-host-shared-library = $(call emugl-begin-module,$1,HOST_SHARED_LIBRARY,HOST)
emugl-begin-host-executable = $(call emugl-begin-module,$1,HOST_EXECUTABLE,HOST)
+emugl-begin-host64-static-library = $(call emugl-begin-module64,$1,HOST_STATIC_LIBRARY,HOST)
+emugl-begin-host64-shared-library = $(call emugl-begin-module64,$1,HOST_SHARED_LIBRARY,HOST)
+emugl-begin-host64-executable = $(call emugl-begin-module64,$1,HOST_EXECUTABLE,HOST)
+
# Internal list of all declared modules (used for sanity checking)
_emugl_modules :=
_emugl_HOST_modules :=
+ifeq ($(BUILD_STANDALONE_EMULATOR),true)
+EMUGL_LOCAL_EXTRAS = $(end-emulator-module-ev)
+else # BUILD_STANDALONE_EMULATOR != true
+EMUGL_LOCAL_EXTRAS =
+endif # BUILD_STANDALONE_EMULATOR != true
+
# do not use directly, see functions above instead
emugl-begin-module = \
$(eval include $(CLEAR_VARS)) \
@@ -35,14 +45,21 @@ emugl-begin-module = \
$(eval LOCAL_MODULE_TAGS := $(if $3,,debug)) \
$(eval LOCAL_MODULE_CLASS := $(patsubst HOST_%,%,$(patsubst %EXECUTABLE,%EXECUTABLES,$(patsubst %LIBRARY,%LIBRARIES,$2)))) \
$(eval LOCAL_IS_HOST_MODULE := $(if $3,true,))\
- $(eval LOCAL_C_INCLUDES := $(EMUGL_COMMON_INCLUDES)) \
- $(eval LOCAL_CFLAGS := $(EMUGL_COMMON_CFLAGS)) \
+ $(eval LOCAL_C_INCLUDES += $(EMUGL_COMMON_INCLUDES)) \
+ $(eval LOCAL_CFLAGS += $(EMUGL_COMMON_CFLAGS)) \
+ $(eval LOCAL_LDLIBS += -lstdc++) \
$(eval LOCAL_PRELINK_MODULE := false)\
$(eval _EMUGL_INCLUDE_TYPE := $(BUILD_$2)) \
+ $(eval LOCAL_MODULE_BITS := 32) \
$(call _emugl-init-module,$1,$2,$3)
+emugl-begin-module64 = \
+ $(call emugl-begin-module,$1,$2,$3) \
+ $(eval LOCAL_MODULE_BITS := 64) \
+
# Used to end a module definition, see function definitions above
emugl-end-module = \
+ $(eval $(EMUGL_LOCAL_EXTRAS)) \
$(eval include $(_EMUGL_INCLUDE_TYPE))\
$(eval _EMUGL_INCLUDE_TYPE :=) \
$(eval _emugl_$(_emugl_HOST)modules += $(_emugl_MODULE))\
@@ -87,6 +104,7 @@ emugl-end-module = \
# This is the list of recognized export types we support for now.
EMUGL_EXPORT_TYPES := \
CFLAGS \
+ CXXFLAGS \
LDLIBS \
LDFLAGS \
C_INCLUDES \
@@ -118,7 +136,7 @@ _emugl-init-module = \
# $2: Value(s) to append to the export
emugl-export = \
$(eval _emugl.$(_emugl_MODULE).export.$1 += $2)\
- $(eval LOCAL_$1 := $2 $(LOCAL_$1))
+ $(eval LOCAL_$1 := $(LOCAL_$1) $2)
emugl-export-outer = \
$(eval _emugl.$(_emugl_MODULE).export.$1 += $2)
@@ -148,7 +166,7 @@ _emugl-module-import = \
$(call _emugl-module-import,$(_sub))\
)\
$(foreach _type,$(EMUGL_EXPORT_TYPES),\
- $(eval LOCAL_$(_type) := $(_emugl.$1.export.$(_type)) $(LOCAL_$(_type)))\
+ $(eval LOCAL_$(_type) := $(LOCAL_$(_type)) $(_emugl.$1.export.$(_type)))\
)\
$(if $(filter EXECUTABLE SHARED_LIBRARY,$(_emugl.$(_emugl_MODULE).type)),\
$(if $(filter STATIC_LIBRARY,$(_emugl.$1.type)),\
diff --git a/emulator/opengl/gen-encoder.sh b/emulator/opengl/gen-encoder.sh
index 23ecf03..c55a170 100755
--- a/emulator/opengl/gen-encoder.sh
+++ b/emulator/opengl/gen-encoder.sh
@@ -12,17 +12,12 @@ if [ -z "$ANDROID_BUILD_TOP" ]; then
fi
cd "$ANDROID_BUILD_TOP" >/dev/null
SRCDIR="sdk/emulator/opengl/host/libs"
-DSTDIR="development/tools/emulator/opengl/system"
+DSTDIR="device/generic/goldfish/opengl/system"
+EMUGEN="external/qemu/objs/emugen"
if [ ! -d "$SRCDIR" -o ! -d "$DSTDIR" ]; then
echo error: can\'t find source and/or destination directory
exit 1
fi
-
-if [ -z "$ANDROID_HOST_OUT" ]; then
- echo error: ANDROID_HOST_OUT not set
- exit 1
-fi
-EMUGEN="$ANDROID_HOST_OUT/bin/emugen"
if [ ! -x "$EMUGEN" ]; then
echo error: emugen not available, did you forget to build?
exit 1
diff --git a/emulator/opengl/googletest.mk b/emulator/opengl/googletest.mk
new file mode 100644
index 0000000..8147874
--- /dev/null
+++ b/emulator/opengl/googletest.mk
@@ -0,0 +1,43 @@
+# This contains common definitions used to define a host module
+# to link GoogleTest with the EmuGL test programs.
+#
+# This is used instead of including external/gtest/Android.mk to
+# be able to build both the 32-bit and 64-bit binaries while
+# building a 32-bit only SDK (sdk-eng, sdk_x86-eng, sdk_mips-eng).
+
+
+ifeq (true,$(BUILD_STANDALONE_EMULATOR))
+LOCAL_PATH := $(EMULATOR_GTEST_SOURCES_DIR)
+else
+LOCAL_PATH := $(EMUGL_PATH)/../../../external/gtest
+endif
+
+common_SRC_FILES := \
+ src/gtest-all.cc \
+ src/gtest_main.cc
+
+common_CFLAGS := -O0
+
+ifneq (windows,$(HOST_OS))
+ common_LDLIBS += -lpthread
+endif
+
+$(call emugl-begin-host-static-library,libemugl_gtest)
+LOCAL_SRC_FILES := $(common_SRC_FILES)
+LOCAL_CFLAGS += $(common_CFLAGS)
+LOCAL_CPP_EXTENSION := .cc
+$(call emugl-export,C_INCLUDES,$(LOCAL_PATH)/include)
+$(call emugl-export,LDLIBS,$(common_LDLIBS))
+$(call emugl-end-module)
+
+ifdef EMUGL_BUILD_64BITS
+ $(call emugl-begin-host64-static-library,lib64emugl_gtest)
+ LOCAL_SRC_FILES := $(common_SRC_FILES)
+ LOCAL_CFLAGS += $(common_CFLAGS)
+ LOCAL_C_INCLUDES += $(LOCAL_PATH)/include
+ LOCAL_CPP_EXTENSION := .cc
+ $(call emugl-export,C_INCLUDES,$(LOCAL_PATH)/include)
+ $(call emugl-export,CFLAGS,-m64)
+ $(call emugl-export,LDLIBS,$(common_LDLIBS) -m64)
+ $(call emugl-end-module)
+endif # EMUGL_BUILD_64BITS
diff --git a/emulator/opengl/host/libs/GLESv1_dec/Android.mk b/emulator/opengl/host/libs/GLESv1_dec/Android.mk
index a6d8670..7ab3f0a 100644
--- a/emulator/opengl/host/libs/GLESv1_dec/Android.mk
+++ b/emulator/opengl/host/libs/GLESv1_dec/Android.mk
@@ -18,20 +18,24 @@ $(call emugl-gen-decoder,$(LOCAL_PATH),gl)
LOCAL_SRC_FILES := GLDecoder.cpp
$(call emugl-export,CFLAGS,$(host_common_debug_CFLAGS))
+$(call emugl-export,LDLIBS,-lstdc++)
$(call emugl-end-module)
### host library, 64-bit ####################################
-$(call emugl-begin-host-static-library,lib64GLESv1_dec)
+ifdef EMUGL_BUILD_64BITS
+ $(call emugl-begin-host64-static-library,lib64GLESv1_dec)
-$(call emugl-import, lib64OpenglCodecCommon lib64OpenglOsUtils)
-$(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
+ $(call emugl-import, lib64OpenglCodecCommon lib64OpenglOsUtils)
+ $(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
-$(call emugl-gen-decoder,$(LOCAL_PATH),gl)
+ $(call emugl-gen-decoder,$(LOCAL_PATH),gl)
-LOCAL_SRC_FILES := GLDecoder.cpp
+ LOCAL_SRC_FILES := GLDecoder.cpp
-$(call emugl-export,CFLAGS,$(host_common_debug_CFLAGS) -m64)
+ $(call emugl-export,CFLAGS,$(host_common_debug_CFLAGS) -m64)
+ $(call emugl-export,LDLIBS,-lstdc++)
-$(call emugl-end-module)
+ $(call emugl-end-module)
+endif \ No newline at end of file
diff --git a/emulator/opengl/host/libs/GLESv1_dec/GLDecoder.cpp b/emulator/opengl/host/libs/GLESv1_dec/GLDecoder.cpp
index 5399445..3c5bd70 100644
--- a/emulator/opengl/host/libs/GLESv1_dec/GLDecoder.cpp
+++ b/emulator/opengl/host/libs/GLESv1_dec/GLDecoder.cpp
@@ -21,6 +21,10 @@
#include <GLES/gl.h>
#include <GLES/glext.h>
+static inline void* SafePointerFromUInt(GLuint value) {
+ return (void*)(uintptr_t)value;
+}
+
GLDecoder::GLDecoder()
{
m_contextData = NULL;
@@ -88,43 +92,43 @@ int GLDecoder::s_glFinishRoundTrip(void *self)
void GLDecoder::s_glVertexPointerOffset(void *self, GLint size, GLenum type, GLsizei stride, GLuint offset)
{
GLDecoder *ctx = (GLDecoder *)self;
- ctx->glVertexPointer(size, type, stride, (void *)offset);
+ ctx->glVertexPointer(size, type, stride, SafePointerFromUInt(offset));
}
void GLDecoder::s_glColorPointerOffset(void *self, GLint size, GLenum type, GLsizei stride, GLuint offset)
{
GLDecoder *ctx = (GLDecoder *)self;
- ctx->glColorPointer(size, type, stride, (void *)offset);
+ ctx->glColorPointer(size, type, stride, SafePointerFromUInt(offset));
}
void GLDecoder::s_glTexCoordPointerOffset(void *self, GLint size, GLenum type, GLsizei stride, GLuint offset)
{
GLDecoder *ctx = (GLDecoder *)self;
- ctx->glTexCoordPointer(size, type, stride, (void *) offset);
+ ctx->glTexCoordPointer(size, type, stride, SafePointerFromUInt(offset));
}
void GLDecoder::s_glNormalPointerOffset(void *self, GLenum type, GLsizei stride, GLuint offset)
{
GLDecoder *ctx = (GLDecoder *)self;
- ctx->glNormalPointer(type, stride, (void *)offset);
+ ctx->glNormalPointer(type, stride, SafePointerFromUInt(offset));
}
void GLDecoder::s_glPointSizePointerOffset(void *self, GLenum type, GLsizei stride, GLuint offset)
{
GLDecoder *ctx = (GLDecoder *)self;
- ctx->glPointSizePointerOES(type, stride, (void *)offset);
+ ctx->glPointSizePointerOES(type, stride, SafePointerFromUInt(offset));
}
void GLDecoder::s_glWeightPointerOffset(void * self, GLint size, GLenum type, GLsizei stride, GLuint offset)
{
GLDecoder *ctx = (GLDecoder *)self;
- ctx->glWeightPointerOES(size, type, stride, (void*)offset);
+ ctx->glWeightPointerOES(size, type, stride, SafePointerFromUInt(offset));
}
void GLDecoder::s_glMatrixIndexPointerOffset(void * self, GLint size, GLenum type, GLsizei stride, GLuint offset)
{
GLDecoder *ctx = (GLDecoder *)self;
- ctx->glMatrixIndexPointerOES(size, type, stride, (void*)offset);
+ ctx->glMatrixIndexPointerOES(size, type, stride, SafePointerFromUInt(offset));
}
@@ -204,7 +208,7 @@ void GLDecoder::s_glMatrixIndexPointerData(void * self, GLint size, GLenum type,
void GLDecoder::s_glDrawElementsOffset(void *self, GLenum mode, GLsizei count, GLenum type, GLuint offset)
{
GLDecoder *ctx = (GLDecoder *)self;
- ctx->glDrawElements(mode, count, type, (void *)offset);
+ ctx->glDrawElements(mode, count, type, SafePointerFromUInt(offset));
}
void GLDecoder::s_glDrawElementsData(void *self, GLenum mode, GLsizei count, GLenum type, void * data, GLuint datalen)
diff --git a/emulator/opengl/host/libs/GLESv2_dec/Android.mk b/emulator/opengl/host/libs/GLESv2_dec/Android.mk
index 7a034ec..bc04c25 100644
--- a/emulator/opengl/host/libs/GLESv2_dec/Android.mk
+++ b/emulator/opengl/host/libs/GLESv2_dec/Android.mk
@@ -22,15 +22,17 @@ LOCAL_SRC_FILES := GL2Decoder.cpp
$(call emugl-end-module)
### host library, 64-bit ####################################
-$(call emugl-begin-host-static-library,lib64GLESv2_dec)
-$(call emugl-import, lib64OpenglCodecCommon lib64OpenglOsUtils)
-$(call emugl-gen-decoder,$(LOCAL_PATH),gl2)
+ifdef EMUGL_BUILD_64BITS
+ $(call emugl-begin-host64-static-library,lib64GLESv2_dec)
+ $(call emugl-import, lib64OpenglCodecCommon lib64OpenglOsUtils)
+ $(call emugl-gen-decoder,$(LOCAL_PATH),gl2)
-# For gl2_types.h !
-$(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
+ # For gl2_types.h !
+ $(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
-$(call emugl-export,CFLAGS,$(host_common_debug_CFLAGS) -m64)
+ $(call emugl-export,CFLAGS,$(host_common_debug_CFLAGS) -m64)
-LOCAL_SRC_FILES := GL2Decoder.cpp
+ LOCAL_SRC_FILES := GL2Decoder.cpp
-$(call emugl-end-module)
+ $(call emugl-end-module)
+endif \ No newline at end of file
diff --git a/emulator/opengl/host/libs/GLESv2_dec/GL2Decoder.cpp b/emulator/opengl/host/libs/GLESv2_dec/GL2Decoder.cpp
index a777c50..ccf2f06 100644
--- a/emulator/opengl/host/libs/GLESv2_dec/GL2Decoder.cpp
+++ b/emulator/opengl/host/libs/GLESv2_dec/GL2Decoder.cpp
@@ -19,6 +19,9 @@
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
+static inline void* SafePointerFromUInt(GLuint value) {
+ return (void*)(uintptr_t)value;
+}
GL2Decoder::GL2Decoder()
{
@@ -115,7 +118,7 @@ void GL2Decoder::s_glVertexAttribPointerOffset(void *self, GLuint indx, GLint si
GLboolean normalized, GLsizei stride, GLuint data)
{
GL2Decoder *ctx = (GL2Decoder *) self;
- ctx->glVertexAttribPointer(indx, size, type, normalized, stride, (GLvoid *)data);
+ ctx->glVertexAttribPointer(indx, size, type, normalized, stride, SafePointerFromUInt(data));
}
@@ -129,7 +132,7 @@ void GL2Decoder::s_glDrawElementsData(void *self, GLenum mode, GLsizei count, GL
void GL2Decoder::s_glDrawElementsOffset(void *self, GLenum mode, GLsizei count, GLenum type, GLuint offset)
{
GL2Decoder *ctx = (GL2Decoder *)self;
- ctx->glDrawElements(mode, count, type, (void *)offset);
+ ctx->glDrawElements(mode, count, type, SafePointerFromUInt(offset));
}
void GL2Decoder::s_glShaderString(void *self, GLuint shader, const GLchar* string, GLsizei len)
diff --git a/emulator/opengl/host/libs/Translator/EGL/Android.mk b/emulator/opengl/host/libs/Translator/EGL/Android.mk
index f1a6d3a..5d1c9b2 100644
--- a/emulator/opengl/host/libs/Translator/EGL/Android.mk
+++ b/emulator/opengl/host/libs/Translator/EGL/Android.mk
@@ -47,11 +47,12 @@ LOCAL_SRC_FILES := $(host_common_SRC_FILES)
$(call emugl-end-module)
### EGL host implementation, 64-bit ########################
-$(call emugl-begin-host-shared-library,lib64EGL_translator)
-$(call emugl-import,lib64GLcommon)
+ifdef EMUGL_BUILD_64BITS
+ $(call emugl-begin-host64-shared-library,lib64EGL_translator)
+ $(call emugl-import,lib64GLcommon)
-LOCAL_LDLIBS += $(host_common_LDLIBS) -m64
-LOCAL_SRC_FILES := $(host_common_SRC_FILES)
-
-$(call emugl-end-module)
+ LOCAL_LDLIBS += $(host_common_LDLIBS) -m64
+ LOCAL_SRC_FILES := $(host_common_SRC_FILES)
+ $(call emugl-end-module)
+endif
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.cpp b/emulator/opengl/host/libs/Translator/EGL/EglDisplay.cpp
index 99f9d8b..24b9a0d 100644
--- a/emulator/opengl/host/libs/Translator/EGL/EglDisplay.cpp
+++ b/emulator/opengl/host/libs/Translator/EGL/EglDisplay.cpp
@@ -16,7 +16,6 @@
#include "EglDisplay.h"
#include "EglOsApi.h"
#include <GLcommon/GLutils.h>
-#include <utils/threads.h>
EglDisplay::EglDisplay(EGLNativeInternalDisplayType dpy,bool isDefault) :
m_dpy(dpy),
@@ -31,7 +30,7 @@ EglDisplay::EglDisplay(EGLNativeInternalDisplayType dpy,bool isDefault) :
};
EglDisplay::~EglDisplay() {
- android::Mutex::Autolock mutex(m_lock);
+ emugl::Mutex::AutoLock mutex(m_lock);
//
// Destroy the global context if one was created.
@@ -59,7 +58,7 @@ EglDisplay::~EglDisplay() {
EGLNativeInternalDisplayType EglDisplay::nativeType(){return m_dpy;}
void EglDisplay::initialize(int renderableType) {
- android::Mutex::Autolock mutex(m_lock);
+ emugl::Mutex::AutoLock mutex(m_lock);
m_initialized = true;
initConfigurations(renderableType);
m_configInitialized = true;
@@ -68,7 +67,7 @@ void EglDisplay::initialize(int renderableType) {
bool EglDisplay::isInitialize() { return m_initialized;}
void EglDisplay::terminate(){
- android::Mutex::Autolock mutex(m_lock);
+ emugl::Mutex::AutoLock mutex(m_lock);
m_contexts.clear();
m_surfaces.clear();
m_initialized = false;
@@ -128,7 +127,7 @@ void EglDisplay::initConfigurations(int renderableType) {
}
EglConfig* EglDisplay::getConfig(EGLConfig conf) {
- android::Mutex::Autolock mutex(m_lock);
+ emugl::Mutex::AutoLock mutex(m_lock);
for(ConfigsList::iterator it = m_configs.begin(); it != m_configs.end() ;it++) {
if(static_cast<EGLConfig>(*it) == conf) {
@@ -140,9 +139,9 @@ EglConfig* EglDisplay::getConfig(EGLConfig conf) {
}
SurfacePtr EglDisplay::getSurface(EGLSurface surface) {
- android::Mutex::Autolock mutex(m_lock);
+ emugl::Mutex::AutoLock mutex(m_lock);
/* surface is "key" in map<unsigned int, SurfacePtr>. */
- unsigned int hndl = ToTargetCompatibleHandle((uintptr_t)surface);
+ unsigned int hndl = SafeUIntFromPointer(surface);
SurfacesHndlMap::iterator it = m_surfaces.find(hndl);
return it != m_surfaces.end() ?
(*it).second :
@@ -150,9 +149,9 @@ SurfacePtr EglDisplay::getSurface(EGLSurface surface) {
}
ContextPtr EglDisplay::getContext(EGLContext ctx) {
- android::Mutex::Autolock mutex(m_lock);
+ emugl::Mutex::AutoLock mutex(m_lock);
/* ctx is "key" in map<unsigned int, ContextPtr>. */
- unsigned int hndl = ToTargetCompatibleHandle((uintptr_t)ctx);
+ unsigned int hndl = SafeUIntFromPointer(ctx);
ContextsHndlMap::iterator it = m_contexts.find(hndl);
return it != m_contexts.end() ?
(*it).second :
@@ -160,9 +159,9 @@ ContextPtr EglDisplay::getContext(EGLContext ctx) {
}
bool EglDisplay::removeSurface(EGLSurface s) {
- android::Mutex::Autolock mutex(m_lock);
+ emugl::Mutex::AutoLock mutex(m_lock);
/* s is "key" in map<unsigned int, SurfacePtr>. */
- unsigned int hndl = ToTargetCompatibleHandle((uintptr_t)s);
+ unsigned int hndl = SafeUIntFromPointer(s);
SurfacesHndlMap::iterator it = m_surfaces.find(hndl);
if(it != m_surfaces.end()) {
m_surfaces.erase(it);
@@ -172,7 +171,7 @@ bool EglDisplay::removeSurface(EGLSurface s) {
}
bool EglDisplay::removeSurface(SurfacePtr s) {
- android::Mutex::Autolock mutex(m_lock);
+ emugl::Mutex::AutoLock mutex(m_lock);
SurfacesHndlMap::iterator it;
for(it = m_surfaces.begin(); it!= m_surfaces.end();it++)
@@ -189,9 +188,9 @@ bool EglDisplay::removeSurface(SurfacePtr s) {
}
bool EglDisplay::removeContext(EGLContext ctx) {
- android::Mutex::Autolock mutex(m_lock);
+ emugl::Mutex::AutoLock mutex(m_lock);
/* ctx is "key" in map<unsigned int, ContextPtr>. */
- unsigned int hndl = ToTargetCompatibleHandle((uintptr_t)ctx);
+ unsigned int hndl = SafeUIntFromPointer(ctx);
ContextsHndlMap::iterator it = m_contexts.find(hndl);
if(it != m_contexts.end()) {
m_contexts.erase(it);
@@ -201,7 +200,7 @@ bool EglDisplay::removeContext(EGLContext ctx) {
}
bool EglDisplay::removeContext(ContextPtr ctx) {
- android::Mutex::Autolock mutex(m_lock);
+ emugl::Mutex::AutoLock mutex(m_lock);
ContextsHndlMap::iterator it;
for(it = m_contexts.begin(); it != m_contexts.end();it++) {
@@ -217,7 +216,7 @@ bool EglDisplay::removeContext(ContextPtr ctx) {
}
EglConfig* EglDisplay::getConfig(EGLint id) {
- android::Mutex::Autolock mutex(m_lock);
+ emugl::Mutex::AutoLock mutex(m_lock);
for(ConfigsList::iterator it = m_configs.begin(); it != m_configs.end() ;it++) {
if((*it)->id() == id) {
@@ -229,7 +228,7 @@ EglConfig* EglDisplay::getConfig(EGLint id) {
}
int EglDisplay::getConfigs(EGLConfig* configs,int config_size) {
- android::Mutex::Autolock mutex(m_lock);
+ emugl::Mutex::AutoLock mutex(m_lock);
int i = 0;
for(ConfigsList::iterator it = m_configs.begin(); it != m_configs.end() && i < config_size ;i++,it++) {
configs[i] = static_cast<EGLConfig>(*it);
@@ -238,7 +237,7 @@ int EglDisplay::getConfigs(EGLConfig* configs,int config_size) {
}
int EglDisplay::chooseConfigs(const EglConfig& dummy,EGLConfig* configs,int config_size) {
- android::Mutex::Autolock mutex(m_lock);
+ emugl::Mutex::AutoLock mutex(m_lock);
return doChooseConfigs(dummy, configs, config_size);
}
@@ -258,7 +257,7 @@ int EglDisplay::doChooseConfigs(const EglConfig& dummy,EGLConfig* configs,int co
}
EGLSurface EglDisplay::addSurface(SurfacePtr s ) {
- android::Mutex::Autolock mutex(m_lock);
+ emugl::Mutex::AutoLock mutex(m_lock);
unsigned int hndl = s.Ptr()->getHndl();
EGLSurface ret =reinterpret_cast<EGLSurface> (hndl);
@@ -271,7 +270,7 @@ EGLSurface EglDisplay::addSurface(SurfacePtr s ) {
}
EGLContext EglDisplay::addContext(ContextPtr ctx ) {
- android::Mutex::Autolock mutex(m_lock);
+ emugl::Mutex::AutoLock mutex(m_lock);
unsigned int hndl = ctx.Ptr()->getHndl();
EGLContext ret = reinterpret_cast<EGLContext> (hndl);
@@ -285,7 +284,7 @@ EGLContext EglDisplay::addContext(ContextPtr ctx ) {
EGLImageKHR EglDisplay::addImageKHR(ImagePtr img) {
- android::Mutex::Autolock mutex(m_lock);
+ emugl::Mutex::AutoLock mutex(m_lock);
do { ++m_nextEglImageId; } while(m_nextEglImageId == 0);
img->imageId = m_nextEglImageId;
m_eglImages[m_nextEglImageId] = img;
@@ -293,17 +292,17 @@ EGLImageKHR EglDisplay::addImageKHR(ImagePtr img) {
}
ImagePtr EglDisplay::getImage(EGLImageKHR img) {
- android::Mutex::Autolock mutex(m_lock);
+ emugl::Mutex::AutoLock mutex(m_lock);
/* img is "key" in map<unsigned int, ImagePtr>. */
- unsigned int hndl = ToTargetCompatibleHandle((uintptr_t)img);
+ unsigned int hndl = SafeUIntFromPointer(img);
ImagesHndlMap::iterator i( m_eglImages.find(hndl) );
return (i != m_eglImages.end()) ? (*i).second :ImagePtr(NULL);
}
bool EglDisplay:: destroyImageKHR(EGLImageKHR img) {
- android::Mutex::Autolock mutex(m_lock);
+ emugl::Mutex::AutoLock mutex(m_lock);
/* img is "key" in map<unsigned int, ImagePtr>. */
- unsigned int hndl = ToTargetCompatibleHandle((uintptr_t)img);
+ unsigned int hndl = SafeUIntFromPointer(img);
ImagesHndlMap::iterator i( m_eglImages.find(hndl) );
if (i != m_eglImages.end())
{
@@ -314,7 +313,7 @@ bool EglDisplay:: destroyImageKHR(EGLImageKHR img) {
}
EGLNativeContextType EglDisplay::getGlobalSharedContext(){
- android::Mutex::Autolock mutex(m_lock);
+ emugl::Mutex::AutoLock mutex(m_lock);
#ifndef _WIN32
// find an existing OpenGL context to share with, if exist
EGLNativeContextType ret =
diff --git a/emulator/opengl/host/libs/Translator/EGL/EglDisplay.h b/emulator/opengl/host/libs/Translator/EGL/EglDisplay.h
index 587e92a..47a2598 100644
--- a/emulator/opengl/host/libs/Translator/EGL/EglDisplay.h
+++ b/emulator/opengl/host/libs/Translator/EGL/EglDisplay.h
@@ -20,8 +20,8 @@
#include <map>
#include <EGL/egl.h>
#include <EGL/eglext.h>
-#include <utils/threads.h>
-#include <GLcommon/SmartPtr.h>
+#include "emugl/common/mutex.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;
@@ -81,7 +82,7 @@ private:
SurfacesHndlMap m_surfaces;
GlobalNameSpace m_globalNameSpace;
ObjectNameManager *m_manager[MAX_GLES_VERSION];
- android::Mutex m_lock;
+ emugl::Mutex m_lock;
ImagesHndlMap m_eglImages;
unsigned int m_nextEglImageId;
EGLNativeContextType m_globalSharedContext;
diff --git a/emulator/opengl/host/libs/Translator/EGL/EglGlobalInfo.cpp b/emulator/opengl/host/libs/Translator/EGL/EglGlobalInfo.cpp
index 8e5b462..95b696e 100644
--- a/emulator/opengl/host/libs/Translator/EGL/EglGlobalInfo.cpp
+++ b/emulator/opengl/host/libs/Translator/EGL/EglGlobalInfo.cpp
@@ -51,7 +51,7 @@ void EglGlobalInfo::delInstance() {
EglDisplay* EglGlobalInfo::addDisplay(EGLNativeDisplayType dpy,EGLNativeInternalDisplayType idpy) {
//search if it is not already exists
- android::Mutex::Autolock mutex(m_lock);
+ emugl::Mutex::AutoLock mutex(m_lock);
for(DisplaysMap::iterator it = m_displays.begin(); it != m_displays.end() ;it++) {
if((*it).second == dpy) return (*it).first;
}
@@ -68,7 +68,7 @@ EglDisplay* EglGlobalInfo::addDisplay(EGLNativeDisplayType dpy,EGLNativeInternal
}
bool EglGlobalInfo::removeDisplay(EGLDisplay dpy) {
- android::Mutex::Autolock mutex(m_lock);
+ emugl::Mutex::AutoLock mutex(m_lock);
for(DisplaysMap::iterator it = m_displays.begin(); it != m_displays.end() ;it++) {
if(static_cast<EGLDisplay>((*it).first) == dpy) {
delete (*it).first;
@@ -80,7 +80,7 @@ bool EglGlobalInfo::removeDisplay(EGLDisplay dpy) {
}
EglDisplay* EglGlobalInfo::getDisplay(EGLNativeDisplayType dpy) {
- android::Mutex::Autolock mutex(m_lock);
+ emugl::Mutex::AutoLock mutex(m_lock);
for(DisplaysMap::iterator it = m_displays.begin(); it != m_displays.end() ;it++) {
if((*it).second == dpy) return (*it).first;
}
@@ -88,7 +88,7 @@ EglDisplay* EglGlobalInfo::getDisplay(EGLNativeDisplayType dpy) {
}
EglDisplay* EglGlobalInfo::getDisplay(EGLDisplay dpy) {
- android::Mutex::Autolock mutex(m_lock);
+ emugl::Mutex::AutoLock mutex(m_lock);
DisplaysMap::iterator it = m_displays.find(static_cast<EglDisplay*>(dpy));
return (it != m_displays.end() ? (*it).first : NULL);
}
@@ -99,7 +99,7 @@ EGLNativeInternalDisplayType EglGlobalInfo::generateInternalDisplay(EGLNativeDis
void EglGlobalInfo::initClientExtFuncTable(GLESVersion ver)
{
- android::Mutex::Autolock mutex(m_lock);
+ emugl::Mutex::AutoLock mutex(m_lock);
if (!m_gles_extFuncs_inited[ver]) {
ClientAPIExts::initClientFuncs(m_gles_ifaces[ver], (int)ver - 1);
m_gles_extFuncs_inited[ver] = true;
diff --git a/emulator/opengl/host/libs/Translator/EGL/EglGlobalInfo.h b/emulator/opengl/host/libs/Translator/EGL/EglGlobalInfo.h
index ec07ffe..f56b79e 100644
--- a/emulator/opengl/host/libs/Translator/EGL/EglGlobalInfo.h
+++ b/emulator/opengl/host/libs/Translator/EGL/EglGlobalInfo.h
@@ -16,14 +16,15 @@
#ifndef EGL_GLOBAL_INFO
#define EGL_GLOBAL_INFO
-#include <list>
-#include <EGL/egl.h>
-#include <utils/threads.h>
-#include <GLcommon/TranslatorIfaces.h>
#include "EglDisplay.h"
#include "EglConfig.h"
#include "EglContext.h"
+#include <GLcommon/TranslatorIfaces.h>
+#include "emugl/common/mutex.h"
+#include <list>
+#include <EGL/egl.h>
+
typedef std::map<EglDisplay*,EGLNativeDisplayType>DisplaysMap;
@@ -58,7 +59,7 @@ private:
EGLNativeInternalDisplayType m_default;
GLESiface* m_gles_ifaces[MAX_GLES_VERSION];
bool m_gles_extFuncs_inited[MAX_GLES_VERSION];
- android::Mutex m_lock;
+ emugl::Mutex m_lock;
};
#endif
diff --git a/emulator/opengl/host/libs/Translator/EGL/EglImp.cpp b/emulator/opengl/host/libs/Translator/EGL/EglImp.cpp
index d03c9db..06dcf67 100644
--- a/emulator/opengl/host/libs/Translator/EGL/EglImp.cpp
+++ b/emulator/opengl/host/libs/Translator/EGL/EglImp.cpp
@@ -50,11 +50,11 @@ GLEScontext* getGLESContext();
#define tls_thread EglThreadInfo::get()
EglGlobalInfo* g_eglInfo = NULL;
-android::Mutex s_eglLock;
+emugl::Mutex s_eglLock;
void initGlobalInfo()
{
- android::Mutex::Autolock mutex(s_eglLock);
+ emugl::Mutex::AutoLock mutex(s_eglLock);
if (!g_eglInfo) {
g_eglInfo = EglGlobalInfo::getInstance();
}
@@ -72,8 +72,8 @@ static EGLiface s_eglIface = {
#define EGL_EXTENTIONS 2
//decleration
-EGLImageKHR eglCreateImageKHR(EGLDisplay display, EGLContext context, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
-EGLBoolean eglDestroyImageKHR(EGLDisplay display, EGLImageKHR image);
+EGLAPI EGLImageKHR EGLAPIENTRY eglCreateImageKHR(EGLDisplay display, EGLContext context, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImageKHR(EGLDisplay display, EGLImageKHR image);
// extentions descriptors
static ExtentionDescriptor s_eglExtentions[] = {
@@ -273,28 +273,31 @@ EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay display, const EGLint *
}
//selection defaults
+ // NOTE: Some variables below are commented out to reduce compiler warnings.
+ // TODO(digit): Look if these variables are really needed or not, and if so
+ // fix the code to do it properly.
EGLint surface_type = EGL_WINDOW_BIT;
EGLint renderable_type = EGL_OPENGL_ES_BIT;
- EGLBoolean bind_to_tex_rgb = EGL_DONT_CARE;
- EGLBoolean bind_to_tex_rgba = EGL_DONT_CARE;
+ //EGLBoolean bind_to_tex_rgb = EGL_DONT_CARE;
+ //EGLBoolean bind_to_tex_rgba = EGL_DONT_CARE;
EGLenum caveat = EGL_DONT_CARE;
EGLint config_id = EGL_DONT_CARE;
EGLBoolean native_renderable = EGL_DONT_CARE;
EGLint native_visual_type = EGL_DONT_CARE;
- EGLint max_swap_interval = EGL_DONT_CARE;
- EGLint min_swap_interval = EGL_DONT_CARE;
+ //EGLint max_swap_interval = EGL_DONT_CARE;
+ //EGLint min_swap_interval = EGL_DONT_CARE;
EGLint trans_red_val = EGL_DONT_CARE;
EGLint trans_green_val = EGL_DONT_CARE;
EGLint trans_blue_val = EGL_DONT_CARE;
EGLenum transparent_type = EGL_NONE;
- EGLint buffer_size = 0;
+ //EGLint buffer_size = 0;
EGLint red_size = 0;
EGLint green_size = 0;
EGLint blue_size = 0;
EGLint alpha_size = 0;
EGLint depth_size = 0;
EGLint frame_buffer_level = 0;
- EGLint sample_buffers_num = 0;
+ //EGLint sample_buffers_num = 0;
EGLint samples_per_pixel = 0;
EGLint stencil_size = 0;
@@ -318,7 +321,7 @@ EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay display, const EGLint *
if(attrib_list[i+1] < 0) {
RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
}
- buffer_size = attrib_list[i+1];
+ //buffer_size = attrib_list[i+1];
break;
case EGL_RED_SIZE:
if(attrib_list[i+1] < 0) {
@@ -345,10 +348,10 @@ EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay display, const EGLint *
alpha_size = attrib_list[i+1];
break;
case EGL_BIND_TO_TEXTURE_RGB:
- bind_to_tex_rgb = attrib_list[i+1];
+ //bind_to_tex_rgb = attrib_list[i+1];
break;
case EGL_BIND_TO_TEXTURE_RGBA:
- bind_to_tex_rgba = attrib_list[i+1];
+ //bind_to_tex_rgba = attrib_list[i+1];
break;
case EGL_CONFIG_CAVEAT:
if(attrib_list[i+1] != EGL_NONE && attrib_list[i+1] != EGL_SLOW_CONFIG && attrib_list[i+1] != EGL_NON_CONFORMANT_CONFIG) {
@@ -373,13 +376,13 @@ EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay display, const EGLint *
if(attrib_list[i+1] < 0) {
RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
}
- max_swap_interval = attrib_list[i+1];
+ //max_swap_interval = attrib_list[i+1];
break;
case EGL_MIN_SWAP_INTERVAL:
if(attrib_list[i+1] < 0) {
RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
}
- min_swap_interval = attrib_list[i+1];
+ //min_swap_interval = attrib_list[i+1];
break;
case EGL_NATIVE_RENDERABLE:
native_renderable = attrib_list[i+1];
@@ -394,7 +397,7 @@ EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay display, const EGLint *
RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
}
case EGL_SAMPLE_BUFFERS:
- sample_buffers_num = attrib_list[i+1];
+ //sample_buffers_num = attrib_list[i+1];
break;
if(attrib_list[i+1] < 0) {
RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
@@ -635,13 +638,11 @@ EGLAPI EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay display, EGLConfig con
}
ContextPtr sharedCtxPtr;
- EGLNativeContextType nativeShared = NULL;
if(share_context != EGL_NO_CONTEXT) {
sharedCtxPtr = dpy->getContext(share_context);
if(!sharedCtxPtr.Ptr()) {
RETURN_ERROR(EGL_NO_CONTEXT,EGL_BAD_CONTEXT);
}
- nativeShared = sharedCtxPtr->nativeType();
}
EGLNativeContextType globalSharedContext = dpy->getGlobalSharedContext();
@@ -815,7 +816,7 @@ EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext(void) {
if(dpy && ctx.Ptr()){
// This double check is required because a context might still be current after it is destroyed - in which case
// its handle should be invalid, that is EGL_NO_CONTEXT should be returned even though the context is current
- EGLContext c = (EGLContext)ctx->getHndl();
+ EGLContext c = (EGLContext)SafePointerFromUInt(ctx->getHndl());
if(dpy->getContext(c).Ptr())
{
return c;
@@ -839,7 +840,7 @@ EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface(EGLint readdraw) {
// current after it is destroyed - in which case its handle should
// be invalid, that is EGL_NO_SURFACE should be returned even
// though the surface is current.
- EGLSurface s = (EGLSurface)surface->getHndl();
+ EGLSurface s = (EGLSurface)SafePointerFromUInt(surface->getHndl());
surface = dpy->getSurface(s);
if(surface.Ptr())
{
@@ -858,7 +859,9 @@ EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay(void) {
EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL(void) {
EGLenum api = eglQueryAPI();
eglBindAPI(EGL_OPENGL_ES_API);
- return eglWaitClient();
+ EGLBoolean ret = eglWaitClient();
+ eglBindAPI(api);
+ return ret;
}
EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative(EGLint engine) {
@@ -1012,7 +1015,6 @@ EglImage *attachEGLImage(unsigned int imageId)
void detachEGLImage(unsigned int imageId)
{
ThreadInfo* thread = getThreadInfo();
- EglDisplay* dpy = static_cast<EglDisplay*>(thread->eglDisplay);
ContextPtr ctx = thread->eglContext;
if (ctx.Ptr()) {
ctx->detachImage(imageId);
@@ -1020,7 +1022,7 @@ void detachEGLImage(unsigned int imageId)
}
-EGLImageKHR eglCreateImageKHR(EGLDisplay display, EGLContext context, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)
+EGLAPI EGLImageKHR EGLAPIENTRY eglCreateImageKHR(EGLDisplay display, EGLContext context, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)
{
VALIDATE_DISPLAY(display);
VALIDATE_CONTEXT(context);
@@ -1033,13 +1035,13 @@ EGLImageKHR eglCreateImageKHR(EGLDisplay display, EGLContext context, EGLenum ta
ThreadInfo* thread = getThreadInfo();
ShareGroupPtr sg = thread->shareGroup;
if (sg.Ptr() != NULL) {
- unsigned int globalTexName = sg->getGlobalName(TEXTURE, (uintptr_t)buffer);
+ unsigned int globalTexName = sg->getGlobalName(TEXTURE, SafeUIntFromPointer(buffer));
if (!globalTexName) return EGL_NO_IMAGE_KHR;
ImagePtr img( new EglImage() );
if (img.Ptr() != NULL) {
- ObjectDataPtr objData = sg->getObjectData(TEXTURE, (uintptr_t)buffer);
+ ObjectDataPtr objData = sg->getObjectData(TEXTURE, SafeUIntFromPointer(buffer));
if (!objData.Ptr()) return EGL_NO_IMAGE_KHR;
TextureData *texData = (TextureData *)objData.Ptr();
@@ -1057,7 +1059,7 @@ EGLImageKHR eglCreateImageKHR(EGLDisplay display, EGLContext context, EGLenum ta
}
-EGLBoolean eglDestroyImageKHR(EGLDisplay display, EGLImageKHR image)
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImageKHR(EGLDisplay display, EGLImageKHR image)
{
VALIDATE_DISPLAY(display);
return dpy->destroyImageKHR(image) ? EGL_TRUE:EGL_FALSE;
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/EGL/EglThreadInfo.cpp b/emulator/opengl/host/libs/Translator/EGL/EglThreadInfo.cpp
index 1b403f2..6481774 100644
--- a/emulator/opengl/host/libs/Translator/EGL/EglThreadInfo.cpp
+++ b/emulator/opengl/host/libs/Translator/EGL/EglThreadInfo.cpp
@@ -16,26 +16,33 @@
#include "EglThreadInfo.h"
#include "EglOsApi.h"
-EglThreadInfo::EglThreadInfo():m_err(EGL_SUCCESS),m_api(EGL_OPENGL_ES_API) {}
+#include "emugl/common/lazy_instance.h"
+#include "emugl/common/thread_store.h"
-#include <cutils/threads.h>
+namespace {
-static thread_store_t s_tls = THREAD_STORE_INITIALIZER;
-
-static void tlsDestruct(void *ptr)
-{
- if (ptr) {
- EglThreadInfo *ti = (EglThreadInfo *)ptr;
- delete ti;
+class EglThreadInfoStore : public emugl::ThreadStore {
+public:
+ EglThreadInfoStore() : emugl::ThreadStore(&destructor) {}
+private:
+ static void destructor(void* value) {
+ delete static_cast<EglThreadInfo*>(value);
}
-}
+};
+
+} // namespace
+
+EglThreadInfo::EglThreadInfo() :
+ m_err(EGL_SUCCESS), m_api(EGL_OPENGL_ES_API) {}
+
+static emugl::LazyInstance<EglThreadInfoStore> s_tls = LAZY_INSTANCE_INIT;
EglThreadInfo* EglThreadInfo::get(void)
{
- EglThreadInfo *ti = (EglThreadInfo *)thread_store_get(&s_tls);
+ EglThreadInfo *ti = static_cast<EglThreadInfo*>(s_tls->get());
if (!ti) {
ti = new EglThreadInfo();
- thread_store_set(&s_tls, ti, tlsDestruct);
+ s_tls->set(ti);
}
return ti;
}
diff --git a/emulator/opengl/host/libs/Translator/EGL/EglWindowsApi.cpp b/emulator/opengl/host/libs/Translator/EGL/EglWindowsApi.cpp
index 460c0b6..5b48fcb 100644
--- a/emulator/opengl/host/libs/Translator/EGL/EglWindowsApi.cpp
+++ b/emulator/opengl/host/libs/Translator/EGL/EglWindowsApi.cpp
@@ -20,8 +20,7 @@
#include <stdio.h>
#define IS_TRUE(a) \
- if(a != true) return false;
-
+ if(a != true) return NULL;
struct DisplayInfo{
DisplayInfo():dc(NULL),hwnd(NULL),isPixelFormatSet(false){};
@@ -48,9 +47,7 @@ static TlsData *getTLS() {
class WinDisplay{
public:
- typedef enum {
- DEFAULT_DISPLAY = 0
- };
+ enum { DEFAULT_DISPLAY = 0 };
WinDisplay(){};
DisplayInfo& getInfo(int configurationIndex){ return getTLS()->m_map[configurationIndex];}
HDC getDC(int configId){return getTLS()->m_map[configId].dc;}
@@ -193,7 +190,8 @@ HWND createDummyWindow(){
wcx.lpszClassName = "DummyWin"; // name of window class
wcx.hIconSm = (HICON) NULL; // small class icon
- ATOM winClass = RegisterClassEx(&wcx);
+ RegisterClassEx(&wcx);
+
HWND hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,
"DummyWin",
"Dummy",
@@ -340,7 +338,7 @@ EglConfig* pixelFormatToConfig(EGLNativeInternalDisplayType display,int renderab
EGLint transparentType,samples;
EGLint tRed,tGreen,tBlue;
EGLint pMaxWidth,pMaxHeight,pMaxPixels;
- EGLint configId,level;
+ EGLint level;
EGLint window,bitmap,pbuffer,transparent;
HDC dpy = getDummyDC(display,WinDisplay::DEFAULT_DISPLAY);
@@ -416,10 +414,10 @@ void queryConfigs(EGLNativeInternalDisplayType display,int renderableType,Config
initPixelFormat(dpy);
//quering num of formats
- int nFormats = DescribePixelFormat(dpy, iPixelFormat,sizeof(PIXELFORMATDESCRIPTOR), &pfd);
+ int maxFormat = DescribePixelFormat(dpy, iPixelFormat,sizeof(PIXELFORMATDESCRIPTOR), &pfd);
//inserting rest of formats
- for(iPixelFormat;iPixelFormat < nFormats; iPixelFormat++) {
+ for(;iPixelFormat <= maxFormat; iPixelFormat++) {
DescribePixelFormat(dpy, iPixelFormat,sizeof(PIXELFORMATDESCRIPTOR), &pfd);
EglConfig* pConfig = pixelFormatToConfig(display,renderableType,&pfd,iPixelFormat);
if(pConfig) listOut.push_back(pConfig);
@@ -497,7 +495,7 @@ EGLNativeSurfaceType createPbufferSurface(EGLNativeInternalDisplayType display,E
if(!s_wglExtProcs->wglCreatePbufferARB) return NULL;
EGLNativePbufferType pb = s_wglExtProcs->wglCreatePbufferARB(dpy,cfg->nativeId(),width,height,pbAttribs);
if(!pb) {
- DWORD err = GetLastError();
+ GetLastError();
return NULL;
}
return new SrfcInfo(pb);
@@ -507,7 +505,7 @@ bool releasePbuffer(EGLNativeInternalDisplayType display,EGLNativeSurfaceType pb
if (!pb) return false;
if(!s_wglExtProcs->wglReleasePbufferDCARB || !s_wglExtProcs->wglDestroyPbufferARB) return false;
if(!s_wglExtProcs->wglReleasePbufferDCARB(pb->getPbuffer(),pb->getDC()) || !s_wglExtProcs->wglDestroyPbufferARB(pb->getPbuffer())){
- DWORD err = GetLastError();
+ GetLastError();
return false;
}
return true;
@@ -539,7 +537,7 @@ EGLNativeContextType createContext(EGLNativeInternalDisplayType display,EglConfi
bool destroyContext(EGLNativeInternalDisplayType dpy,EGLNativeContextType ctx) {
if(!wglDeleteContext(ctx)) {
- DWORD err = GetLastError();
+ GetLastError();
return false;
}
return true;
@@ -566,7 +564,7 @@ bool makeCurrent(EGLNativeInternalDisplayType display,EglSurface* read,EglSurfac
void swapBuffers(EGLNativeInternalDisplayType display,EGLNativeSurfaceType srfc){
if(srfc && !SwapBuffers(srfc->getDC())) {
- DWORD err = GetLastError();
+ GetLastError();
}
}
diff --git a/emulator/opengl/host/libs/Translator/EGL/EglX11Api.cpp b/emulator/opengl/host/libs/Translator/EGL/EglX11Api.cpp
index 129f244..41cf8c4 100644
--- a/emulator/opengl/host/libs/Translator/EGL/EglX11Api.cpp
+++ b/emulator/opengl/host/libs/Translator/EGL/EglX11Api.cpp
@@ -14,10 +14,11 @@
* limitations under the License.
*/
#include "EglOsApi.h"
+#include "emugl/common/mutex.h"
+
#include <string.h>
#include <X11/Xlib.h>
#include <GL/glx.h>
-#include <utils/threads.h>
class ErrorHandler{
@@ -29,7 +30,7 @@ int getLastError(){ return s_lastErrorCode;};
private:
static int s_lastErrorCode;
int (*m_oldErrorHandler) (Display *, XErrorEvent *);
-static android::Mutex s_lock;
+static emugl::Mutex s_lock;
static int errorHandlerProc(EGLNativeDisplayType dpy,XErrorEvent* event);
};
@@ -50,17 +51,17 @@ private:
};
int ErrorHandler::s_lastErrorCode = 0;
-android::Mutex ErrorHandler::s_lock;
+emugl::Mutex ErrorHandler::s_lock;
ErrorHandler::ErrorHandler(EGLNativeDisplayType dpy){
- android::Mutex::Autolock mutex(s_lock);
+ emugl::Mutex::AutoLock mutex(s_lock);
XSync(dpy,False);
s_lastErrorCode = 0;
m_oldErrorHandler = XSetErrorHandler(errorHandlerProc);
}
ErrorHandler::~ErrorHandler(){
- android::Mutex::Autolock mutex(s_lock);
+ emugl::Mutex::AutoLock mutex(s_lock);
XSetErrorHandler(m_oldErrorHandler);
s_lastErrorCode = 0;
}
@@ -71,7 +72,7 @@ int ErrorHandler::errorHandlerProc(EGLNativeDisplayType dpy,XErrorEvent* event){
}
#define IS_SUCCESS(a) \
- if(a != Success) return false;
+ if(a != Success) return 0;
namespace EglOS {
@@ -193,7 +194,7 @@ bool validNativePixmap(EGLNativeDisplayType dpy,EGLNativeSurfaceType pix) {
int tmp;
unsigned int utmp;
ErrorHandler handler(dpy);
- if(!XGetGeometry(dpy,pix ? pix->srfc() : NULL,&root,&tmp,&tmp,&utmp,&utmp,&utmp,&utmp)) return false;
+ if(!XGetGeometry(dpy,pix ? pix->srfc() : 0,&root,&tmp,&tmp,&utmp,&utmp,&utmp,&utmp)) return false;
return handler.getLastError() == 0;
}
@@ -260,7 +261,7 @@ bool makeCurrent(EGLNativeDisplayType dpy,EglSurface* read,EglSurface* draw,EGLN
bool retval = false;
if (!ctx && !read && !draw) {
// unbind
- retval = glXMakeContextCurrent(dpy, NULL, NULL, NULL);
+ retval = glXMakeContextCurrent(dpy, 0, 0, NULL);
}
else if (ctx && read && draw) {
retval = glXMakeContextCurrent(dpy,draw->native()->srfc(),read->native()->srfc(),ctx);
diff --git a/emulator/opengl/host/libs/Translator/EGL/ThreadInfo.cpp b/emulator/opengl/host/libs/Translator/EGL/ThreadInfo.cpp
index 4f5d75f..1571b3a 100644
--- a/emulator/opengl/host/libs/Translator/EGL/ThreadInfo.cpp
+++ b/emulator/opengl/host/libs/Translator/EGL/ThreadInfo.cpp
@@ -14,16 +14,47 @@
* limitations under the License.
*/
-#include <stdio.h>
#include "ThreadInfo.h"
-//#define TRACE_THREADINFO
-#ifdef TRACE_THREADINFO
+#include "emugl/common/lazy_instance.h"
+#include "emugl/common/thread_store.h"
+
+#include <stdio.h>
+
+// Set TRACE_THREADINFO to 1 to debug creation/destruction of ThreadInfo
+// instances.
+#define TRACE_THREADINFO 0
+
+#if TRACE_THREADINFO
#define LOG_THREADINFO(x...) fprintf(stderr, x)
#else
#define LOG_THREADINFO(x...)
#endif
+namespace {
+
+class ThreadInfoStore : public ::emugl::ThreadStore {
+public:
+ ThreadInfoStore() : ::emugl::ThreadStore(&destructor) {}
+
+ size_t getInstanceCount() const { return mNumInstances; }
+
+private:
+ static void destructor(void* value) {
+ LOG_THREADINFO("%s: EFL %p (%d instances)\n", __FUNCTION__,
+ value, mNumInstances);
+ delete static_cast<ThreadInfo*>(value);
+ mNumInstances--;
+ }
+
+ static size_t mNumInstances;
+};
+
+size_t ThreadInfoStore::mNumInstances = 0;
+
+} // namespace
+
+
void ThreadInfo::updateInfo(ContextPtr eglCtx,
EglDisplay* dpy,
GLEScontext* glesCtx,
@@ -37,27 +68,16 @@ void ThreadInfo::updateInfo(ContextPtr eglCtx,
objManager = manager;
}
-#include <cutils/threads.h>
-static thread_store_t s_tls = THREAD_STORE_INITIALIZER;
-static int active_instance = 0;
-static void tlsDestruct(void *ptr)
-{
- active_instance--;
- LOG_THREADINFO("tlsDestruct EGL %lx %d\n", (long)ptr, active_instance);
- if (ptr) {
- ThreadInfo *ti = (ThreadInfo *)ptr;
- delete ti;
- }
-}
+static ::emugl::LazyInstance<ThreadInfoStore> s_tls = LAZY_INSTANCE_INIT;
ThreadInfo *getThreadInfo()
{
- ThreadInfo *ti = (ThreadInfo *)thread_store_get(&s_tls);
+ ThreadInfo *ti = static_cast<ThreadInfo*>(s_tls->get());
if (!ti) {
ti = new ThreadInfo();
- thread_store_set(&s_tls, ti, tlsDestruct);
- active_instance++;
- LOG_THREADINFO("getThreadInfo EGL %lx %d\n", (long)ti, active_instance);
+ s_tls->set(ti);
+ LOG_THREADINFO("%s: EGL %p (%d instances)\n", __FUNCTION__,
+ ti, (int)ThreadInfoStore::getInstanceCount());
}
return ti;
}
diff --git a/emulator/opengl/host/libs/Translator/GLES_CM/Android.mk b/emulator/opengl/host/libs/Translator/GLES_CM/Android.mk
index 9aa74a7..c5e7e6d 100644
--- a/emulator/opengl/host/libs/Translator/GLES_CM/Android.mk
+++ b/emulator/opengl/host/libs/Translator/GLES_CM/Android.mk
@@ -18,11 +18,14 @@ $(call emugl-end-module)
### GLES_CM host implementation, 64-bit ########################
-$(call emugl-begin-host-shared-library,lib64GLES_CM_translator)
+ifdef EMUGL_BUILD_64BITS
+ $(call emugl-begin-host64-shared-library,lib64GLES_CM_translator)
-$(call emugl-import,lib64GLcommon)
+ $(call emugl-import,lib64GLcommon)
-LOCAL_LDLIBS += -m64
-LOCAL_SRC_FILES := $(host_common_SRC_FILES)
+ LOCAL_CFLAGS += -fPIC
+ LOCAL_LDLIBS += -m64
+ LOCAL_SRC_FILES := $(host_common_SRC_FILES)
-$(call emugl-end-module)
+ $(call emugl-end-module)
+endif \ No newline at end of file
diff --git a/emulator/opengl/host/libs/Translator/GLES_CM/GLDispatch.cpp b/emulator/opengl/host/libs/Translator/GLES_CM/GLDispatch.cpp
index af5c0d8..66adefb 100644
--- a/emulator/opengl/host/libs/Translator/GLES_CM/GLDispatch.cpp
+++ b/emulator/opengl/host/libs/Translator/GLES_CM/GLDispatch.cpp
@@ -51,7 +51,7 @@ GLDispatch::GLDispatch():m_isLoaded(false){};
void GLDispatch::dispatchFuncs() {
- android::Mutex::Autolock mutex(m_lock);
+ emugl::Mutex::AutoLock mutex(m_lock);
if(m_isLoaded)
return;
LOAD_GL_FUNC(glActiveTexture);
diff --git a/emulator/opengl/host/libs/Translator/GLES_CM/GLDispatch.h b/emulator/opengl/host/libs/Translator/GLES_CM/GLDispatch.h
index 9dc320f..ae8c9f8 100644
--- a/emulator/opengl/host/libs/Translator/GLES_CM/GLDispatch.h
+++ b/emulator/opengl/host/libs/Translator/GLES_CM/GLDispatch.h
@@ -17,7 +17,7 @@
#define GLDISPATCHH
#include <GLES/gl.h>
-#include <utils/threads.h>
+#include "emugl/common/mutex.h"
#define GLAPIENTRY GL_APIENTRY
@@ -151,8 +151,8 @@ public:
void (GLAPIENTRY *glVertexPointer) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
void (GLAPIENTRY *glViewport) (GLint x, GLint y, GLsizei width, GLsizei height);
private:
- bool m_isLoaded;
- android::Mutex m_lock;
+ bool m_isLoaded;
+ emugl::Mutex m_lock;
};
#endif
diff --git a/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmContext.cpp b/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmContext.cpp
index ecf51bb..6476c02 100644
--- a/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmContext.cpp
+++ b/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmContext.cpp
@@ -23,7 +23,7 @@
#include <GLES/glext.h>
void GLEScmContext::init() {
- android::Mutex::Autolock mutex(s_lock);
+ emugl::Mutex::AutoLock mutex(s_lock);
if(!m_initialized) {
s_glDispatch.dispatchFuncs(GLES_1_1);
GLEScontext::init();
diff --git a/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmContext.h b/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmContext.h
index 1785877..fbb7023 100644
--- a/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmContext.h
+++ b/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmContext.h
@@ -23,7 +23,6 @@
#include <map>
#include <vector>
#include <string>
-#include <utils/threads.h>
typedef std::map<GLfloat,std::vector<int> > PointSizeIndices;
diff --git a/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmImp.cpp b/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmImp.cpp
index 3ae271f..dd74750 100644
--- a/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmImp.cpp
+++ b/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmImp.cpp
@@ -582,7 +582,7 @@ GL_API void GL_APIENTRY glDrawElements( GLenum mode, GLsizei count, GLenum type
GLESConversionArrays tmpArrs;
if(ctx->isBindedBuffer(GL_ELEMENT_ARRAY_BUFFER)) { // if vbo is binded take the indices from the vbo
const unsigned char* buf = static_cast<unsigned char *>(ctx->getBindedBuffer(GL_ELEMENT_ARRAY_BUFFER));
- indices = buf+reinterpret_cast<uintptr_t>(elementsIndices);
+ indices = buf + SafeUIntFromPointer(elementsIndices);
}
ctx->setupArraysPointers(tmpArrs,0,count,type,indices,false);
@@ -699,8 +699,6 @@ GL_API void GL_APIENTRY glGetBooleanv( GLenum pname, GLboolean *params) {
return;
}
- GLint i;
-
switch(pname)
{
case GL_FRAMEBUFFER_BINDING_OES:
@@ -745,7 +743,6 @@ GL_API void GL_APIENTRY glGetBufferParameteriv( GLenum target, GLenum pname, GL
GET_CTX()
SET_ERROR_IF(!(GLEScmValidate::bufferTarget(target) && GLEScmValidate::bufferParam(pname)),GL_INVALID_ENUM);
SET_ERROR_IF(!ctx->isBindedBuffer(target),GL_INVALID_OPERATION);
- bool ret = true;
switch(pname) {
case GL_BUFFER_SIZE:
ctx->getBufferSize(target,params);
@@ -787,7 +784,6 @@ GL_API void GL_APIENTRY glGetFixedv( GLenum pname, GLfixed *params) {
size_t nParams = glParamSize(pname);
GLfloat fParams[16];
- GLint i;
switch(pname)
{
@@ -994,9 +990,9 @@ GL_API void GL_APIENTRY glGetPointerv( GLenum pname, void **params) {
if(p) {
if(p->isVBO())
{
- *params = (void*)(p->getBufferOffset());
+ *params = SafePointerFromUInt(p->getBufferOffset());
}else{
- *params = const_cast<void *>( p->getArrayData());
+ *params = const_cast<void *>(p->getArrayData());
}
} else {
ctx->setGLerror(GL_INVALID_ENUM);
@@ -1652,7 +1648,7 @@ GL_API void GL_APIENTRY glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOE
{
GET_CTX();
SET_ERROR_IF(!GLEScmValidate::textureTargetLimited(target),GL_INVALID_ENUM);
- unsigned int imagehndl = ToTargetCompatibleHandle((uintptr_t)image);
+ unsigned int imagehndl = SafeUIntFromPointer(image);
EglImage *img = s_eglIface->eglAttachEGLImage(imagehndl);
if (img) {
// Create the texture object in the underlying EGL implementation,
@@ -1688,7 +1684,7 @@ GL_API void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES(GLenum target, GL
{
GET_CTX();
SET_ERROR_IF(target != GL_RENDERBUFFER_OES,GL_INVALID_ENUM);
- unsigned int imagehndl = ToTargetCompatibleHandle((uintptr_t)image);
+ unsigned int imagehndl = SafeUIntFromPointer(image);
EglImage *img = s_eglIface->eglAttachEGLImage(imagehndl);
SET_ERROR_IF(!img,GL_INVALID_VALUE);
SET_ERROR_IF(!ctx->shareGroup().Ptr(),GL_INVALID_OPERATION);
@@ -2231,13 +2227,15 @@ void glDrawTexOES (T x, T y, T z, T width, T height) {
int numClipPlanes;
- GLint viewport[4];
+ GLint viewport[4] = {};
z = (z>1 ? 1 : (z<0 ? 0 : z));
- T vertices[4*3] = {x , y, z,
- x , y+height, z,
- x+width, y+height, z,
- x+width, y, z};
+ T vertices[4*3] = {
+ x , y, z,
+ x , static_cast<T>(y+height), z,
+ static_cast<T>(x+width), static_cast<T>(y+height), z,
+ static_cast<T>(x+width), y, z
+ };
GLfloat texels[ctx->getMaxTexUnits()][4*2];
memset((void*)texels, 0, ctx->getMaxTexUnits()*4*2*sizeof(GLfloat));
diff --git a/emulator/opengl/host/libs/Translator/GLES_V2/Android.mk b/emulator/opengl/host/libs/Translator/GLES_V2/Android.mk
index f4845f7..438334a 100644
--- a/emulator/opengl/host/libs/Translator/GLES_V2/Android.mk
+++ b/emulator/opengl/host/libs/Translator/GLES_V2/Android.mk
@@ -18,10 +18,12 @@ $(call emugl-end-module)
### GLES_V2 host implementation, 64-bit ##############################
-$(call emugl-begin-host-shared-library,lib64GLES_V2_translator)
-$(call emugl-import, lib64GLcommon)
+ifdef EMUGL_BUILD_64BITS
+ $(call emugl-begin-host64-shared-library,lib64GLES_V2_translator)
+ $(call emugl-import, lib64GLcommon)
-LOCAL_LDLIBS += -m64
-LOCAL_SRC_FILES := $(host_common_SRC_FILES)
+ LOCAL_LDLIBS += -m64
+ LOCAL_SRC_FILES := $(host_common_SRC_FILES)
-$(call emugl-end-module)
+ $(call emugl-end-module)
+endif \ No newline at end of file
diff --git a/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Context.cpp b/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Context.cpp
index 1457cec..f8f674b 100644
--- a/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Context.cpp
+++ b/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Context.cpp
@@ -15,11 +15,10 @@
*/
#include "GLESv2Context.h"
-
-
+#include <string.h>
void GLESv2Context::init() {
- android::Mutex::Autolock mutex(s_lock);
+ emugl::Mutex::AutoLock mutex(s_lock);
if(!m_initialized) {
s_glDispatch.dispatchFuncs(GLES_2_0);
GLEScontext::init();
diff --git a/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Context.h b/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Context.h
index 75af864..7e71177 100644
--- a/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Context.h
+++ b/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Context.h
@@ -20,7 +20,6 @@
#include <GLcommon/GLDispatch.h>
#include <GLcommon/GLEScontext.h>
#include <GLcommon/objectNameManager.h>
-#include <utils/threads.h>
diff --git a/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Imp.cpp b/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Imp.cpp
index 7ae9427..fe64f6f 100644
--- a/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Imp.cpp
+++ b/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Imp.cpp
@@ -593,7 +593,7 @@ GL_APICALL void GL_APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum t
const GLvoid* indices = elementsIndices;
if(ctx->isBindedBuffer(GL_ELEMENT_ARRAY_BUFFER)) { // if vbo is binded take the indices from the vbo
const unsigned char* buf = static_cast<unsigned char *>(ctx->getBindedBuffer(GL_ELEMENT_ARRAY_BUFFER));
- indices = buf+reinterpret_cast<uintptr_t>(elementsIndices);
+ indices = buf + SafeUIntFromPointer(elementsIndices);
}
GLESConversionArrays tmpArrs;
@@ -867,7 +867,6 @@ GL_APICALL void GL_APIENTRY glGetBufferParameteriv(GLenum target, GLenum pname,
GET_CTX();
SET_ERROR_IF(!(GLESv2Validate::bufferTarget(target) && GLESv2Validate::bufferParam(pname)),GL_INVALID_ENUM);
SET_ERROR_IF(!ctx->isBindedBuffer(target),GL_INVALID_OPERATION);
- bool ret = true;
switch(pname) {
case GL_BUFFER_SIZE:
ctx->getBufferSize(target,params);
@@ -941,11 +940,19 @@ GL_APICALL void GL_APIENTRY glGetFloatv(GLenum pname, GLfloat* params){
}
GL_APICALL void GL_APIENTRY glGetIntegerv(GLenum pname, GLint* params){
+ int destroyCtx = 0;
GET_CTX();
+ if (!ctx) {
+ ctx = createGLESContext();
+ if (ctx)
+ destroyCtx = 1;
+ }
if (ctx->glGetIntegerv(pname,params))
{
- return;
+ if (destroyCtx)
+ deleteGLESContext(ctx);
+ return;
}
bool es2 = ctx->getCaps()->GL_ARB_ES2_COMPATIBILITY;
@@ -1031,6 +1038,8 @@ GL_APICALL void GL_APIENTRY glGetIntegerv(GLenum pname, GLint* params){
default:
ctx->dispatcher().glGetIntegerv(pname,params);
}
+ if (destroyCtx)
+ deleteGLESContext(ctx);
}
GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params){
@@ -2006,7 +2015,7 @@ GL_APICALL void GL_APIENTRY glEGLImageTargetTexture2DOES(GLenum target, GLeglIma
{
GET_CTX();
SET_ERROR_IF(!GLESv2Validate::textureTargetLimited(target),GL_INVALID_ENUM);
- unsigned int imagehndl = ToTargetCompatibleHandle((uintptr_t)image);
+ unsigned int imagehndl = SafeUIntFromPointer(image);
EglImage *img = s_eglIface->eglAttachEGLImage(imagehndl);
if (img) {
// Create the texture object in the underlying EGL implementation,
@@ -2042,7 +2051,7 @@ GL_APICALL void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES(GLenum target
{
GET_CTX();
SET_ERROR_IF(target != GL_RENDERBUFFER_OES,GL_INVALID_ENUM);
- unsigned int imagehndl = ToTargetCompatibleHandle((uintptr_t)image);
+ unsigned int imagehndl = SafeUIntFromPointer(image);
EglImage *img = s_eglIface->eglAttachEGLImage(imagehndl);
SET_ERROR_IF(!img,GL_INVALID_VALUE);
SET_ERROR_IF(!ctx->shareGroup().Ptr(),GL_INVALID_OPERATION);
diff --git a/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Validate.cpp b/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Validate.cpp
index 53d1314..3f00428 100644
--- a/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Validate.cpp
+++ b/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Validate.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
#include "GLESv2Validate.h"
+#include <string.h>
bool GLESv2Validate::blendEquationMode(GLenum mode){
return mode == GL_FUNC_ADD ||
diff --git a/emulator/opengl/host/libs/Translator/GLES_V2/ShaderParser.cpp b/emulator/opengl/host/libs/Translator/GLES_V2/ShaderParser.cpp
index a80326d..940538a 100644
--- a/emulator/opengl/host/libs/Translator/GLES_V2/ShaderParser.cpp
+++ b/emulator/opengl/host/libs/Translator/GLES_V2/ShaderParser.cpp
@@ -15,6 +15,7 @@
*/
#include "ShaderParser.h"
+#include <stdlib.h>
#include <string.h>
ShaderParser::ShaderParser():ObjectData(SHADER_DATA),
@@ -223,8 +224,7 @@ void ShaderParser::parseOmitPrecision(){
SEMICOLON
} statementState = PRECISION;
const char *precision = NULL;
- const char *delimiter = NULL;
-
+
enum {
PARSE_NONE,
PARSE_IN_C_COMMENT,
diff --git a/emulator/opengl/host/libs/Translator/GLcommon/Android.mk b/emulator/opengl/host/libs/Translator/GLcommon/Android.mk
index 1236566..b215329 100644
--- a/emulator/opengl/host/libs/Translator/GLcommon/Android.mk
+++ b/emulator/opengl/host/libs/Translator/GLcommon/Android.mk
@@ -41,21 +41,23 @@ 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)
$(call emugl-end-module)
### EGL host implementation, 64-bit ################
-
-$(call emugl-begin-host-static-library,lib64GLcommon)
-
-$(call emugl-import,lib64OpenglOsUtils)
-translator_path := $(LOCAL_PATH)/..
-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-end-module)
+ifdef EMUGL_BUILD_64BITS
+ $(call emugl-begin-host64-static-library,lib64GLcommon)
+
+ $(call emugl-import,lib64OpenglOsUtils)
+ translator_path := $(LOCAL_PATH)/..
+ LOCAL_SRC_FILES := $(host_common_SRC_FILES)
+ LOCAL_CFLAGS += -fPIC
+ $(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, lib64emugl_common)
+
+ $(call emugl-end-module)
+endif \ No newline at end of file
diff --git a/emulator/opengl/host/libs/Translator/GLcommon/GLDispatch.cpp b/emulator/opengl/host/libs/Translator/GLcommon/GLDispatch.cpp
index abed760..7b217fd 100644
--- a/emulator/opengl/host/libs/Translator/GLcommon/GLDispatch.cpp
+++ b/emulator/opengl/host/libs/Translator/GLcommon/GLDispatch.cpp
@@ -45,29 +45,30 @@ static GL_FUNC_PTR getGLFuncAddress(const char *funcName) {
return ret;
}
-#define LOAD_GL_FUNC(name) { void * funcAddrs = NULL; \
- if(name == NULL){ \
- funcAddrs = (void *)getGLFuncAddress(#name); \
- if(funcAddrs){ \
- *(void**)(&name) = funcAddrs; \
- } else { \
- fprintf(stderr,"could not load func %s\n",#name); \
- *(void**)(&name) = (void *)dummy_##name; \
- } \
- } \
- }
+#define LOAD_GL_FUNC(name) do { \
+ if (!name) { \
+ void* funcAddress = (void *)getGLFuncAddress(#name); \
+ if (funcAddress) { \
+ name = (__typeof__(name))(funcAddress); \
+ } else { \
+ fprintf(stderr, "Could not load func %s\n", #name); \
+ name = (__typeof__(name))(dummy_##name); \
+ } \
+ } \
+ } while (0)
-#define LOAD_GLEXT_FUNC(name) { void * funcAddrs = NULL; \
- if(name == NULL){ \
- funcAddrs = (void *)getGLFuncAddress(#name); \
- if(funcAddrs) \
- *(void**)(&name) = funcAddrs; \
- } \
- }
+#define LOAD_GLEXT_FUNC(name) do { \
+ if (!name) { \
+ void* funcAddress = (void *)getGLFuncAddress(#name); \
+ if (funcAddress) { \
+ name = (__typeof__(name))(funcAddress); \
+ } \
+ } \
+ } while (0)
/* initializing static GLDispatch members*/
-android::Mutex GLDispatch::s_lock;
+emugl::Mutex GLDispatch::s_lock;
void (GLAPIENTRY *GLDispatch::glActiveTexture)(GLenum) = NULL;
void (GLAPIENTRY *GLDispatch::glBindBuffer)(GLenum,GLuint) = NULL;
void (GLAPIENTRY *GLDispatch::glBindTexture)(GLenum, GLuint) = NULL;
@@ -298,7 +299,7 @@ GLDispatch::GLDispatch():m_isLoaded(false){};
void GLDispatch::dispatchFuncs(GLESVersion version){
- android::Mutex::Autolock mutex(s_lock);
+ emugl::Mutex::AutoLock mutex(s_lock);
if(m_isLoaded)
return;
diff --git a/emulator/opengl/host/libs/Translator/GLcommon/GLEScontext.cpp b/emulator/opengl/host/libs/Translator/GLcommon/GLEScontext.cpp
index 387eb2d..ba3edbe 100644
--- a/emulator/opengl/host/libs/Translator/GLcommon/GLEScontext.cpp
+++ b/emulator/opengl/host/libs/Translator/GLcommon/GLEScontext.cpp
@@ -23,6 +23,7 @@
#include <GLcommon/TextureUtils.h>
#include <GLcommon/FramebufferData.h>
#include <strings.h>
+#include <string.h>
//decleration
static void convertFixedDirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,unsigned int nBytes,unsigned int strideOut,int attribSize);
@@ -84,7 +85,7 @@ void GLESConversionArrays::operator++(){
}
GLDispatch GLEScontext::s_glDispatch;
-android::Mutex GLEScontext::s_lock;
+emugl::Mutex GLEScontext::s_lock;
std::string* GLEScontext::s_glExtensions= NULL;
std::string GLEScontext::s_glVendor;
std::string GLEScontext::s_glRenderer;
@@ -191,7 +192,7 @@ GLEScontext::~GLEScontext() {
const GLvoid* GLEScontext::setPointer(GLenum arrType,GLint size,GLenum type,GLsizei stride,const GLvoid* data,bool normalize) {
GLuint bufferName = m_arrayBuffer;
if(bufferName) {
- unsigned int offset = ToTargetCompatibleHandle((uintptr_t)data);
+ unsigned int offset = SafeUIntFromPointer(data);
GLESbuffer* vbo = static_cast<GLESbuffer*>(m_shareGroup->getObjectData(VERTEXBUFFER,bufferName).Ptr());
m_map[arrType]->setBuffer(size,type,stride,vbo,bufferName,offset,normalize);
return static_cast<const unsigned char*>(vbo->getData()) + offset;
@@ -329,10 +330,8 @@ void GLEScontext::convertDirectVBO(GLESConversionArrays& cArrs,GLint first,GLsiz
RangeList ranges;
RangeList conversions;
GLushort* indices = NULL;
- GLenum type = p->getType();
int attribSize = p->getSize();
int stride = p->getStride()?p->getStride():sizeof(GLfixed)*attribSize;
- unsigned int size = p->getStride()?p->getStride()*count:attribSize*count*sizeof(GLfixed);
char* data = (char*)p->getBufferData() + (first*stride);
if(p->bufferNeedConversion()) {
@@ -388,7 +387,6 @@ void GLEScontext::convertIndirectVBO(GLESConversionArrays& cArrs,GLsizei count,G
RangeList ranges;
RangeList conversions;
GLushort* conversionIndices = NULL;
- GLenum type = p->getType();
int attribSize = p->getSize();
int stride = p->getStride()?p->getStride():sizeof(GLfixed)*attribSize;
char* data = static_cast<char*>(p->getBufferData());
@@ -679,6 +677,10 @@ bool GLEScontext::glGetIntegerv(GLenum pname, GLint *params)
case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
*params = GL_RGBA;
break;
+
+ case GL_MAX_TEXTURE_SIZE:
+ *params = getMaxTexSize();
+ break;
default:
return false;
}
diff --git a/emulator/opengl/host/libs/Translator/GLcommon/objectNameManager.cpp b/emulator/opengl/host/libs/Translator/GLcommon/objectNameManager.cpp
index cfea855..3612211 100644
--- a/emulator/opengl/host/libs/Translator/GLcommon/objectNameManager.cpp
+++ b/emulator/opengl/host/libs/Translator/GLcommon/objectNameManager.cpp
@@ -18,12 +18,11 @@
#include <GLcommon/GLEScontext.h>
-NameSpace::NameSpace(NamedObjectType p_type, GlobalNameSpace *globalNameSpace) :
+NameSpace::NameSpace(NamedObjectType p_type,
+ GlobalNameSpace *globalNameSpace) :
m_nextName(0),
m_type(p_type),
- m_globalNameSpace(globalNameSpace)
-{
-}
+ m_globalNameSpace(globalNameSpace) {}
NameSpace::~NameSpace()
{
@@ -35,14 +34,16 @@ NameSpace::~NameSpace()
}
ObjectLocalName
-NameSpace::genName(ObjectLocalName p_localName, bool genGlobal, bool genLocal)
+NameSpace::genName(ObjectLocalName p_localName,
+ bool genGlobal, bool genLocal)
{
-
ObjectLocalName localName = p_localName;
if (genLocal) {
do {
localName = ++m_nextName;
- } while( localName == 0 || m_localToGlobalMap.find(localName) != m_localToGlobalMap.end() );
+ } while(localName == 0 ||
+ m_localToGlobalMap.find(localName) !=
+ m_localToGlobalMap.end() );
}
if (genGlobal) {
@@ -114,15 +115,9 @@ NameSpace::replaceGlobalName(ObjectLocalName p_localName, unsigned int p_globalN
}
-GlobalNameSpace::GlobalNameSpace()
-{
- mutex_init(&m_lock);
-}
+GlobalNameSpace::GlobalNameSpace() : m_lock() {}
-GlobalNameSpace::~GlobalNameSpace()
-{
- mutex_destroy(&m_lock);
-}
+GlobalNameSpace::~GlobalNameSpace() {}
unsigned int
GlobalNameSpace::genName(NamedObjectType p_type)
@@ -130,7 +125,7 @@ GlobalNameSpace::genName(NamedObjectType p_type)
if ( p_type >= NUM_OBJECT_TYPES ) return 0;
unsigned int name = 0;
- mutex_lock(&m_lock);
+ emugl::Mutex::AutoLock _lock(m_lock);
switch (p_type) {
case VERTEXBUFFER:
GLEScontext::dispatcher().glGenBuffers(1,&name);
@@ -148,7 +143,6 @@ GlobalNameSpace::genName(NamedObjectType p_type)
default:
name = 0;
}
- mutex_unlock(&m_lock);
return name;
}
@@ -160,11 +154,8 @@ GlobalNameSpace::deleteName(NamedObjectType p_type, unsigned int p_name)
typedef std::pair<NamedObjectType, ObjectLocalName> ObjectIDPair;
typedef std::map<ObjectIDPair, ObjectDataPtr> ObjectDataMap;
-ShareGroup::ShareGroup(GlobalNameSpace *globalNameSpace)
-{
- mutex_init(&m_lock);
-
- for (int i=0; i<NUM_OBJECT_TYPES; i++) {
+ShareGroup::ShareGroup(GlobalNameSpace *globalNameSpace) : m_lock() {
+ for (int i=0; i < NUM_OBJECT_TYPES; i++) {
m_nameSpace[i] = new NameSpace((NamedObjectType)i, globalNameSpace);
}
@@ -173,27 +164,24 @@ ShareGroup::ShareGroup(GlobalNameSpace *globalNameSpace)
ShareGroup::~ShareGroup()
{
- mutex_lock(&m_lock);
+ emugl::Mutex::AutoLock _lock(m_lock);
for (int t = 0; t < NUM_OBJECT_TYPES; t++) {
delete m_nameSpace[t];
}
- ObjectDataMap *map = (ObjectDataMap *)m_objectsData;
- if (map) delete map;
-
- mutex_unlock(&m_lock);
- mutex_destroy(&m_lock);
+ delete (ObjectDataMap *)m_objectsData;
}
ObjectLocalName
-ShareGroup::genName(NamedObjectType p_type, ObjectLocalName p_localName, bool genLocal)
+ShareGroup::genName(NamedObjectType p_type,
+ ObjectLocalName p_localName,
+ bool genLocal)
{
if (p_type >= NUM_OBJECT_TYPES) return 0;
- mutex_lock(&m_lock);
- ObjectLocalName localName = m_nameSpace[p_type]->genName(p_localName,true,genLocal);
- mutex_unlock(&m_lock);
-
+ emugl::Mutex::AutoLock _lock(m_lock);
+ ObjectLocalName localName =
+ m_nameSpace[p_type]->genName(p_localName, true, genLocal);
return localName;
}
@@ -202,35 +190,28 @@ ShareGroup::genGlobalName(NamedObjectType p_type)
{
if (p_type >= NUM_OBJECT_TYPES) return 0;
- mutex_lock(&m_lock);
- unsigned int name = m_nameSpace[p_type]->genGlobalName();
- mutex_unlock(&m_lock);
-
- return name;
+ emugl::Mutex::AutoLock _lock(m_lock);
+ return m_nameSpace[p_type]->genGlobalName();
}
unsigned int
-ShareGroup::getGlobalName(NamedObjectType p_type, ObjectLocalName p_localName)
+ShareGroup::getGlobalName(NamedObjectType p_type,
+ ObjectLocalName p_localName)
{
if (p_type >= NUM_OBJECT_TYPES) return 0;
- mutex_lock(&m_lock);
- unsigned int globalName = m_nameSpace[p_type]->getGlobalName(p_localName);
- mutex_unlock(&m_lock);
-
- return globalName;
+ emugl::Mutex::AutoLock _lock(m_lock);
+ return m_nameSpace[p_type]->getGlobalName(p_localName);
}
ObjectLocalName
-ShareGroup::getLocalName(NamedObjectType p_type, unsigned int p_globalName)
+ShareGroup::getLocalName(NamedObjectType p_type,
+ unsigned int p_globalName)
{
if (p_type >= NUM_OBJECT_TYPES) return 0;
- mutex_lock(&m_lock);
- ObjectLocalName localName = m_nameSpace[p_type]->getLocalName(p_globalName);
- mutex_unlock(&m_lock);
-
- return localName;
+ emugl::Mutex::AutoLock _lock(m_lock);
+ return m_nameSpace[p_type]->getLocalName(p_globalName);
}
void
@@ -238,13 +219,12 @@ ShareGroup::deleteName(NamedObjectType p_type, ObjectLocalName p_localName)
{
if (p_type >= NUM_OBJECT_TYPES) return;
- mutex_lock(&m_lock);
+ emugl::Mutex::AutoLock _lock(m_lock);
m_nameSpace[p_type]->deleteName(p_localName);
ObjectDataMap *map = (ObjectDataMap *)m_objectsData;
if (map) {
map->erase( ObjectIDPair(p_type, p_localName) );
}
- mutex_unlock(&m_lock);
}
bool
@@ -252,29 +232,29 @@ ShareGroup::isObject(NamedObjectType p_type, ObjectLocalName p_localName)
{
if (p_type >= NUM_OBJECT_TYPES) return 0;
- mutex_lock(&m_lock);
- bool exist = m_nameSpace[p_type]->isObject(p_localName);
- mutex_unlock(&m_lock);
-
- return exist;
+ emugl::Mutex::AutoLock _lock(m_lock);
+ return m_nameSpace[p_type]->isObject(p_localName);
}
void
-ShareGroup::replaceGlobalName(NamedObjectType p_type, ObjectLocalName p_localName, unsigned int p_globalName)
+ShareGroup::replaceGlobalName(NamedObjectType p_type,
+ ObjectLocalName p_localName,
+ unsigned int p_globalName)
{
if (p_type >= NUM_OBJECT_TYPES) return;
- mutex_lock(&m_lock);
+ emugl::Mutex::AutoLock _lock(m_lock);
m_nameSpace[p_type]->replaceGlobalName(p_localName, p_globalName);
- mutex_unlock(&m_lock);
}
void
-ShareGroup::setObjectData(NamedObjectType p_type, ObjectLocalName p_localName, ObjectDataPtr data)
+ShareGroup::setObjectData(NamedObjectType p_type,
+ ObjectLocalName p_localName,
+ ObjectDataPtr data)
{
if (p_type >= NUM_OBJECT_TYPES) return;
- mutex_lock(&m_lock);
+ emugl::Mutex::AutoLock _lock(m_lock);
ObjectDataMap *map = (ObjectDataMap *)m_objectsData;
if (!map) {
@@ -284,45 +264,36 @@ ShareGroup::setObjectData(NamedObjectType p_type, ObjectLocalName p_localName, O
ObjectIDPair id( p_type, p_localName );
map->insert( std::pair<ObjectIDPair, ObjectDataPtr>(id, data) );
-
- mutex_unlock(&m_lock);
}
ObjectDataPtr
-ShareGroup::getObjectData(NamedObjectType p_type, ObjectLocalName p_localName)
+ShareGroup::getObjectData(NamedObjectType p_type,
+ ObjectLocalName p_localName)
{
ObjectDataPtr ret;
if (p_type >= NUM_OBJECT_TYPES) return ret;
- mutex_lock(&m_lock);
+ emugl::Mutex::AutoLock _lock(m_lock);
ObjectDataMap *map = (ObjectDataMap *)m_objectsData;
if (map) {
- ObjectDataMap::iterator i = map->find( ObjectIDPair(p_type, p_localName) );
+ ObjectDataMap::iterator i =
+ map->find( ObjectIDPair(p_type, p_localName) );
if (i != map->end()) ret = (*i).second;
}
-
- mutex_unlock(&m_lock);
-
return ret;
}
ObjectNameManager::ObjectNameManager(GlobalNameSpace *globalNameSpace) :
- m_globalNameSpace(globalNameSpace)
-{
- mutex_init(&m_lock);
-}
+ m_lock(), m_globalNameSpace(globalNameSpace) {}
-ObjectNameManager::~ObjectNameManager()
-{
- mutex_destroy(&m_lock);
-}
+ObjectNameManager::~ObjectNameManager() {}
ShareGroupPtr
ObjectNameManager::createShareGroup(void *p_groupName)
{
- mutex_lock(&m_lock);
+ emugl::Mutex::AutoLock _lock(m_lock);
ShareGroupPtr shareGroupReturn;
@@ -334,19 +305,19 @@ ObjectNameManager::createShareGroup(void *p_groupName)
//
// Group does not exist, create new group
//
- shareGroupReturn = ShareGroupPtr( new ShareGroup(m_globalNameSpace) );
- m_groups.insert( std::pair<void *, ShareGroupPtr>(p_groupName, shareGroupReturn) );
+ shareGroupReturn = ShareGroupPtr(new ShareGroup(m_globalNameSpace));
+ m_groups.insert(
+ std::pair<void*, ShareGroupPtr>(
+ p_groupName, shareGroupReturn));
}
- mutex_unlock(&m_lock);
-
return shareGroupReturn;
}
ShareGroupPtr
ObjectNameManager::getShareGroup(void *p_groupName)
{
- mutex_lock(&m_lock);
+ emugl::Mutex::AutoLock _lock(m_lock);
ShareGroupPtr shareGroupReturn(NULL);
@@ -354,58 +325,45 @@ ObjectNameManager::getShareGroup(void *p_groupName)
if (s != m_groups.end()) {
shareGroupReturn = (*s).second;
}
- mutex_unlock(&m_lock);
return shareGroupReturn;
}
ShareGroupPtr
-ObjectNameManager::attachShareGroup(void *p_groupName, void *p_existingGroupName)
+ObjectNameManager::attachShareGroup(void *p_groupName,
+ void *p_existingGroupName)
{
- mutex_lock(&m_lock);
-
- ShareGroupPtr shareGroupReturn;
+ emugl::Mutex::AutoLock _lock(m_lock);
ShareGroupsMap::iterator s( m_groups.find(p_existingGroupName) );
if (s == m_groups.end()) {
// ShareGroup did not found !!!
- mutex_unlock(&m_lock);
return ShareGroupPtr(NULL);
}
- shareGroupReturn = (*s).second;
-
- if (m_groups.find(p_groupName) == m_groups.end())
- {
- m_groups.insert( std::pair<void *, ShareGroupPtr>(p_groupName, shareGroupReturn) );
+ ShareGroupPtr shareGroupReturn((*s).second);
+ if (m_groups.find(p_groupName) == m_groups.end()) {
+ m_groups.insert(
+ std::pair<void*, ShareGroupPtr>(
+ p_groupName, shareGroupReturn));
}
-
- mutex_unlock(&m_lock);
-
return shareGroupReturn;
}
void
ObjectNameManager::deleteShareGroup(void *p_groupName)
{
- mutex_lock(&m_lock);
+ emugl::Mutex::AutoLock _lock(m_lock);
ShareGroupsMap::iterator s( m_groups.find(p_groupName) );
if (s != m_groups.end()) {
m_groups.erase(s);
}
-
- mutex_unlock(&m_lock);
}
void *ObjectNameManager::getGlobalContext()
{
- void *ret = NULL;
-
- mutex_lock(&m_lock);
- if (m_groups.size() > 0) ret = (*m_groups.begin()).first;
- mutex_unlock(&m_lock);
-
- return ret;
+ emugl::Mutex::AutoLock _lock(m_lock);
+ return (m_groups.size() > 0) ? (*m_groups.begin()).first : NULL;
}
diff --git a/emulator/opengl/host/libs/Translator/include/ETC1/etc1.h b/emulator/opengl/host/libs/Translator/include/ETC1/etc1.h
new file mode 100644
index 0000000..0d38905
--- /dev/null
+++ b/emulator/opengl/host/libs/Translator/include/ETC1/etc1.h
@@ -0,0 +1,106 @@
+// Copyright 2009 Google Inc.
+//
+// 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 __etc1_h__
+#define __etc1_h__
+
+#define ETC1_ENCODED_BLOCK_SIZE 8
+#define ETC1_DECODED_BLOCK_SIZE 48
+
+#ifndef ETC1_RGB8_OES
+#define ETC1_RGB8_OES 0x8D64
+#endif
+
+typedef unsigned char etc1_byte;
+typedef int etc1_bool;
+typedef unsigned int etc1_uint32;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Encode a block of pixels.
+//
+// pIn is a pointer to a ETC_DECODED_BLOCK_SIZE array of bytes that represent a
+// 4 x 4 square of 3-byte pixels in form R, G, B. Byte (3 * (x + 4 * y) is the R
+// value of pixel (x, y).
+//
+// validPixelMask is a 16-bit mask where bit (1 << (x + y * 4)) indicates whether
+// the corresponding (x,y) pixel is valid. Invalid pixel color values are ignored when compressing.
+//
+// pOut is an ETC1 compressed version of the data.
+
+void etc1_encode_block(const etc1_byte* pIn, etc1_uint32 validPixelMask, etc1_byte* pOut);
+
+// Decode a block of pixels.
+//
+// pIn is an ETC1 compressed version of the data.
+//
+// pOut is a pointer to a ETC_DECODED_BLOCK_SIZE array of bytes that represent a
+// 4 x 4 square of 3-byte pixels in form R, G, B. Byte (3 * (x + 4 * y) is the R
+// value of pixel (x, y).
+
+void etc1_decode_block(const etc1_byte* pIn, etc1_byte* pOut);
+
+// Return the size of the encoded image data (does not include size of PKM header).
+
+etc1_uint32 etc1_get_encoded_data_size(etc1_uint32 width, etc1_uint32 height);
+
+// Encode an entire image.
+// pIn - pointer to the image data. Formatted such that
+// pixel (x,y) is at pIn + pixelSize * x + stride * y;
+// pOut - pointer to encoded data. Must be large enough to store entire encoded image.
+// pixelSize can be 2 or 3. 2 is an GL_UNSIGNED_SHORT_5_6_5 image, 3 is a GL_BYTE RGB image.
+// returns non-zero if there is an error.
+
+int etc1_encode_image(const etc1_byte* pIn, etc1_uint32 width, etc1_uint32 height,
+ etc1_uint32 pixelSize, etc1_uint32 stride, etc1_byte* pOut);
+
+// Decode an entire image.
+// pIn - pointer to encoded data.
+// pOut - pointer to the image data. Will be written such that
+// pixel (x,y) is at pIn + pixelSize * x + stride * y. Must be
+// large enough to store entire image.
+// pixelSize can be 2 or 3. 2 is an GL_UNSIGNED_SHORT_5_6_5 image, 3 is a GL_BYTE RGB image.
+// returns non-zero if there is an error.
+
+int etc1_decode_image(const etc1_byte* pIn, etc1_byte* pOut,
+ etc1_uint32 width, etc1_uint32 height,
+ etc1_uint32 pixelSize, etc1_uint32 stride);
+
+// Size of a PKM header, in bytes.
+
+#define ETC_PKM_HEADER_SIZE 16
+
+// Format a PKM header
+
+void etc1_pkm_format_header(etc1_byte* pHeader, etc1_uint32 width, etc1_uint32 height);
+
+// Check if a PKM header is correctly formatted.
+
+etc1_bool etc1_pkm_is_valid(const etc1_byte* pHeader);
+
+// Read the image width from a PKM header
+
+etc1_uint32 etc1_pkm_get_width(const etc1_byte* pHeader);
+
+// Read the image height from a PKM header
+
+etc1_uint32 etc1_pkm_get_height(const etc1_byte* pHeader);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/emulator/opengl/host/libs/Translator/include/GLcommon/GLDispatch.h b/emulator/opengl/host/libs/Translator/include/GLcommon/GLDispatch.h
index de7d563..18a989c 100644
--- a/emulator/opengl/host/libs/Translator/include/GLcommon/GLDispatch.h
+++ b/emulator/opengl/host/libs/Translator/include/GLcommon/GLDispatch.h
@@ -18,7 +18,7 @@
#include <GLES/gl.h>
#include <GLES2/gl2.h>
-#include <utils/threads.h>
+#include "emugl/common/mutex.h"
#include "gldefs.h"
#include "GLutils.h"
@@ -260,8 +260,8 @@ public:
static void (GL_APIENTRY *glShaderSource)(GLuint shader, GLsizei count, const GLchar** string, const GLint* length);
private:
- bool m_isLoaded;
- static android::Mutex s_lock;
+ bool m_isLoaded;
+ static emugl::Mutex s_lock;
};
#endif
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/GLEScontext.h b/emulator/opengl/host/libs/Translator/include/GLcommon/GLEScontext.h
index 20509fc..5aed0ad 100644
--- a/emulator/opengl/host/libs/Translator/include/GLcommon/GLEScontext.h
+++ b/emulator/opengl/host/libs/Translator/include/GLcommon/GLEScontext.h
@@ -20,7 +20,7 @@
#include "GLDispatch.h"
#include "GLESpointer.h"
#include "objectNameManager.h"
-#include <utils/threads.h>
+#include "emugl/common/mutex.h"
#include <string>
typedef std::map<GLenum,GLESpointer*> ArraysMap;
@@ -187,7 +187,7 @@ protected:
void initCapsLocked(const GLubyte * extensionString);
virtual void initExtensionString() =0;
- static android::Mutex s_lock;
+ static emugl::Mutex s_lock;
static GLDispatch s_glDispatch;
bool m_initialized;
unsigned int m_activeTexture;
diff --git a/emulator/opengl/host/libs/Translator/include/GLcommon/GLutils.h b/emulator/opengl/host/libs/Translator/include/GLcommon/GLutils.h
index 2aed646..974b9be 100644
--- a/emulator/opengl/host/libs/Translator/include/GLcommon/GLutils.h
+++ b/emulator/opengl/host/libs/Translator/include/GLcommon/GLutils.h
@@ -16,36 +16,37 @@
#ifndef GL_UTILS_H
#define GL_UTILS_H
-#include <inttypes.h>
#include <assert.h>
+#include <inttypes.h>
-typedef enum{
- GLES_1_1 = 1,
- GLES_2_0 = 2,
- MAX_GLES_VERSION //Must be last
- }GLESVersion;
+typedef enum {
+ GLES_1_1 = 1,
+ GLES_2_0 = 2,
+ MAX_GLES_VERSION //Must be last
+} GLESVersion;
template <class T>
void swap(T& x,T& y) {
T temp;
- temp=x;
- x=y;
- y=temp;
+ temp = x;
+ x = y;
+ y = temp;
}
bool isPowerOf2(int num);
-inline
-unsigned int ToTargetCompatibleHandle(uintptr_t hostHandle)
-{
- // The host and target handles can have different sizes (e.g. 32-bit
- // target handle for ARM, and 64-bit host handle on x86_64).
- // This function checks that the input host handle value can be
- // converted into a target handle one without losing any bits.
- //
- unsigned int targetHandle = (unsigned int)hostHandle;
- assert(sizeof(targetHandle) == sizeof(hostHandle) || targetHandle == hostHandle);
- return targetHandle;
+// <EGL/egl.h> defines many types as 'void*' while they're really
+// implemented as unsigned integers. These convenience template functions
+// help casting between them safely without generating compiler warnings.
+inline void* SafePointerFromUInt(unsigned int handle) {
+ return (void*)(uintptr_t)(handle);
+}
+
+inline unsigned int SafeUIntFromPointer(const void* ptr) {
+ // Assertion error if the pointer contains a value that does not fit
+ // in an unsigned integer!
+ assert((uintptr_t)(ptr) == (unsigned int)(uintptr_t)(ptr));
+ return (unsigned int)(uintptr_t)(ptr);
}
#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..4d4d038 100644
--- a/emulator/opengl/host/libs/Translator/include/GLcommon/objectNameManager.h
+++ b/emulator/opengl/host/libs/Translator/include/GLcommon/objectNameManager.h
@@ -16,9 +16,9 @@
#ifndef _OBJECT_NAME_MANAGER_H
#define _OBJECT_NAME_MANAGER_H
-#include <cutils/threads.h>
#include <map>
-#include "SmartPtr.h"
+#include "emugl/common/mutex.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;
@@ -129,7 +129,7 @@ public:
void deleteName(NamedObjectType p_type, unsigned int p_name);
private:
- mutex_t m_lock;
+ emugl::Mutex m_lock;
};
//
@@ -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:
@@ -204,12 +204,12 @@ private:
~ShareGroup();
private:
- mutex_t m_lock;
+ emugl::Mutex m_lock;
NameSpace *m_nameSpace[NUM_OBJECT_TYPES];
void *m_objectsData;
};
-typedef SmartPtr<ShareGroup> ShareGroupPtr;
+typedef emugl::SmartPtr<ShareGroup> ShareGroupPtr;
typedef std::multimap<void *, ShareGroupPtr> ShareGroupsMap;
//
@@ -262,7 +262,7 @@ public:
private:
ShareGroupsMap m_groups;
- mutex_t m_lock;
+ emugl::Mutex m_lock;
GlobalNameSpace *m_globalNameSpace;
};
diff --git a/emulator/opengl/host/libs/Translator/include/KHR/khrplatform.h b/emulator/opengl/host/libs/Translator/include/KHR/khrplatform.h
new file mode 100644
index 0000000..c9e6f17
--- /dev/null
+++ b/emulator/opengl/host/libs/Translator/include/KHR/khrplatform.h
@@ -0,0 +1,282 @@
+#ifndef __khrplatform_h_
+#define __khrplatform_h_
+
+/*
+** Copyright (c) 2008-2009 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+/* Khronos platform-specific types and definitions.
+ *
+ * $Revision: 23298 $ on $Date: 2013-09-30 17:07:13 -0700 (Mon, 30 Sep 2013) $
+ *
+ * Adopters may modify this file to suit their platform. Adopters are
+ * encouraged to submit platform specific 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
+ * "Khronos (general)" component "Registry".
+ *
+ * A predefined template which fills in some of the bug fields can be
+ * reached using http://tinyurl.com/khrplatform-h-bugreport, but you
+ * must create a Bugzilla login first.
+ *
+ *
+ * See the Implementer's Guidelines for information about where this file
+ * should be located on your system and for more details of its use:
+ * http://www.khronos.org/registry/implementers_guide.pdf
+ *
+ * This file should be included as
+ * #include <KHR/khrplatform.h>
+ * by Khronos client API header files that use its types and defines.
+ *
+ * The types in khrplatform.h should only be used to define API-specific types.
+ *
+ * Types defined in khrplatform.h:
+ * khronos_int8_t signed 8 bit
+ * khronos_uint8_t unsigned 8 bit
+ * khronos_int16_t signed 16 bit
+ * khronos_uint16_t unsigned 16 bit
+ * khronos_int32_t signed 32 bit
+ * khronos_uint32_t unsigned 32 bit
+ * khronos_int64_t signed 64 bit
+ * khronos_uint64_t unsigned 64 bit
+ * khronos_intptr_t signed same number of bits as a pointer
+ * khronos_uintptr_t unsigned same number of bits as a pointer
+ * khronos_ssize_t signed size
+ * khronos_usize_t unsigned size
+ * khronos_float_t signed 32 bit floating point
+ * khronos_time_ns_t unsigned 64 bit time in nanoseconds
+ * khronos_utime_nanoseconds_t unsigned time interval or absolute time in
+ * nanoseconds
+ * khronos_stime_nanoseconds_t signed time interval in nanoseconds
+ * khronos_boolean_enum_t enumerated boolean type. This should
+ * only be used as a base type when a client API's boolean type is
+ * an enum. Client APIs which use an integer or other type for
+ * booleans cannot use this as the base type for their boolean.
+ *
+ * Tokens defined in khrplatform.h:
+ *
+ * KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
+ *
+ * KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
+ * KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
+ *
+ * Calling convention macros defined in this file:
+ * KHRONOS_APICALL
+ * KHRONOS_APIENTRY
+ * KHRONOS_APIATTRIBUTES
+ *
+ * These may be used in function prototypes as:
+ *
+ * KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
+ * int arg1,
+ * int arg2) KHRONOS_APIATTRIBUTES;
+ */
+
+/*-------------------------------------------------------------------------
+ * Definition of KHRONOS_APICALL
+ *-------------------------------------------------------------------------
+ * This precedes the return type of the function in the function prototype.
+ */
+#if defined(_WIN32) && !defined(__SCITECH_SNAP__)
+# define KHRONOS_APICALL __declspec(dllimport)
+#elif defined (__SYMBIAN32__)
+# define KHRONOS_APICALL IMPORT_C
+#else
+# define KHRONOS_APICALL
+#endif
+
+/*-------------------------------------------------------------------------
+ * Definition of KHRONOS_APIENTRY
+ *-------------------------------------------------------------------------
+ * This follows the return type of the function and precedes the function
+ * name in the function prototype.
+ */
+#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
+ /* Win32 but not WinCE */
+# define KHRONOS_APIENTRY __stdcall
+#else
+# define KHRONOS_APIENTRY
+#endif
+
+/*-------------------------------------------------------------------------
+ * Definition of KHRONOS_APIATTRIBUTES
+ *-------------------------------------------------------------------------
+ * This follows the closing parenthesis of the function prototype arguments.
+ */
+#if defined (__ARMCC_2__)
+#define KHRONOS_APIATTRIBUTES __softfp
+#else
+#define KHRONOS_APIATTRIBUTES
+#endif
+
+/*-------------------------------------------------------------------------
+ * basic type definitions
+ *-----------------------------------------------------------------------*/
+#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
+
+
+/*
+ * Using <stdint.h>
+ */
+#include <stdint.h>
+typedef int32_t khronos_int32_t;
+typedef uint32_t khronos_uint32_t;
+typedef int64_t khronos_int64_t;
+typedef uint64_t khronos_uint64_t;
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+
+#elif defined(__VMS ) || defined(__sgi)
+
+/*
+ * Using <inttypes.h>
+ */
+#include <inttypes.h>
+typedef int32_t khronos_int32_t;
+typedef uint32_t khronos_uint32_t;
+typedef int64_t khronos_int64_t;
+typedef uint64_t khronos_uint64_t;
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+
+#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
+
+/*
+ * Win32
+ */
+typedef __int32 khronos_int32_t;
+typedef unsigned __int32 khronos_uint32_t;
+typedef __int64 khronos_int64_t;
+typedef unsigned __int64 khronos_uint64_t;
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+
+#elif defined(__sun__) || defined(__digital__)
+
+/*
+ * Sun or Digital
+ */
+typedef int khronos_int32_t;
+typedef unsigned int khronos_uint32_t;
+#if defined(__arch64__) || defined(_LP64)
+typedef long int khronos_int64_t;
+typedef unsigned long int khronos_uint64_t;
+#else
+typedef long long int khronos_int64_t;
+typedef unsigned long long int khronos_uint64_t;
+#endif /* __arch64__ */
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+
+#elif 0
+
+/*
+ * Hypothetical platform with no float or int64 support
+ */
+typedef int khronos_int32_t;
+typedef unsigned int khronos_uint32_t;
+#define KHRONOS_SUPPORT_INT64 0
+#define KHRONOS_SUPPORT_FLOAT 0
+
+#else
+
+/*
+ * Generic fallback
+ */
+#include <stdint.h>
+typedef int32_t khronos_int32_t;
+typedef uint32_t khronos_uint32_t;
+typedef int64_t khronos_int64_t;
+typedef uint64_t khronos_uint64_t;
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+
+#endif
+
+
+/*
+ * Types that are (so far) the same on all platforms
+ */
+typedef signed char khronos_int8_t;
+typedef unsigned char khronos_uint8_t;
+typedef signed short int khronos_int16_t;
+typedef unsigned short int khronos_uint16_t;
+
+/*
+ * Types that differ between LLP64 and LP64 architectures - in LLP64,
+ * pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
+ * to be the only LLP64 architecture in current use.
+ */
+#ifdef _WIN64
+typedef signed long long int khronos_intptr_t;
+typedef unsigned long long int khronos_uintptr_t;
+typedef signed long long int khronos_ssize_t;
+typedef unsigned long long int khronos_usize_t;
+#else
+typedef signed long int khronos_intptr_t;
+typedef unsigned long int khronos_uintptr_t;
+typedef signed long int khronos_ssize_t;
+typedef unsigned long int khronos_usize_t;
+#endif
+
+#if KHRONOS_SUPPORT_FLOAT
+/*
+ * Float type
+ */
+typedef float khronos_float_t;
+#endif
+
+#if KHRONOS_SUPPORT_INT64
+/* Time types
+ *
+ * These types can be used to represent a time interval in nanoseconds or
+ * an absolute Unadjusted System Time. Unadjusted System Time is the number
+ * of nanoseconds since some arbitrary system event (e.g. since the last
+ * time the system booted). The Unadjusted System Time is an unsigned
+ * 64 bit value that wraps back to 0 every 584 years. Time intervals
+ * may be either signed or unsigned.
+ */
+typedef khronos_uint64_t khronos_utime_nanoseconds_t;
+typedef khronos_int64_t khronos_stime_nanoseconds_t;
+#endif
+
+/*
+ * Dummy value used to pad enum types to 32 bits.
+ */
+#ifndef KHRONOS_MAX_ENUM
+#define KHRONOS_MAX_ENUM 0x7FFFFFFF
+#endif
+
+/*
+ * Enumerated boolean type
+ *
+ * Values other than zero should be considered to be true. Therefore
+ * comparisons should not be made against KHRONOS_TRUE.
+ */
+typedef enum {
+ KHRONOS_FALSE = 0,
+ KHRONOS_TRUE = 1,
+ KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
+} khronos_boolean_enum_t;
+
+#endif /* __khrplatform_h_ */
diff --git a/emulator/opengl/host/libs/libOpenglRender/Android.mk b/emulator/opengl/host/libs/libOpenglRender/Android.mk
index 1d923b4..787ae83 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
$(call emugl-export,CFLAGS,$(host_common_CFLAGS))
@@ -62,22 +62,24 @@ $(call emugl-end-module)
### host libOpenglRender, 64-bit #########################################
-$(call emugl-begin-host-shared-library,lib64OpenglRender)
+ifdef EMUGL_BUILD_64BITS
+ $(call emugl-begin-host64-shared-library,lib64OpenglRender)
-$(call emugl-import,lib64GLESv1_dec lib64GLESv2_dec lib64_renderControl_dec lib64OpenglCodecCommon lib64OpenglOsUtils)
+ $(call emugl-import,lib64GLESv1_dec lib64GLESv2_dec lib64_renderControl_dec lib64OpenglCodecCommon lib64OpenglOsUtils)
-#LOCAL_LDFLAGS += -m64 # adding -m64 here doesn't work, because it somehow appear BEFORE -m32 in command-line.
-LOCAL_LDLIBS += $(host_common_LDLIBS) -m64 # Put -m64 it in LOCAL_LDLIBS instead.
+ #LOCAL_LDFLAGS += -m64 # adding -m64 here doesn't work, because it somehow appear BEFORE -m32 in command-line.
+ LOCAL_LDLIBS += $(host_common_LDLIBS) -m64 # Put -m64 it in LOCAL_LDLIBS instead.
-LOCAL_SRC_FILES := $(host_common_SRC_FILES)
-$(call emugl-export,C_INCLUDES,$(EMUGL_PATH)/host/include)
-$(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
+ LOCAL_SRC_FILES := $(host_common_SRC_FILES)
+ $(call emugl-export,C_INCLUDES,$(EMUGL_PATH)/host/include)
+ $(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
-# use Translator's egl/gles headers
-LOCAL_C_INCLUDES += $(EMUGL_PATH)/host/libs/Translator/include
+ # 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
-$(call emugl-export,CFLAGS,$(host_common_CFLAGS) -m64)
+ $(call emugl-export,CFLAGS,$(host_common_CFLAGS) -m64)
-$(call emugl-end-module)
+ $(call emugl-end-module)
+endif \ No newline at end of file
diff --git a/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.cpp b/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.cpp
index 46c5acf..e612294 100644
--- a/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.cpp
+++ b/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.cpp
@@ -18,6 +18,7 @@
#include "EGLDispatch.h"
#include "GLDispatch.h"
#include "ThreadInfo.h"
+#include "GLcommon/GLutils.h"
#ifdef WITH_GLES2
#include "GL2Dispatch.h"
#endif
@@ -92,17 +93,19 @@ ColorBuffer *ColorBuffer::create(int p_width, int p_height,
cb->m_internalFormat = texInternalFormat;
if (fb->getCaps().has_eglimage_texture_2d) {
- cb->m_eglImage = s_egl.eglCreateImageKHR(fb->getDisplay(),
- s_egl.eglGetCurrentContext(),
- EGL_GL_TEXTURE_2D_KHR,
- (EGLClientBuffer)cb->m_tex,
- NULL);
-
- cb->m_blitEGLImage = s_egl.eglCreateImageKHR(fb->getDisplay(),
- s_egl.eglGetCurrentContext(),
- EGL_GL_TEXTURE_2D_KHR,
- (EGLClientBuffer)cb->m_blitTex,
- NULL);
+ cb->m_eglImage = s_egl.eglCreateImageKHR(
+ fb->getDisplay(),
+ s_egl.eglGetCurrentContext(),
+ EGL_GL_TEXTURE_2D_KHR,
+ (EGLClientBuffer)SafePointerFromUInt(cb->m_tex),
+ NULL);
+
+ cb->m_blitEGLImage = s_egl.eglCreateImageKHR(
+ fb->getDisplay(),
+ s_egl.eglGetCurrentContext(),
+ EGL_GL_TEXTURE_2D_KHR,
+ (EGLClientBuffer)SafePointerFromUInt(cb->m_blitTex),
+ NULL);
}
fb->unbind_locked();
@@ -201,7 +204,7 @@ bool ColorBuffer::blitFromCurrentReadBuffer()
// save current viewport and match it to the current
// colorbuffer size
//
- GLint vport[4];
+ GLint vport[4] = {};
s_gl.glGetIntegerv(GL_VIEWPORT, vport);
s_gl.glViewport(0, 0, m_width, m_height);
@@ -295,6 +298,7 @@ bool ColorBuffer::bind_fbo()
GL_TEXTURE_2D, m_tex, 0);
GLenum status = s_gl.glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
if (status != GL_FRAMEBUFFER_COMPLETE_OES) {
+ ERR("ColorBuffer::bind_fbo: FBO not complete: %#x\n", status);
s_gl.glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
s_gl.glDeleteFramebuffersOES(1, &m_fbo);
m_fbo = 0;
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/FBConfig.cpp b/emulator/opengl/host/libs/libOpenglRender/FBConfig.cpp
index ca7351e..08c71e8 100644
--- a/emulator/opengl/host/libs/libOpenglRender/FBConfig.cpp
+++ b/emulator/opengl/host/libs/libOpenglRender/FBConfig.cpp
@@ -67,7 +67,6 @@ InitConfigStatus FBConfig::initConfigList(FrameBuffer *fb)
return ret;
}
- const FrameBufferCaps &caps = fb->getCaps();
EGLDisplay dpy = fb->getDisplay();
if (dpy == EGL_NO_DISPLAY) {
diff --git a/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp b/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp
index cfadf12..e7a7960 100644
--- a/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp
+++ b/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp
@@ -393,7 +393,7 @@ FrameBuffer::~FrameBuffer()
void FrameBuffer::setPostCallback(OnPostFn onPost, void* onPostContext)
{
- android::Mutex::Autolock mutex(m_lock);
+ emugl::Mutex::AutoLock mutex(m_lock);
m_onPost = onPost;
m_onPostContext = onPostContext;
if (m_onPost && !m_fbImage) {
@@ -490,7 +490,7 @@ HandleType FrameBuffer::genHandle()
HandleType FrameBuffer::createColorBuffer(int p_width, int p_height,
GLenum p_internalFormat)
{
- android::Mutex::Autolock mutex(m_lock);
+ emugl::Mutex::AutoLock mutex(m_lock);
HandleType ret = 0;
ColorBufferPtr cb( ColorBuffer::create(p_width, p_height, p_internalFormat) );
@@ -505,7 +505,7 @@ HandleType FrameBuffer::createColorBuffer(int p_width, int p_height,
HandleType FrameBuffer::createRenderContext(int p_config, HandleType p_share,
bool p_isGL2)
{
- android::Mutex::Autolock mutex(m_lock);
+ emugl::Mutex::AutoLock mutex(m_lock);
HandleType ret = 0;
RenderContextPtr share(NULL);
@@ -527,7 +527,7 @@ HandleType FrameBuffer::createRenderContext(int p_config, HandleType p_share,
HandleType FrameBuffer::createWindowSurface(int p_config, int p_width, int p_height)
{
- android::Mutex::Autolock mutex(m_lock);
+ emugl::Mutex::AutoLock mutex(m_lock);
HandleType ret = 0;
WindowSurfacePtr win( WindowSurface::create(p_config, p_width, p_height) );
@@ -541,32 +541,35 @@ HandleType FrameBuffer::createWindowSurface(int p_config, int p_width, int p_hei
void FrameBuffer::DestroyRenderContext(HandleType p_context)
{
- android::Mutex::Autolock mutex(m_lock);
+ emugl::Mutex::AutoLock mutex(m_lock);
m_contexts.erase(p_context);
}
void FrameBuffer::DestroyWindowSurface(HandleType p_surface)
{
- android::Mutex::Autolock mutex(m_lock);
+ emugl::Mutex::AutoLock mutex(m_lock);
m_windows.erase(p_surface);
}
-void FrameBuffer::openColorBuffer(HandleType p_colorbuffer)
+int FrameBuffer::openColorBuffer(HandleType p_colorbuffer)
{
- android::Mutex::Autolock mutex(m_lock);
+ emugl::Mutex::AutoLock mutex(m_lock);
ColorBufferMap::iterator c(m_colorbuffers.find(p_colorbuffer));
if (c == m_colorbuffers.end()) {
// bad colorbuffer handle
- return;
+ ERR("FB: openColorBuffer cb handle %#x not found\n", p_colorbuffer);
+ return -1;
}
(*c).second.refcount++;
+ return 0;
}
void FrameBuffer::closeColorBuffer(HandleType p_colorbuffer)
{
- android::Mutex::Autolock mutex(m_lock);
+ emugl::Mutex::AutoLock mutex(m_lock);
ColorBufferMap::iterator c(m_colorbuffers.find(p_colorbuffer));
if (c == m_colorbuffers.end()) {
+ ERR("FB: closeColorBuffer cb handle %#x not found\n", p_colorbuffer);
// bad colorbuffer handle
return;
}
@@ -577,10 +580,11 @@ void FrameBuffer::closeColorBuffer(HandleType p_colorbuffer)
bool FrameBuffer::flushWindowSurfaceColorBuffer(HandleType p_surface)
{
- android::Mutex::Autolock mutex(m_lock);
+ emugl::Mutex::AutoLock mutex(m_lock);
WindowSurfaceMap::iterator w( m_windows.find(p_surface) );
if (w == m_windows.end()) {
+ ERR("FB::flushWindowSurfaceColorBuffer: window handle %#x not found\n", p_surface);
// bad surface handle
return false;
}
@@ -591,16 +595,18 @@ bool FrameBuffer::flushWindowSurfaceColorBuffer(HandleType p_surface)
bool FrameBuffer::setWindowSurfaceColorBuffer(HandleType p_surface,
HandleType p_colorbuffer)
{
- android::Mutex::Autolock mutex(m_lock);
+ emugl::Mutex::AutoLock mutex(m_lock);
WindowSurfaceMap::iterator w( m_windows.find(p_surface) );
if (w == m_windows.end()) {
// bad surface handle
+ ERR("%s: bad window surface handle %#x\n", __FUNCTION__, p_surface);
return false;
}
ColorBufferMap::iterator c( m_colorbuffers.find(p_colorbuffer) );
if (c == m_colorbuffers.end()) {
+ ERR("%s: bad color buffer handle %#x\n", __FUNCTION__, p_colorbuffer);
// bad colorbuffer handle
return false;
}
@@ -614,7 +620,7 @@ bool FrameBuffer::updateColorBuffer(HandleType p_colorbuffer,
int x, int y, int width, int height,
GLenum format, GLenum type, void *pixels)
{
- android::Mutex::Autolock mutex(m_lock);
+ emugl::Mutex::AutoLock mutex(m_lock);
ColorBufferMap::iterator c( m_colorbuffers.find(p_colorbuffer) );
if (c == m_colorbuffers.end()) {
@@ -629,7 +635,7 @@ bool FrameBuffer::updateColorBuffer(HandleType p_colorbuffer,
bool FrameBuffer::bindColorBufferToTexture(HandleType p_colorbuffer)
{
- android::Mutex::Autolock mutex(m_lock);
+ emugl::Mutex::AutoLock mutex(m_lock);
ColorBufferMap::iterator c( m_colorbuffers.find(p_colorbuffer) );
if (c == m_colorbuffers.end()) {
@@ -642,7 +648,7 @@ bool FrameBuffer::bindColorBufferToTexture(HandleType p_colorbuffer)
bool FrameBuffer::bindColorBufferToRenderbuffer(HandleType p_colorbuffer)
{
- android::Mutex::Autolock mutex(m_lock);
+ emugl::Mutex::AutoLock mutex(m_lock);
ColorBufferMap::iterator c( m_colorbuffers.find(p_colorbuffer) );
if (c == m_colorbuffers.end()) {
@@ -657,7 +663,7 @@ bool FrameBuffer::bindContext(HandleType p_context,
HandleType p_drawSurface,
HandleType p_readSurface)
{
- android::Mutex::Autolock mutex(m_lock);
+ emugl::Mutex::AutoLock mutex(m_lock);
WindowSurfacePtr draw(NULL), read(NULL);
RenderContextPtr ctx(NULL);
diff --git a/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.h b/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.h
index de0b71c..f8683b2 100644
--- a/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.h
+++ b/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.h
@@ -20,7 +20,8 @@
#include "ColorBuffer.h"
#include "RenderContext.h"
#include "WindowSurface.h"
-#include <utils/threads.h>
+#include "emugl/common/mutex.h"
+
#include <map>
#include <EGL/egl.h>
#include <stdint.h>
@@ -72,7 +73,7 @@ public:
HandleType createColorBuffer(int p_width, int p_height, GLenum p_internalFormat);
void DestroyRenderContext(HandleType p_context);
void DestroyWindowSurface(HandleType p_surface);
- void openColorBuffer(HandleType p_colorbuffer);
+ int openColorBuffer(HandleType p_colorbuffer);
void closeColorBuffer(HandleType p_colorbuffer);
bool bindContext(HandleType p_context, HandleType p_drawSurface, HandleType p_readSurface);
@@ -111,7 +112,7 @@ private:
int m_y;
int m_width;
int m_height;
- android::Mutex m_lock;
+ emugl::Mutex m_lock;
FBNativeWindowType m_nativeWindow;
FrameBufferCaps m_caps;
EGLDisplay m_eglDisplay;
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/RenderControl.cpp b/emulator/opengl/host/libs/libOpenglRender/RenderControl.cpp
index 6a15138..83ba9c5 100644
--- a/emulator/opengl/host/libs/libOpenglRender/RenderControl.cpp
+++ b/emulator/opengl/host/libs/libOpenglRender/RenderControl.cpp
@@ -215,13 +215,20 @@ static uint32_t rcCreateColorBuffer(uint32_t width,
return fb->createColorBuffer(width, height, internalFormat);
}
-static void rcOpenColorBuffer(uint32_t colorbuffer)
+static int rcOpenColorBuffer2(uint32_t colorbuffer)
{
FrameBuffer *fb = FrameBuffer::getFB();
if (!fb) {
- return;
+ return -1;
}
- fb->openColorBuffer( colorbuffer );
+ return fb->openColorBuffer( colorbuffer );
+}
+
+// Deprecated, kept for compatibility with old system images only.
+// Use rcOpenColorBuffer2 instead.
+static void rcOpenColorBuffer(uint32_t colorbuffer)
+{
+ (void) rcOpenColorBuffer2(colorbuffer);
}
static void rcCloseColorBuffer(uint32_t colorbuffer)
@@ -359,4 +366,5 @@ void initRenderControlContext(renderControl_decoder_context_t *dec)
dec->set_rcColorBufferCacheFlush(rcColorBufferCacheFlush);
dec->set_rcReadColorBuffer(rcReadColorBuffer);
dec->set_rcUpdateColorBuffer(rcUpdateColorBuffer);
+ dec->set_rcOpenColorBuffer2(rcOpenColorBuffer2);
}
diff --git a/emulator/opengl/host/libs/libOpenglRender/RenderThread.cpp b/emulator/opengl/host/libs/libOpenglRender/RenderThread.cpp
index 1b2c0fe..9ae2a43 100644
--- a/emulator/opengl/host/libs/libOpenglRender/RenderThread.cpp
+++ b/emulator/opengl/host/libs/libOpenglRender/RenderThread.cpp
@@ -94,7 +94,7 @@ int RenderThread::Main()
stats_totalBytes += readBuf.validData();
long long dt = GetCurrentTimeMS() - stats_t0;
if (dt > 1000) {
- float dts = (float)dt / 1000.0f;
+ //float dts = (float)dt / 1000.0f;
//printf("Used Bandwidth %5.3f MB/s\n", ((float)stats_totalBytes / dts) / (1024.0f*1024.0f));
stats_totalBytes = 0;
stats_t0 = GetCurrentTimeMS();
diff --git a/emulator/opengl/host/libs/libOpenglRender/ThreadInfo.cpp b/emulator/opengl/host/libs/libOpenglRender/ThreadInfo.cpp
index 566ca40..5337009 100644
--- a/emulator/opengl/host/libs/libOpenglRender/ThreadInfo.cpp
+++ b/emulator/opengl/host/libs/libOpenglRender/ThreadInfo.cpp
@@ -15,17 +15,28 @@
*/
#include "ThreadInfo.h"
-#include <cutils/threads.h>
+#include "emugl/common/lazy_instance.h"
+#include "emugl/common/thread_store.h"
-static thread_store_t s_tls = THREAD_STORE_INITIALIZER;
+namespace {
+
+class ThreadInfoStore : public ::emugl::ThreadStore {
+public:
+ ThreadInfoStore() : ::emugl::ThreadStore(NULL) {}
+};
+
+} // namespace
+
+static ::emugl::LazyInstance<ThreadInfoStore> s_tls = LAZY_INSTANCE_INIT;
RenderThreadInfo::RenderThreadInfo() {
- thread_store_set(&s_tls, this, NULL);
+ s_tls->set(this);
}
RenderThreadInfo::~RenderThreadInfo() {
+ s_tls->set(NULL);
}
RenderThreadInfo* RenderThreadInfo::get() {
- return (RenderThreadInfo*)thread_store_get(&s_tls);
+ return static_cast<RenderThreadInfo*>(s_tls->get());
}
diff --git a/emulator/opengl/host/libs/libOpenglRender/WindowSurface.cpp b/emulator/opengl/host/libs/libOpenglRender/WindowSurface.cpp
index 9c32ff8..bdda01a 100644
--- a/emulator/opengl/host/libs/libOpenglRender/WindowSurface.cpp
+++ b/emulator/opengl/host/libs/libOpenglRender/WindowSurface.cpp
@@ -58,9 +58,6 @@ WindowSurface *WindowSurface::create(int p_config, int p_width, int p_height)
}
win->m_fbconf = fbconf;
- FrameBuffer *fb = FrameBuffer::getFB();
- const FrameBufferCaps &caps = fb->getCaps();
-
//
// Create a pbuffer to be used as the egl surface
// for that window.
@@ -209,8 +206,6 @@ bool WindowSurface::resizePbuffer(unsigned int p_width, unsigned int p_height)
m_eglSurface = NULL;
}
- const FrameBufferCaps &caps = fb->getCaps();
-
//
// Create pbuffer surface.
//
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/host/libs/renderControl_dec/Android.mk b/emulator/opengl/host/libs/renderControl_dec/Android.mk
index 1063532..4a97a93 100644
--- a/emulator/opengl/host/libs/renderControl_dec/Android.mk
+++ b/emulator/opengl/host/libs/renderControl_dec/Android.mk
@@ -10,10 +10,12 @@ $(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
$(call emugl-end-module)
### host library, 64-bit ####################################
-$(call emugl-begin-host-static-library,lib64_renderControl_dec)
-$(call emugl-import,lib64OpenglCodecCommon)
-$(call emugl-gen-decoder,$(LOCAL_PATH),renderControl)
-# For renderControl_types.h
-$(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
-$(call emugl-export,CFLAGS,-m64)
-$(call emugl-end-module)
+ifdef EMUGL_BUILD_64BITS
+ $(call emugl-begin-host64-static-library,lib64_renderControl_dec)
+ $(call emugl-import,lib64OpenglCodecCommon)
+ $(call emugl-gen-decoder,$(LOCAL_PATH),renderControl)
+ # For renderControl_types.h
+ $(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
+ $(call emugl-export,CFLAGS,-m64)
+ $(call emugl-end-module)
+endif \ No newline at end of file
diff --git a/emulator/opengl/host/libs/renderControl_dec/renderControl.in b/emulator/opengl/host/libs/renderControl_dec/renderControl.in
index 8281fd9..55539f9 100644
--- a/emulator/opengl/host/libs/renderControl_dec/renderControl.in
+++ b/emulator/opengl/host/libs/renderControl_dec/renderControl.in
@@ -23,3 +23,4 @@ GL_ENTRY(void, rcBindRenderbuffer, uint32_t colorBuffer)
GL_ENTRY(EGLint, rcColorBufferCacheFlush, uint32_t colorbuffer, EGLint postCount,int forRead)
GL_ENTRY(void, rcReadColorBuffer, uint32_t colorbuffer, GLint x, GLint y, GLint width, GLint height, GLenum format, GLenum type, void *pixels)
GL_ENTRY(int, rcUpdateColorBuffer, uint32_t colorbuffer, GLint x, GLint y, GLint width, GLint height, GLenum format, GLenum type, void *pixels)
+GL_ENTRY(int, rcOpenColorBuffer2, uint32_t colorbuffer)
diff --git a/emulator/opengl/host/renderer/main.cpp b/emulator/opengl/host/renderer/main.cpp
index d2e3f72..2c3f8e2 100644
--- a/emulator/opengl/host/renderer/main.cpp
+++ b/emulator/opengl/host/renderer/main.cpp
@@ -47,7 +47,7 @@ int main(int argc, char *argv[])
int winY = 0;
int winWidth = 320;
int winHeight = 480;
- FBNativeWindowType windowId = NULL;
+ FBNativeWindowType windowId = 0;
int iWindowId = 0;
//
diff --git a/emulator/opengl/host/tools/emugen/Android.mk b/emulator/opengl/host/tools/emugen/Android.mk
index ad9ab06..e2f3939 100644
--- a/emulator/opengl/host/tools/emugen/Android.mk
+++ b/emulator/opengl/host/tools/emugen/Android.mk
@@ -1,15 +1,35 @@
-ifneq ($(HOST_OS),windows)
+# Determine if the emugen build needs to be builts from
+# sources.
+EMUGL_BUILD_EMUGEN :=
+ifeq (true,$(BUILD_STANDALONE_EMULATOR))
+ # The emulator's standalone build system can build host Linux
+ # binaries even when it targets Windows by setting
+ # LOCAL_HOST_BUILD to true, so rebuild from sources.
+ EMUGL_BUILD_EMUGEN := true
+else
+ ifneq ($(HOST_OS),windows)
+ # The platform build can only build emugen when targetting
+ # the same host sytem.
+ EMUGL_BUILD_EMUGEN := true
+ endif
+endif
LOCAL_PATH:=$(call my-dir)
+ifeq (true,$(EMUGL_BUILD_EMUGEN))
+
$(call emugl-begin-host-executable,emugen)
- LOCAL_SRC_FILES := \
- ApiGen.cpp \
- EntryPoint.cpp \
- main.cpp \
- strUtils.cpp \
- TypeFactory.cpp
+LOCAL_SRC_FILES := \
+ ApiGen.cpp \
+ EntryPoint.cpp \
+ main.cpp \
+ strUtils.cpp \
+ TypeFactory.cpp \
+
+ifeq (true,$(BUILD_STANDALONE_EMULATOR))
+LOCAL_HOST_BUILD := true
+endif
$(call emugl-end-module)
@@ -17,7 +37,7 @@ $(call emugl-end-module)
# protocol encoders/ decoders. This variable is used by other emugl modules.
EMUGL_EMUGEN := $(LOCAL_BUILT_MODULE)
-else # windows build
+else # windows platform build
# on windows use the build host emugen executable
# (that will be the linux exeutable when using mingw build)
diff --git a/emulator/opengl/host/tools/emugen/ApiGen.cpp b/emulator/opengl/host/tools/emugen/ApiGen.cpp
index 6964862..2e4c8d1 100644
--- a/emulator/opengl/host/tools/emugen/ApiGen.cpp
+++ b/emulator/opengl/host/tools/emugen/ApiGen.cpp
@@ -420,8 +420,8 @@ static void writeVarEncodingExpression(Var& var, FILE* fp)
if (!var.isVoid()) {
fprintf(fp, "\t\tmemcpy(ptr, &%s, %u); ptr += %u;\n",
varname,
- (uint) var.type()->bytes(),
- (uint) var.type()->bytes());
+ (unsigned) var.type()->bytes(),
+ (unsigned) var.type()->bytes());
}
}
}
@@ -645,7 +645,7 @@ int ApiGen::genEncoderImpl(const std::string &filename)
fprintf(fp, "\t return NULL;\n");
} else if (e->retval().type()->name() != "void") {
fprintf(fp, "\n\t%s retval;\n", e->retval().type()->name().c_str());
- fprintf(fp, "\tstream->readback(&retval, %u);\n",(uint) e->retval().type()->bytes());
+ fprintf(fp, "\tstream->readback(&retval, %u);\n",(unsigned) e->retval().type()->bytes());
fprintf(fp, "\treturn retval;\n");
}
fprintf(fp, "}\n\n");
@@ -776,12 +776,10 @@ int ApiGen::genDecoderImpl(const std::string &filename)
\tchar lastCall[256] = {0}; \n\
#endif \n\
\twhile ((len - pos >= 8) && !unknownOpcode) { \n\
-\t\tvoid *params[%u]; \n\
\t\tint opcode = *(int *)ptr; \n\
\t\tunsigned int packetLen = *(int *)(ptr + 4);\n\
\t\tif (len - pos < packetLen) return pos; \n\
-\t\tswitch(opcode) {\n",
- (uint) m_maxEntryPointsParams);
+\t\tswitch(opcode) {\n");
for (size_t f = 0; f < n; f++) {
enum Pass_t { PASS_TmpBuffAlloc = 0, PASS_MemAlloc, PASS_DebugPrint, PASS_FunctionCall, PASS_Epilog, PASS_LAST };
@@ -823,7 +821,8 @@ int ApiGen::genDecoderImpl(const std::string &filename)
}
} else if (pass == PASS_DebugPrint) {
fprintf(fp, "#ifdef DEBUG_PRINTOUT\n");
- fprintf(fp, "\t\t\tfprintf(stderr,\"%s: %s(%s)\\n\"", m_basename.c_str(), e->name().c_str(), printString.c_str());
+ fprintf(fp, "\t\t\tfprintf(stderr,\"%s(%%p): %s(%s)\\n\", stream",
+ m_basename.c_str(), e->name().c_str(), printString.c_str());
if (e->vars().size() > 0 && !e->vars()[0].isVoid()) fprintf(fp, ",");
}
@@ -845,9 +844,9 @@ int ApiGen::genDecoderImpl(const std::string &filename)
if (v->pointerDir() == Var::POINTER_IN || v->pointerDir() == Var::POINTER_INOUT) {
if (pass == PASS_MemAlloc && v->pointerDir() == Var::POINTER_INOUT) {
fprintf(fp, "\t\t\tsize_t tmpPtr%uSize = (size_t)*(unsigned int *)(ptr + %s);\n",
- (uint) j, varoffset.c_str());
+ (unsigned) j, varoffset.c_str());
fprintf(fp, "unsigned char *tmpPtr%u = (ptr + %s + 4);\n",
- (uint) j, varoffset.c_str());
+ (unsigned) j, varoffset.c_str());
}
if (pass == PASS_FunctionCall) {
if (v->nullAllowed()) {
@@ -866,30 +865,33 @@ int ApiGen::genDecoderImpl(const std::string &filename)
} else { // out pointer;
if (pass == PASS_TmpBuffAlloc) {
fprintf(fp, "\t\t\tsize_t tmpPtr%uSize = (size_t)*(unsigned int *)(ptr + %s);\n",
- (uint) j, varoffset.c_str());
+ (unsigned) j, varoffset.c_str());
if (!totalTmpBuffExist) {
- fprintf(fp, "\t\t\tsize_t totalTmpSize = tmpPtr%uSize;\n", (uint)j);
+ fprintf(fp, "\t\t\tsize_t totalTmpSize = tmpPtr%uSize;\n", (unsigned)j);
} else {
- fprintf(fp, "\t\t\ttotalTmpSize += tmpPtr%uSize;\n", (uint)j);
+ fprintf(fp, "\t\t\ttotalTmpSize += tmpPtr%uSize;\n", (unsigned)j);
}
tmpBufOffset[j] = totalTmpBuffOffset;
char tmpPtrName[16];
- sprintf(tmpPtrName," + tmpPtr%uSize", (uint)j);
+ sprintf(tmpPtrName," + tmpPtr%uSize", (unsigned)j);
totalTmpBuffOffset += std::string(tmpPtrName);
totalTmpBuffExist = true;
} else if (pass == PASS_MemAlloc) {
fprintf(fp, "\t\t\tunsigned char *tmpPtr%u = &tmpBuf[%s];\n",
- (uint)j, tmpBufOffset[j].c_str());
+ (unsigned)j, tmpBufOffset[j].c_str());
+ fprintf(fp, "\t\t\tmemset(tmpPtr%u, 0, %s);\n",
+ (unsigned)j,
+ toString(v->type()->bytes()).c_str());
} else if (pass == PASS_FunctionCall) {
if (v->nullAllowed()) {
fprintf(fp, "tmpPtr%uSize == 0 ? NULL : (%s)(tmpPtr%u)",
- (uint) j, v->type()->name().c_str(), (uint) j);
+ (unsigned) j, v->type()->name().c_str(), (unsigned) j);
} else {
- fprintf(fp, "(%s)(tmpPtr%u)", v->type()->name().c_str(), (uint) j);
+ fprintf(fp, "(%s)(tmpPtr%u)", v->type()->name().c_str(), (unsigned) j);
}
} else if (pass == PASS_DebugPrint) {
fprintf(fp, "(%s)(tmpPtr%u), *(unsigned int *)(ptr + %s)",
- v->type()->name().c_str(), (uint) j,
+ v->type()->name().c_str(), (unsigned) j,
varoffset.c_str());
}
varoffset += " + 4";
@@ -939,7 +941,7 @@ int ApiGen::genDecoderImpl(const std::string &filename)
fprintf(fp, "\t\t} //switch\n");
if (strstr(m_basename.c_str(), "gl")) {
fprintf(fp, "#ifdef CHECK_GL_ERROR\n");
- fprintf(fp, "\tint err = this->glGetError();\n");
+ fprintf(fp, "\tint err = lastCall[0] ? this->glGetError() : GL_NO_ERROR;\n");
fprintf(fp, "\tif (err) fprintf(stderr, \"%s Error: 0x%%X in %%s\\n\", err, lastCall);\n", m_basename.c_str());
fprintf(fp, "#endif\n");
}
@@ -1036,7 +1038,7 @@ int ApiGen::setGlobalAttribute(const std::string & line, size_t lc)
if (token == "base_opcode") {
std::string str = getNextToken(line, pos, &last, WHITESPACE);
if (str.size() == 0) {
- fprintf(stderr, "line %u: missing value for base_opcode\n", (uint) lc);
+ fprintf(stderr, "line %u: missing value for base_opcode\n", (unsigned) lc);
} else {
setBaseOpcode(atoi(str.c_str()));
}
diff --git a/emulator/opengl/host/tools/emugen/ApiGen.h b/emulator/opengl/host/tools/emugen/ApiGen.h
index 1627ef6..8ba18af 100644
--- a/emulator/opengl/host/tools/emugen/ApiGen.h
+++ b/emulator/opengl/host/tools/emugen/ApiGen.h
@@ -54,6 +54,8 @@ public:
case WRAPPER_SIDE:
retval = "wrapper";
break;
+ default:
+ retval = "unknown";
}
return retval;
}
diff --git a/emulator/opengl/host/tools/emugen/getopt.c b/emulator/opengl/host/tools/emugen/getopt.c
new file mode 100644
index 0000000..3523538
--- /dev/null
+++ b/emulator/opengl/host/tools/emugen/getopt.c
@@ -0,0 +1,76 @@
+#include "getopt.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#define _getprogname() nargv[0]
+
+int opterr = 1;
+int optind = 1;
+int optopt = 0;
+char* optarg;
+
+int getopt(int argc, char* const argv[], const char* ostr) {
+ static const char kEmpty[] = "";
+ static const char* place = kEmpty;
+ if (!*place) {
+ if (optind >= argc)
+ return -1;
+
+ const char* arg = argv[optind];
+ if (arg[0] != '-') {
+ // Not an option.
+ return -1;
+ }
+ if (arg[1] == '-' && !arg[2]) {
+ // '--' -> end of options.
+ return -1;
+ }
+ if (!arg[1]) {
+ // Single '-', If the program wants it, treat it as an option.
+ // Otherwise, it's the end of options.
+ if (!strchr(ostr, '-')) {
+ return -1;
+ }
+ optopt = '-';
+ place = arg + 1;
+ } else {
+ optopt = arg[1];
+ place = arg + 2;
+ }
+ };
+
+ char* oindex = strchr(ostr, optopt);
+ if (!oindex) {
+ // Unsupported option.
+ (void)fprintf(stderr, "%s: illegal option -- %c\n", argv[0]);
+ return '?';
+ }
+ if (oindex[1] != ':') {
+ // No argument needed.
+ optarg = NULL;
+ if (!*place)
+ optind++;
+ return optopt;
+ }
+
+ // This option needs an argument. Either after the option character,
+ // or the argument that follows.
+ if (*place) {
+ optarg = (char *)place;
+ } else if (argc > ++optind) {
+ optarg = (char *)argv[optind];
+ } else if (oindex[2] == ':') {
+ // Optional argument is missing.
+ place = kEmpty;
+ optarg = NULL;
+ return optopt;
+ } else {
+ // Missing argument.
+ place = kEmpty;
+ (void)fprintf(stderr, "%s: option requires an argument --%c\n",
+ argv[0], optopt);
+ return ':';
+ }
+ return optopt;
+}
diff --git a/emulator/opengl/host/tools/emugen/getopt.h b/emulator/opengl/host/tools/emugen/getopt.h
new file mode 100644
index 0000000..cc04850
--- /dev/null
+++ b/emulator/opengl/host/tools/emugen/getopt.h
@@ -0,0 +1,18 @@
+#ifndef GETOPT_H
+#define GETOPT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int optind;
+extern char* optarg;
+extern int optopt;
+
+int getopt(int argc, char* const argv[], const char* ostr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // GETOPT_H
diff --git a/emulator/opengl/host/tools/emugen/main.cpp b/emulator/opengl/host/tools/emugen/main.cpp
index 96377f2..c0c24e9 100644
--- a/emulator/opengl/host/tools/emugen/main.cpp
+++ b/emulator/opengl/host/tools/emugen/main.cpp
@@ -20,6 +20,7 @@
#include "strUtils.h"
#include "ApiGen.h"
#include "TypeFactory.h"
+#include "getopt.h"
const std::string SPEC_EXTENSION = std::string(".in");
const std::string ATTRIB_EXTENSION = std::string(".attrib");
diff --git a/emulator/opengl/sdl.mk b/emulator/opengl/sdl.mk
new file mode 100644
index 0000000..a85ed58
--- /dev/null
+++ b/emulator/opengl/sdl.mk
@@ -0,0 +1,25 @@
+# This contains common definitions used to define a host module to
+# link SDL with the EmuGL test programs.
+
+ifeq ($(BUILD_STANDALONE_EMULATOR),true)
+
+# When using the emulator standalone build, inherit the values from the
+# Makefile that included us.
+EMUGL_SDL_CFLAGS := $(SDL_CFLAGS)
+EMUGL_SDL_LDLIBS := $(SDL_LDLIBS)
+EMUGL_SDL_STATIC_LIBRARIES := emulator_libSDL emulator_libSDLmain
+
+else # BUILD_STANDALONE_EMULATOR != true
+
+# Otherwise, use the prebuilt libraries that come with the platform.
+
+EMUGL_SDL_CONFIG ?= prebuilts/tools/$(HOST_PREBUILT_TAG)/sdl/bin/sdl-config
+EMUGL_SDL_CFLAGS := $(shell $(EMUGL_SDL_CONFIG) --cflags)
+EMUGL_SDL_LDLIBS := $(filter-out %.a %.lib,$(shell $(EMUGL_SDL_CONFIG) --static-libs))
+EMUGL_SDL_STATIC_LIBRARIES := libSDL libSDLmain
+
+ifeq ($(HOST_OS),windows)
+EMUGL_SDL_LDLIBS += -lws2_32
+endif
+
+endif # BUILD_STANDALONE_EMULATOR != true
diff --git a/emulator/opengl/shared/OpenglCodecCommon/Android.mk b/emulator/opengl/shared/OpenglCodecCommon/Android.mk
index 5deb1f7..83090d8 100644
--- a/emulator/opengl/shared/OpenglCodecCommon/Android.mk
+++ b/emulator/opengl/shared/OpenglCodecCommon/Android.mk
@@ -24,19 +24,21 @@ endif
$(call emugl-begin-host-static-library,libOpenglCodecCommon)
LOCAL_SRC_FILES := $(host_commonSources)
-
-$(call emugl-export,STATIC_LIBRARIES,libcutils)
-$(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
+$(call emugl-import, libemugl_common)
+$(call emugl-export,C_INCLUDES,$(EMUGL_PATH)/host/include/libOpenglRender $(LOCAL_PATH))
+$(call emugl-export,LDLIBS,-lstdc++)
$(call emugl-end-module)
### OpenglCodecCommon host, 64-bit #########################################
-$(call emugl-begin-host-static-library,lib64OpenglCodecCommon)
+ifdef EMUGL_BUILD_64BITS
+ $(call emugl-begin-host64-static-library,lib64OpenglCodecCommon)
-LOCAL_SRC_FILES := $(host_commonSources)
-
-$(call emugl-export,STATIC_LIBRARIES,lib64cutils)
-$(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
-$(call emugl-export,CFLAGS,-m64)
-$(call emugl-end-module)
+ LOCAL_SRC_FILES := $(host_commonSources)
+ $(call emugl-import, lib64emugl_common)
+ $(call emugl-export,C_INCLUDES,$(EMUGL_PATH)/host/include/libOpenglRender $(LOCAL_PATH))
+ $(call emugl-export,CFLAGS,-m64 -fPIC)
+ $(call emugl-export,LDLIBS,-lstdc++)
+ $(call emugl-end-module)
+endif
diff --git a/emulator/opengl/shared/OpenglCodecCommon/ErrorLog.h b/emulator/opengl/shared/OpenglCodecCommon/ErrorLog.h
index 6f41fd7..4cad61f 100644
--- a/emulator/opengl/shared/OpenglCodecCommon/ErrorLog.h
+++ b/emulator/opengl/shared/OpenglCodecCommon/ErrorLog.h
@@ -16,22 +16,12 @@
#ifndef _ERROR_LOG_H_
#define _ERROR_LOG_H_
-#if (HAVE_ANDROID_OS == 1)
-# include <cutils/log.h>
-# define ERR(...) ALOGE(__VA_ARGS__)
-# ifdef EMUGL_DEBUG
-# define DBG(...) ALOGD(__VA_ARGS__)
-# else
-# define DBG(...) ((void)0)
-# endif
+#include <stdio.h>
+#define ERR(...) fprintf(stderr, __VA_ARGS__)
+#ifdef EMUGL_DEBUG
+# define DBG(...) fprintf(stderr, __VA_ARGS__)
#else
-# include <stdio.h>
-# define ERR(...) fprintf(stderr, __VA_ARGS__)
-# ifdef EMUGL_DEBUG
-# define DBG(...) fprintf(stderr, __VA_ARGS__)
-# else
-# define DBG(...) ((void)0)
-# endif
+# define DBG(...) ((void)0)
#endif
-#endif
+#endif // _ERROR_LOG_H_
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/GLDecoderContextData.h b/emulator/opengl/shared/OpenglCodecCommon/GLDecoderContextData.h
index 23785ae..d5b5189 100644
--- a/emulator/opengl/shared/OpenglCodecCommon/GLDecoderContextData.h
+++ b/emulator/opengl/shared/OpenglCodecCommon/GLDecoderContextData.h
@@ -53,12 +53,12 @@ public:
void storePointerData(unsigned int loc, void *data, size_t len) {
- assert(loc < m_nLocations);
+ assert(loc < (unsigned)m_nLocations);
m_pointerData[loc].alloc(len);
memcpy(m_pointerData[loc].ptr(), data, len);
}
void *pointerData(unsigned int loc) {
- assert(loc < m_nLocations);
+ assert(loc < (unsigned)m_nLocations);
return m_pointerData[loc].ptr();
}
private:
diff --git a/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.cpp b/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.cpp
index c7da37a..59f7b97 100644
--- a/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.cpp
+++ b/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.cpp
@@ -16,23 +16,22 @@
#include "GLSharedGroup.h"
-/**** KeyedVector utilities ****/
-
-template <typename T>
-static void clearObjectMap(android::DefaultKeyedVector<GLuint, T>& v) {
- for (size_t i = 0; i < v.size(); i++)
- delete v.valueAt(i);
- v.clear();
-}
+#include <string.h>
/**** BufferData ****/
BufferData::BufferData() : m_size(0) {};
+
BufferData::BufferData(GLsizeiptr size, void * data) : m_size(size)
{
- void * buffer = NULL;
- if (size>0) buffer = m_fixedBuffer.alloc(size);
- if (data) memcpy(buffer, data, size);
+ void* buffer = NULL;
+
+ if (size > 0) {
+ buffer = m_fixedBuffer.alloc(size);
+ if (data) {
+ memcpy(buffer, data, size);
+ }
+ }
}
/**** ProgramData ****/
@@ -204,9 +203,7 @@ bool ProgramData::attachShader(GLuint shader)
return false;
}
}
- // AKA m_shaders.push_back(), but that has an ambiguous call to insertAt()
- // due to the default parameters. This is the desired insertAt() overload.
- m_shaders.insertAt(shader, m_shaders.size(), 1);
+ m_shaders.append(shader);
return true;
}
@@ -215,7 +212,7 @@ bool ProgramData::detachShader(GLuint shader)
size_t n = m_shaders.size();
for (size_t i = 0; i < n; i++) {
if (m_shaders[i] == shader) {
- m_shaders.removeAt(i);
+ m_shaders.remove(i);
return true;
}
}
@@ -225,49 +222,32 @@ bool ProgramData::detachShader(GLuint shader)
/***** GLSharedGroup ****/
GLSharedGroup::GLSharedGroup() :
- m_buffers(android::DefaultKeyedVector<GLuint, BufferData*>(NULL)),
- m_programs(android::DefaultKeyedVector<GLuint, ProgramData*>(NULL)),
- m_shaders(android::DefaultKeyedVector<GLuint, ShaderData*>(NULL))
-{
-}
+ m_buffers(), m_programs(), m_shaders() {}
-GLSharedGroup::~GLSharedGroup()
-{
- m_buffers.clear();
- m_programs.clear();
- clearObjectMap(m_buffers);
- clearObjectMap(m_programs);
- clearObjectMap(m_shaders);
-}
+GLSharedGroup::~GLSharedGroup() {}
BufferData * GLSharedGroup::getBufferData(GLuint bufferId)
{
- android::AutoMutex _lock(m_lock);
- return m_buffers.valueFor(bufferId);
+ emugl::Mutex::AutoLock _lock(m_lock);
+ return m_buffers.get(bufferId);
}
void GLSharedGroup::addBufferData(GLuint bufferId, GLsizeiptr size, void * data)
{
- android::AutoMutex _lock(m_lock);
- m_buffers.add(bufferId, new BufferData(size, data));
+ emugl::Mutex::AutoLock _lock(m_lock);
+ m_buffers.set(bufferId, new BufferData(size, data));
}
void GLSharedGroup::updateBufferData(GLuint bufferId, GLsizeiptr size, void * data)
{
- android::AutoMutex _lock(m_lock);
- ssize_t idx = m_buffers.indexOfKey(bufferId);
- if (idx >= 0) {
- delete m_buffers.valueAt(idx);
- m_buffers.editValueAt(idx) = new BufferData(size, data);
- } else {
- m_buffers.add(bufferId, new BufferData(size, data));
- }
+ emugl::Mutex::AutoLock _lock(m_lock);
+ m_buffers.set(bufferId, new BufferData(size, data));
}
GLenum GLSharedGroup::subUpdateBufferData(GLuint bufferId, GLintptr offset, GLsizeiptr size, void * data)
{
- android::AutoMutex _lock(m_lock);
- BufferData * buf = m_buffers.valueFor(bufferId);
+ emugl::Mutex::AutoLock _lock(m_lock);
+ BufferData * buf = m_buffers.get(bufferId);
if ((!buf) || (buf->m_size < offset+size) || (offset < 0) || (size<0)) return GL_INVALID_VALUE;
//it's safe to update now
@@ -277,215 +257,197 @@ GLenum GLSharedGroup::subUpdateBufferData(GLuint bufferId, GLintptr offset, GLsi
void GLSharedGroup::deleteBufferData(GLuint bufferId)
{
- android::AutoMutex _lock(m_lock);
- ssize_t idx = m_buffers.indexOfKey(bufferId);
- if (idx >= 0) {
- delete m_buffers.valueAt(idx);
- m_buffers.removeItemsAt(idx);
- }
+ emugl::Mutex::AutoLock _lock(m_lock);
+ (void) m_buffers.remove(bufferId);
}
void GLSharedGroup::addProgramData(GLuint program)
{
- android::AutoMutex _lock(m_lock);
- ProgramData *pData = m_programs.valueFor(program);
- if (pData)
- {
- m_programs.removeItem(program);
- delete pData;
- }
-
- m_programs.add(program,new ProgramData());
+ emugl::Mutex::AutoLock _lock(m_lock);
+ m_programs.set(program, new ProgramData());
}
void GLSharedGroup::initProgramData(GLuint program, GLuint numIndexes)
{
- android::AutoMutex _lock(m_lock);
- ProgramData *pData = m_programs.valueFor(program);
- if (pData)
- {
+ emugl::Mutex::AutoLock _lock(m_lock);
+ ProgramData *pData = m_programs.get(program);
+ if (pData) {
pData->initProgramData(numIndexes);
}
}
bool GLSharedGroup::isProgramInitialized(GLuint program)
{
- android::AutoMutex _lock(m_lock);
- ProgramData* pData = m_programs.valueFor(program);
- if (pData)
- {
- return pData->isInitialized();
- }
- return false;
+ emugl::Mutex::AutoLock _lock(m_lock);
+ ProgramData* pData = m_programs.get(program);
+ return pData && pData->isInitialized();
}
void GLSharedGroup::deleteProgramData(GLuint program)
{
- android::AutoMutex _lock(m_lock);
- ProgramData *pData = m_programs.valueFor(program);
- if (pData)
- delete pData;
- m_programs.removeItem(program);
+ emugl::Mutex::AutoLock _lock(m_lock);
+ m_programs.remove(program);
}
void GLSharedGroup::attachShader(GLuint program, GLuint shader)
{
- android::AutoMutex _lock(m_lock);
- ProgramData* programData = m_programs.valueFor(program);
- ssize_t idx = m_shaders.indexOfKey(shader);
- if (programData && idx >= 0) {
- if (programData->attachShader(shader)) {
- refShaderDataLocked(idx);
- }
+ emugl::Mutex::AutoLock _lock(m_lock);
+ ProgramData* programData = m_programs.get(program);
+ if (programData && programData->attachShader(shader)) {
+ refShaderDataLocked(shader);
}
}
void GLSharedGroup::detachShader(GLuint program, GLuint shader)
{
- android::AutoMutex _lock(m_lock);
- ProgramData* programData = m_programs.valueFor(program);
- ssize_t idx = m_shaders.indexOfKey(shader);
- if (programData && idx >= 0) {
- if (programData->detachShader(shader)) {
- unrefShaderDataLocked(idx);
- }
+ emugl::Mutex::AutoLock _lock(m_lock);
+ ProgramData* programData = m_programs.get(program);
+ if (programData && programData->detachShader(shader)) {
+ unrefShaderDataLocked(shader);
}
}
-void GLSharedGroup::setProgramIndexInfo(GLuint program, GLuint index, GLint base, GLint size, GLenum type, const char* name)
+void GLSharedGroup::setProgramIndexInfo(GLuint program,
+ GLuint index,
+ GLint base,
+ GLint size,
+ GLenum type,
+ const char* name)
{
- android::AutoMutex _lock(m_lock);
- ProgramData* pData = m_programs.valueFor(program);
- if (pData)
- {
- pData->setIndexInfo(index,base,size,type);
-
- if (type == GL_SAMPLER_2D) {
- size_t n = pData->getNumShaders();
- for (size_t i = 0; i < n; i++) {
- GLuint shaderId = pData->getShader(i);
- ShaderData* shader = m_shaders.valueFor(shaderId);
- if (!shader) continue;
- ShaderData::StringList::iterator nameIter = shader->samplerExternalNames.begin();
- ShaderData::StringList::iterator nameEnd = shader->samplerExternalNames.end();
- while (nameIter != nameEnd) {
- if (*nameIter == name) {
- pData->setIndexFlags(index, ProgramData::INDEX_FLAG_SAMPLER_EXTERNAL);
- break;
- }
- ++nameIter;
+ emugl::Mutex::AutoLock _lock(m_lock);
+ ProgramData* pData = m_programs.get(program);
+ if (!pData) {
+ return;
+ }
+ pData->setIndexInfo(index,base,size,type);
+
+ if (type == GL_SAMPLER_2D) {
+ size_t n = pData->getNumShaders();
+ for (size_t i = 0; i < n; i++) {
+ GLuint shaderId = pData->getShader(i);
+ ShaderData* shader = m_shaders.get(shaderId);
+ if (!shader) continue;
+#if 0 // TODO(digit): Understand why samplerExternalNames is always empty?
+ ShaderData::StringList::iterator nameIter =
+ shader->samplerExternalNames.begin();
+ ShaderData::StringList::iterator nameEnd =
+ shader->samplerExternalNames.end();
+ while (nameIter != nameEnd) {
+ if (*nameIter == name) {
+ pData->setIndexFlags(
+ index,
+ ProgramData::INDEX_FLAG_SAMPLER_EXTERNAL);
+ break;
}
+ ++nameIter;
}
+#endif
}
}
}
+
GLenum GLSharedGroup::getProgramUniformType(GLuint program, GLint location)
{
- android::AutoMutex _lock(m_lock);
- ProgramData* pData = m_programs.valueFor(program);
- GLenum type=0;
- if (pData)
- {
- type = pData->getTypeForLocation(location);
- }
- return type;
+ emugl::Mutex::AutoLock _lock(m_lock);
+ ProgramData* pData = m_programs.get(program);
+ return pData ? pData->getTypeForLocation(location) : 0;
}
bool GLSharedGroup::isProgram(GLuint program)
{
- android::AutoMutex _lock(m_lock);
- ProgramData* pData = m_programs.valueFor(program);
- return (pData!=NULL);
+ emugl::Mutex::AutoLock _lock(m_lock);
+ ProgramData* pData = m_programs.get(program);
+ return (pData != NULL);
}
void GLSharedGroup::setupLocationShiftWAR(GLuint program)
{
- android::AutoMutex _lock(m_lock);
- ProgramData* pData = m_programs.valueFor(program);
+ emugl::Mutex::AutoLock _lock(m_lock);
+ ProgramData* pData = m_programs.get(program);
if (pData) pData->setupLocationShiftWAR();
}
-GLint GLSharedGroup::locationWARHostToApp(GLuint program, GLint hostLoc, GLint arrIndex)
+GLint GLSharedGroup::locationWARHostToApp(GLuint program,
+ GLint hostLoc,
+ GLint arrIndex)
{
- android::AutoMutex _lock(m_lock);
- ProgramData* pData = m_programs.valueFor(program);
- if (pData) return pData->locationWARHostToApp(hostLoc, arrIndex);
- else return hostLoc;
+ emugl::Mutex::AutoLock _lock(m_lock);
+ ProgramData* pData = m_programs.get(program);
+ return pData ? pData->locationWARHostToApp(hostLoc, arrIndex) : hostLoc;
}
GLint GLSharedGroup::locationWARAppToHost(GLuint program, GLint appLoc)
{
- android::AutoMutex _lock(m_lock);
- ProgramData* pData = m_programs.valueFor(program);
- if (pData) return pData->locationWARAppToHost(appLoc);
- else return appLoc;
+ emugl::Mutex::AutoLock _lock(m_lock);
+ ProgramData* pData = m_programs.get(program);
+ return pData ? pData->locationWARAppToHost(appLoc) : appLoc;
}
bool GLSharedGroup::needUniformLocationWAR(GLuint program)
{
- android::AutoMutex _lock(m_lock);
- ProgramData* pData = m_programs.valueFor(program);
- if (pData) return pData->needUniformLocationWAR();
- return false;
+ emugl::Mutex::AutoLock _lock(m_lock);
+ ProgramData* pData = m_programs.get(program);
+ return pData ? pData->needUniformLocationWAR() : false;
}
-GLint GLSharedGroup::getNextSamplerUniform(GLuint program, GLint index, GLint* val, GLenum* target) const
+GLint GLSharedGroup::getNextSamplerUniform(GLuint program,
+ GLint index,
+ GLint* val,
+ GLenum* target) const
{
- android::AutoMutex _lock(m_lock);
- ProgramData* pData = m_programs.valueFor(program);
+ emugl::Mutex::AutoLock _lock(m_lock);
+ ProgramData* pData = m_programs.get(program);
return pData ? pData->getNextSamplerUniform(index, val, target) : -1;
}
-bool GLSharedGroup::setSamplerUniform(GLuint program, GLint appLoc, GLint val, GLenum* target)
+bool GLSharedGroup::setSamplerUniform(GLuint program,
+ GLint appLoc,
+ GLint val,
+ GLenum* target)
{
- android::AutoMutex _lock(m_lock);
- ProgramData* pData = m_programs.valueFor(program);
+ emugl::Mutex::AutoLock _lock(m_lock);
+ ProgramData* pData = m_programs.get(program);
return pData ? pData->setSamplerUniform(appLoc, val, target) : false;
}
bool GLSharedGroup::addShaderData(GLuint shader)
{
- android::AutoMutex _lock(m_lock);
+ emugl::Mutex::AutoLock _lock(m_lock);
ShaderData* data = new ShaderData;
- if (data) {
- if (m_shaders.add(shader, data) < 0) {
- delete data;
- data = NULL;
- }
- data->refcount = 1;
- }
- return data != NULL;
+ data->refcount = 1;
+ m_shaders.set(shader, data);
+ return true;
}
ShaderData* GLSharedGroup::getShaderData(GLuint shader)
{
- android::AutoMutex _lock(m_lock);
- return m_shaders.valueFor(shader);
+ emugl::Mutex::AutoLock _lock(m_lock);
+ ShaderData* data = m_shaders.get(shader);
+ if (data) {
+ data->refcount++;
+ }
+ return data;
}
void GLSharedGroup::unrefShaderData(GLuint shader)
{
- android::AutoMutex _lock(m_lock);
- ssize_t idx = m_shaders.indexOfKey(shader);
- if (idx >= 0) {
- unrefShaderDataLocked(idx);
- }
+ emugl::Mutex::AutoLock _lock(m_lock);
+ unrefShaderDataLocked(shader);
}
-void GLSharedGroup::refShaderDataLocked(ssize_t shaderIdx)
+void GLSharedGroup::refShaderDataLocked(GLuint shader)
{
- assert(shaderIdx >= 0 && shaderIdx <= m_shaders.size());
- ShaderData* data = m_shaders.valueAt(shaderIdx);
- data->refcount++;
+ ShaderData* data = m_shaders.get(shader);
+ if (data) {
+ data->refcount++;
+ }
}
-void GLSharedGroup::unrefShaderDataLocked(ssize_t shaderIdx)
+void GLSharedGroup::unrefShaderDataLocked(GLuint shader)
{
- assert(shaderIdx >= 0 && shaderIdx <= m_shaders.size());
- ShaderData* data = m_shaders.valueAt(shaderIdx);
- if (--data->refcount == 0) {
- delete data;
- m_shaders.removeItemsAt(shaderIdx);
+ ShaderData* data = m_shaders.get(shader);
+ if (data && --data->refcount == 0) {
+ m_shaders.remove(shader);
}
}
diff --git a/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.h b/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.h
index 61b8f00..f111f99 100644
--- a/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.h
+++ b/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.h
@@ -16,6 +16,11 @@
#ifndef _GL_SHARED_GROUP_H_
#define _GL_SHARED_GROUP_H_
+#include "emugl/common/id_to_object_map.h"
+#include "emugl/common/mutex.h"
+#include "emugl/common/pod_vector.h"
+#include "emugl/common/smart_ptr.h"
+
#define GL_API
#ifndef ANDROID
#define GL_APIENTRY
@@ -30,18 +35,13 @@
#include <stdio.h>
#include <stdlib.h>
#include "ErrorLog.h"
-#include <utils/KeyedVector.h>
-#include <utils/List.h>
-#include <utils/String8.h>
-#include <utils/threads.h>
#include "FixedBuffer.h"
-#include "SmartPtr.h"
struct BufferData {
BufferData();
BufferData(GLsizeiptr size, void * data);
GLsizeiptr m_size;
- FixedBuffer m_fixedBuffer;
+ FixedBuffer m_fixedBuffer;
};
class ProgramData {
@@ -61,7 +61,7 @@ private:
bool m_initialized;
bool m_locShiftWAR;
- android::Vector<GLuint> m_shaders;
+ emugl::PodVector<GLuint> m_shaders;
public:
enum {
@@ -92,20 +92,22 @@ public:
};
struct ShaderData {
+#if 0 // TODO(digit): Undertand why this is never used?
typedef android::List<android::String8> StringList;
StringList samplerExternalNames;
+#endif
int refcount;
};
class GLSharedGroup {
private:
- android::DefaultKeyedVector<GLuint, BufferData*> m_buffers;
- android::DefaultKeyedVector<GLuint, ProgramData*> m_programs;
- android::DefaultKeyedVector<GLuint, ShaderData*> m_shaders;
- mutable android::Mutex m_lock;
+ emugl::IdToObjectMap<BufferData> m_buffers;
+ emugl::IdToObjectMap<ProgramData> m_programs;
+ emugl::IdToObjectMap<ShaderData> m_shaders;
+ mutable emugl::Mutex m_lock;
- void refShaderDataLocked(ssize_t shaderIdx);
- void unrefShaderDataLocked(ssize_t shaderIdx);
+ void refShaderDataLocked(GLuint shader);
+ void unrefShaderDataLocked(GLuint shader);
public:
GLSharedGroup();
@@ -138,6 +140,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/OpenglCodecCommon/SocketStream.cpp b/emulator/opengl/shared/OpenglCodecCommon/SocketStream.cpp
index f7a2314..726d359 100644
--- a/emulator/opengl/shared/OpenglCodecCommon/SocketStream.cpp
+++ b/emulator/opengl/shared/OpenglCodecCommon/SocketStream.cpp
@@ -14,7 +14,6 @@
* limitations under the License.
*/
#include "SocketStream.h"
-#include <cutils/sockets.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
@@ -53,6 +52,7 @@ SocketStream::~SocketStream()
#else
::close(m_sock);
#endif
+ m_sock = -1;
}
if (m_buf != NULL) {
free(m_buf);
@@ -112,7 +112,6 @@ int SocketStream::writeFully(const void* buffer, size_t size)
const unsigned char *SocketStream::readFully(void *buf, size_t len)
{
- const unsigned char* ret = NULL;
if (!valid()) return NULL;
if (!buf) {
return NULL; // do not allow NULL buf in that implementation
@@ -140,7 +139,7 @@ const unsigned char *SocketStream::read( void *buf, size_t *inout_len)
int n;
do {
- n = recv(buf, *inout_len);
+ n = this->recv(buf, *inout_len);
} while( n < 0 && errno == EINTR );
if (n > 0) {
diff --git a/emulator/opengl/shared/OpenglCodecCommon/TcpStream.cpp b/emulator/opengl/shared/OpenglCodecCommon/TcpStream.cpp
index 8a6e56e..ba355ab 100644
--- a/emulator/opengl/shared/OpenglCodecCommon/TcpStream.cpp
+++ b/emulator/opengl/shared/OpenglCodecCommon/TcpStream.cpp
@@ -14,7 +14,8 @@
* limitations under the License.
*/
#include "TcpStream.h"
-#include <cutils/sockets.h>
+#include "emugl/common/sockets.h"
+
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
@@ -30,77 +31,48 @@
#define LISTEN_BACKLOG 4
-TcpStream::TcpStream(size_t bufSize) :
- SocketStream(bufSize)
-{
-}
+TcpStream::TcpStream(size_t bufSize) : SocketStream(bufSize) {}
TcpStream::TcpStream(int sock, size_t bufSize) :
- SocketStream(sock, bufSize)
-{
+ SocketStream(sock, bufSize) {
// disable Nagle algorithm to improve bandwidth of small
// packets which are quite common in our implementation.
-#ifdef _WIN32
- DWORD flag;
-#else
- int flag;
-#endif
- flag = 1;
- setsockopt( sock, IPPROTO_TCP, TCP_NODELAY, (const char*)&flag, sizeof(flag) );
+ emugl::socketTcpDisableNagle(sock);
}
-int TcpStream::listen(char addrstr[MAX_ADDRSTR_LEN])
-{
- m_sock = socket_loopback_server(0, SOCK_STREAM);
+int TcpStream::listen(char addrstr[MAX_ADDRSTR_LEN]) {
+ m_sock = emugl::socketTcpLoopbackServer(0, SOCK_STREAM);
if (!valid())
return int(ERR_INVALID_SOCKET);
- /* get the actual port number assigned by the system */
- struct sockaddr_in addr;
- socklen_t addrLen = sizeof(addr);
- memset(&addr, 0, sizeof(addr));
- if (getsockname(m_sock, (struct sockaddr*)&addr, &addrLen) < 0) {
- close(m_sock);
+ int port = emugl::socketGetPort(m_sock);
+ if (port < 0) {
+ ::close(m_sock);
return int(ERR_INVALID_SOCKET);
}
- snprintf(addrstr, MAX_ADDRSTR_LEN - 1, "%hu", ntohs(addr.sin_port));
+
+ snprintf(addrstr, MAX_ADDRSTR_LEN - 1, "%hu", port);
addrstr[MAX_ADDRSTR_LEN-1] = '\0';
return 0;
}
-SocketStream * TcpStream::accept()
-{
- int clientSock = -1;
-
- while (true) {
- struct sockaddr_in addr;
- socklen_t len = sizeof(addr);
- clientSock = ::accept(m_sock, (sockaddr *)&addr, &len);
-
- if (clientSock < 0 && errno == EINTR) {
- continue;
- }
- break;
- }
+SocketStream * TcpStream::accept() {
+ int clientSock = emugl::socketAccept(m_sock);
+ if (clientSock < 0)
+ return NULL;
- TcpStream *clientStream = NULL;
-
- if (clientSock >= 0) {
- clientStream = new TcpStream(clientSock, m_bufsize);
- }
- return clientStream;
+ return new TcpStream(clientSock, m_bufsize);
}
-int TcpStream::connect(const char* addr)
-{
+int TcpStream::connect(const char* addr) {
int port = atoi(addr);
- return connect("127.0.0.1",port);
+ m_sock = emugl::socketTcpLoopbackClient(port, SOCK_STREAM);
+ return valid() ? 0 : -1;
}
int TcpStream::connect(const char* hostname, unsigned short port)
{
- m_sock = socket_network_client(hostname, port, SOCK_STREAM);
- if (!valid()) return -1;
- return 0;
+ m_sock = emugl::socketTcpClient(hostname, port, SOCK_STREAM);
+ return valid() ? 0 : -1;
}
diff --git a/emulator/opengl/shared/OpenglCodecCommon/UnixStream.cpp b/emulator/opengl/shared/OpenglCodecCommon/UnixStream.cpp
index b2eef6d..7b2f67d 100644
--- a/emulator/opengl/shared/OpenglCodecCommon/UnixStream.cpp
+++ b/emulator/opengl/shared/OpenglCodecCommon/UnixStream.cpp
@@ -14,7 +14,9 @@
* limitations under the License.
*/
#include "UnixStream.h"
-#include <cutils/sockets.h>
+
+#include "emugl/common/sockets.h"
+
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
@@ -92,7 +94,7 @@ int UnixStream::listen(char addrstr[MAX_ADDRSTR_LEN])
return -1;
}
- m_sock = socket_local_server(addrstr, ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM);
+ m_sock = emugl::socketLocalServer(addrstr, SOCK_STREAM);
if (!valid()) return int(ERR_INVALID_SOCKET);
return 0;
@@ -123,7 +125,7 @@ SocketStream * UnixStream::accept()
int UnixStream::connect(const char* addr)
{
- m_sock = socket_local_client(addr, ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM);
+ m_sock = emugl::socketLocalClient(addr, SOCK_STREAM);
if (!valid()) return -1;
return 0;
diff --git a/emulator/opengl/shared/OpenglCodecCommon/Win32PipeStream.cpp b/emulator/opengl/shared/OpenglCodecCommon/Win32PipeStream.cpp
index 76907a0..dcfb0c0 100644
--- a/emulator/opengl/shared/OpenglCodecCommon/Win32PipeStream.cpp
+++ b/emulator/opengl/shared/OpenglCodecCommon/Win32PipeStream.cpp
@@ -193,8 +193,6 @@ int Win32PipeStream::commitBuffer(size_t size)
const unsigned char *Win32PipeStream::readFully(void *buf, size_t len)
{
- const unsigned char* ret = NULL;
-
if (m_pipe == INVALID_HANDLE_VALUE)
return NULL;
diff --git a/emulator/opengl/shared/OpenglOsUtils/Android.mk b/emulator/opengl/shared/OpenglOsUtils/Android.mk
index 8a6c18b..f9673fc 100644
--- a/emulator/opengl/shared/OpenglOsUtils/Android.mk
+++ b/emulator/opengl/shared/OpenglOsUtils/Android.mk
@@ -10,6 +10,7 @@ LOCAL_PATH := $(call my-dir)
host_common_SRC_FILES := osDynLibrary.cpp
host_common_LDLIBS :=
+host_common_INCLUDES := $(LOCAL_PATH)
ifeq ($(HOST_OS),windows)
host_common_SRC_FILES += \
@@ -29,15 +30,19 @@ endif
### 32-bit host library ####
$(call emugl-begin-host-static-library,libOpenglOsUtils)
- $(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
+ $(call emugl-export,C_INCLUDES,$(host_common_INCLUDES))
LOCAL_SRC_FILES = $(host_common_SRC_FILES)
$(call emugl-export,LDLIBS,$(host_common_LDLIBS))
+ $(call emugl-import,libemugl_common)
$(call emugl-end-module)
### 64-bit host library ####
-$(call emugl-begin-host-static-library,lib64OpenglOsUtils)
- $(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
- LOCAL_SRC_FILES = $(host_common_SRC_FILES)
- $(call emugl-export,LDLIBS,$(host_common_LDLIBS))
- $(call emugl-export,CFLAGS,-m64)
-$(call emugl-end-module)
+ifdef EMUGL_BUILD_64BITS
+ $(call emugl-begin-host64-static-library,lib64OpenglOsUtils)
+ $(call emugl-export,C_INCLUDES,$(host_common_INCLUDES))
+ LOCAL_SRC_FILES = $(host_common_SRC_FILES)
+ $(call emugl-export,LDLIBS,$(host_common_LDLIBS))
+ $(call emugl-import,lib64emugl_common)
+ $(call emugl-export,CFLAGS,-m64 -fPIC)
+ $(call emugl-end-module)
+endif
diff --git a/emulator/opengl/shared/OpenglOsUtils/osThreadUnix.cpp b/emulator/opengl/shared/OpenglOsUtils/osThreadUnix.cpp
index d8879eb..ef2bebc 100644
--- a/emulator/opengl/shared/OpenglOsUtils/osThreadUnix.cpp
+++ b/emulator/opengl/shared/OpenglOsUtils/osThreadUnix.cpp
@@ -15,6 +15,10 @@
*/
#include "osThread.h"
+#include "emugl/common/thread_store.h"
+
+#include <stdint.h>
+
namespace osUtils {
Thread::Thread() :
@@ -55,9 +59,8 @@ Thread::wait(int *exitStatus)
return false;
}
- long long int ret=(long long int)retval;
if (exitStatus) {
- *exitStatus = (int)ret;
+ *exitStatus = (int)(uintptr_t)retval;
}
return true;
}
@@ -87,7 +90,8 @@ Thread::thread_main(void *p_arg)
self->m_exitStatus = ret;
pthread_mutex_unlock(&self->m_lock);
- return (void*)ret;
+ ::emugl::ThreadStore::OnThreadExit();
+ return (void*)(uintptr_t)ret;
}
} // of namespace osUtils
diff --git a/emulator/opengl/shared/OpenglOsUtils/osThreadWin.cpp b/emulator/opengl/shared/OpenglOsUtils/osThreadWin.cpp
index 2d563f8..1a30b97 100644
--- a/emulator/opengl/shared/OpenglOsUtils/osThreadWin.cpp
+++ b/emulator/opengl/shared/OpenglOsUtils/osThreadWin.cpp
@@ -15,6 +15,8 @@
*/
#include "osThread.h"
+#include "emugl/common/thread_store.h"
+
namespace osUtils {
Thread::Thread() :
@@ -95,6 +97,7 @@ Thread::thread_main(void *p_arg)
Thread *self = (Thread *)p_arg;
int ret = self->Main();
self->m_isRunning = false;
+ ::emugl::ThreadStore::OnThreadExit();
return ret;
}
diff --git a/emulator/opengl/shared/emugl/common/Android.mk b/emulator/opengl/shared/emugl/common/Android.mk
new file mode 100644
index 0000000..58dd6da
--- /dev/null
+++ b/emulator/opengl/shared/emugl/common/Android.mk
@@ -0,0 +1,54 @@
+# 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 := \
+ id_to_object_map.cpp \
+ lazy_instance.cpp \
+ pod_vector.cpp \
+ smart_ptr.cpp \
+ sockets.cpp \
+ thread_store.cpp \
+
+host_commonSources := $(commonSources)
+
+$(call emugl-begin-host-static-library,libemugl_common)
+LOCAL_SRC_FILES := $(host_commonSources)
+$(call emugl-export,C_INCLUDES,$(EMUGL_PATH)/shared)
+$(call emugl-export,LDLIBS,-lstdc++)
+$(call emugl-end-module)
+
+ifdef EMUGL_BUILD_64BITS
+ $(call emugl-begin-host64-static-library,lib64emugl_common)
+ LOCAL_SRC_FILES := $(host_commonSources)
+ $(call emugl-export,CFLAGS,-m64 -fPIC)
+ $(call emugl-export,C_INCLUDES,$(EMUGL_PATH)/shared)
+ $(call emugl-export,LDLIBS,-lstdc++)
+ $(call emugl-end-module)
+endif
+
+
+### emugl_common_unittests ##############################################
+
+host_commonSources := \
+ id_to_object_map_unittest.cpp \
+ lazy_instance_unittest.cpp \
+ pod_vector_unittest.cpp \
+ mutex_unittest.cpp \
+ smart_ptr_unittest.cpp \
+ thread_store_unittest.cpp \
+
+$(call emugl-begin-host-executable,emugl_common_host_unittests)
+LOCAL_SRC_FILES := $(host_commonSources)
+$(call emugl-import,libemugl_common libemugl_gtest)
+$(call emugl-end-module)
+
+ifdef EMUGL_BUILD_64BITS
+ $(call emugl-begin-host64-executable,emugl64_common_host_unittests)
+ LOCAL_SRC_FILES := $(host_commonSources)
+ $(call emugl-import,lib64emugl_common lib64emugl_gtest)
+ $(call emugl-end-module)
+endif
diff --git a/emulator/opengl/shared/emugl/common/id_to_object_map.cpp b/emulator/opengl/shared/emugl/common/id_to_object_map.cpp
new file mode 100644
index 0000000..597c9eb
--- /dev/null
+++ b/emulator/opengl/shared/emugl/common/id_to_object_map.cpp
@@ -0,0 +1,236 @@
+// 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/id_to_object_map.h"
+
+#include <stdlib.h>
+
+namespace emugl {
+
+namespace {
+
+typedef IdToObjectMapBase::KeyType KeyType;
+
+enum {
+ kMinShift = 3,
+ kMaxShift = 31,
+ kMinCapacity = (1 << kMinShift),
+ kLoadScale = 1024,
+ kMinLoad = kLoadScale/4, // 25% minimum load.
+ kMaxLoad = kLoadScale*3/4, // 75% maximum load.
+
+ kInvalidKey = IdToObjectMapBase::kMaxId + 1U,
+ kTombstone = IdToObjectMapBase::kMaxId + 2U,
+};
+
+// Return a number that indicates if the current |capacity| is appropriate
+// to hold |size| items in our map.
+// -1 -> the capacity is too small and needs to be increased.
+// 0 -> the capacity is ok.
+// +1 -> the capacity is too large and needs to be decreased.
+int capacityCompare(size_t shift, size_t size) {
+ size_t capacity = 1U << shift;
+ // Essentially, one can rewrite:
+ // load < minLoad
+ // as:
+ // size / capacity < minLoad
+ // capacity * minLoad > size
+ if (capacity * kMinLoad > size * kLoadScale)
+ return +1;
+
+ // Similarly, one can rewrite:
+ // load > maxLoad
+ // as:
+ // size / capacity > maxLoad
+ // capacity * maxLoad < size
+ if (capacity * kMaxLoad < size * kLoadScale)
+ return -1;
+
+ return 0;
+}
+
+size_t probeKeys(const KeyType* keys, size_t shift, KeyType key) {
+ static const int kPrimes[] = {
+ 1, /* For 1 << 0 */
+ 2,
+ 3,
+ 7,
+ 13,
+ 31,
+ 61,
+ 127,
+ 251,
+ 509,
+ 1021,
+ 2039,
+ 4093,
+ 8191,
+ 16381,
+ 32749,
+ 65521, /* For 1 << 16 */
+ 131071,
+ 262139,
+ 524287,
+ 1048573,
+ 2097143,
+ 4194301,
+ 8388593,
+ 16777213,
+ 33554393,
+ 67108859,
+ 134217689,
+ 268435399,
+ 536870909,
+ 1073741789,
+ 2147483647 /* For 1 << 31 */
+ };
+
+ size_t slot = key % kPrimes[shift];
+ size_t step = 0;
+ for (;;) {
+ KeyType k = keys[slot];
+ if (k == kInvalidKey || k == kTombstone || k == key)
+ return slot;
+
+ step += 1;
+ slot = (slot + step) & (1U << shift);
+ }
+}
+
+} // namespace
+
+IdToObjectMapBase::IdToObjectMapBase() :
+ mCount(0), mShift(kMinShift) {
+ size_t capacity = 1U << mShift;
+ mKeys = static_cast<KeyType*>(::calloc(sizeof(mKeys[0]), capacity));
+ mValues = static_cast<void**>(::calloc(sizeof(mValues[0]), capacity));
+ for (size_t n = 0; n < capacity; ++n) {
+ mKeys[n] = kInvalidKey;
+ }
+}
+
+IdToObjectMapBase::~IdToObjectMapBase() {
+ mShift = 0;
+ mCount = 0;
+ ::free(mKeys);
+ ::free(mValues);
+}
+
+bool IdToObjectMapBase::contains(KeyType key) const {
+ size_t slot = probeKeys(mKeys, mShift, key);
+ switch (mKeys[slot]) {
+ case kInvalidKey:
+ case kTombstone:
+ return false;
+ default:
+ ;
+ }
+ return true;
+}
+
+bool IdToObjectMapBase::find(KeyType key, void** value) const {
+ size_t slot = probeKeys(mKeys, mShift, key);
+ if (!isValidKey(mKeys[slot])) {
+ *value = NULL;
+ return false;
+ }
+ *value = mValues[slot];
+ return true;
+}
+
+void* IdToObjectMapBase::set(KeyType key, void* value) {
+ if (!value)
+ return remove(key);
+
+ size_t slot = probeKeys(mKeys, mShift, key);
+ void* result;
+ if (isValidKey(mKeys[slot])) {
+ result = mValues[slot];
+ mValues[slot] = value;
+ } else {
+ mKeys[slot] = key;
+ mValues[slot] = value;
+ result = NULL;
+ mCount++;
+ resize(mCount);
+ }
+ return result;
+}
+
+void* IdToObjectMapBase::remove(KeyType key) {
+ size_t slot = probeKeys(mKeys, mShift, key);
+ if (!isValidKey(mKeys[slot]))
+ return NULL;
+
+ void* result = mValues[slot];
+ mValues[slot] = NULL;
+ mKeys[slot] = kTombstone;
+ mCount--;
+ return result;
+}
+
+void IdToObjectMapBase::resize(size_t newSize) {
+ int ret = capacityCompare(mShift, newSize);
+ if (!ret)
+ return;
+
+ size_t oldCapacity = 1U << mShift;
+ size_t newShift = mShift;
+
+ if (ret < 0) {
+ // Capacity is too small and must be increased.
+ do {
+ if (newShift == kMaxShift)
+ break;
+ ++newShift;
+ } while (capacityCompare(newShift, newSize) < 0);
+ } else {
+ // Capacity is too large and must be decreased.
+ do {
+ if (newShift == kMinShift)
+ break;
+ newShift--;
+ } while (capacityCompare(newShift, newSize) > 0);
+ }
+ if (newShift == mShift)
+ return;
+
+ // Allocate new arrays.
+ size_t newCapacity = 1U << newShift;
+ KeyType* newKeys = static_cast<KeyType*>(
+ ::calloc(sizeof(newKeys[0]), newCapacity));
+ void** newValues = static_cast<void**>(
+ ::calloc(sizeof(newValues[0]), newCapacity));
+ for (size_t n = 0; n < newCapacity; ++n)
+ newKeys[n] = kInvalidKey;
+
+ // Copy old entries into new arrays.
+ for (size_t n = 0; n < oldCapacity; ++n) {
+ KeyType key = mKeys[n];
+ if (isValidKey(key)) {
+ size_t newSlot = probeKeys(newKeys, newShift, key);
+ newKeys[newSlot] = key;
+ newValues[newSlot] = mValues[n];
+ }
+ }
+
+ // Swap arrays, and get rid of old ones.
+ ::free(mKeys);
+ ::free(mValues);
+ mKeys = newKeys;
+ mValues = newValues;
+ mShift = newShift;
+}
+
+} // namespace emugl
diff --git a/emulator/opengl/shared/emugl/common/id_to_object_map.h b/emulator/opengl/shared/emugl/common/id_to_object_map.h
new file mode 100644
index 0000000..e3d0a81
--- /dev/null
+++ b/emulator/opengl/shared/emugl/common/id_to_object_map.h
@@ -0,0 +1,176 @@
+// 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_COMMON_ID_TO_OBJECT_MAP_H
+#define EMUGL_COMMON_ID_TO_OBJECT_MAP_H
+
+#include <stddef.h>
+
+namespace emugl {
+
+// Base implementation class for IdToObjectMap template.
+// Used to reduce template-instanciated code generation.
+class IdToObjectMapBase {
+public:
+ // The type of keys in this map.
+ typedef unsigned KeyType;
+
+ // Values higher than kMaxId cannot be used as map keys.
+ enum {
+ kMaxId = 0xfffffffdU,
+ };
+
+ static inline bool isValidKey(KeyType key) {
+ return key <= kMaxId;
+ }
+
+protected:
+ IdToObjectMapBase();
+
+ ~IdToObjectMapBase();
+
+ void clear();
+
+ // Return size
+ inline size_t size() const { return mCount; }
+
+ inline size_t capacity() const { return 1U << mShift; }
+
+ // Return true iff the map contains a given key.
+ bool contains(KeyType key) const;
+
+ // Find a value associated with a given |key| in the map.
+ // On success, return true and sets |*value| to the value/pointer,
+ // which is _still_ owned by the map.
+ // On failure, return false and sets |*value| to NULL.
+ bool find(KeyType key, void** value) const;
+
+ // Associate a value with a given |key| in the map.
+ // Return the old value for the key, if any. Caller is responsible
+ // for freeing it.
+ void* set(KeyType key, void* value);
+
+ // Remove the value associated with a given |key|.
+ // Return the old value, if any. Caller is responsible for
+ // freeing it.
+ void* remove(KeyType key);
+
+ size_t mCount;
+ size_t mShift;
+ KeyType* mKeys;
+ void** mValues;
+
+private:
+ // Resize the map if needed to ensure it can hold at least |newSize|
+ // entries.
+ void resize(size_t newSize);
+};
+
+// A templated data container that acts as a dictionary mapping unsigned
+// integer keys to heap-allocated objects of type T. The dictionary
+// owns the objects associated with its keys, and automatically destroys
+// them when it is destroyed, or during replacement or removal.
+template <class T>
+class IdToObjectMap : public IdToObjectMapBase {
+public:
+ // Initialize an empty instance.
+ IdToObjectMap() : IdToObjectMapBase() {}
+
+ // Destroy this instance.
+ ~IdToObjectMap() {
+ clear();
+ }
+
+ // Return the number of items in this map.
+ inline size_t size() const { return IdToObjectMapBase::size(); }
+
+ // Return true iff the map is empty.
+ inline bool empty() const { return !IdToObjectMapBase::size(); }
+
+ // Remove all items from the map.
+ void clear();
+
+ // Returns true iff the dictionary contains a value for |key|.
+ inline bool contains(KeyType key) const {
+ return IdToObjectMapBase::contains(key);
+ }
+
+ // Find the value corresponding to |key| in this map.
+ // On success, return true, and sets |*value| to point to the
+ // value (still owned by the instance). On failure, return false.
+ inline bool find(KeyType key, T** value) const {
+ return IdToObjectMapBase::find(key, reinterpret_cast<void**>(value));
+ }
+
+ // Return the value associated with a given |key|, or NULL if it is
+ // not in the map. Result is still owned by the map.
+ inline T* get(KeyType key) const {
+ T* result = NULL;
+ this->find(key, &result);
+ return result;
+ }
+
+ // Associate |value| with a given |key|. Returns true if a previous
+ // value was replaced, and false if this is the first time a value
+ // was associated with the given key. IMPORTANT: This transfers
+ // ownership of |value| to the map instance. In case of replacement,
+ // the old value is automatically destroyed. Using NULL as the value
+ // is equivalent to calling remove().
+ bool set(KeyType key, T* value);
+
+ // Remove any value associated with |key|.
+ // Return true iff a value was associated with the key and destroyed
+ // by this function, false if there was no value associated with the
+ // key (or if it was NULL).
+ bool remove(KeyType key);
+};
+
+template <class T>
+void IdToObjectMap<T>::clear() {
+ size_t n = capacity();
+ while (n > 0) {
+ --n;
+ if (!isValidKey(mKeys[n]))
+ continue;
+
+ delete static_cast<T*>(mValues[n]);
+ mValues[n] = NULL;
+ mKeys[n] = kMaxId + 1U;
+ }
+ mCount = 0;
+}
+
+template <class T>
+bool IdToObjectMap<T>::set(KeyType key, T* value) {
+ T* oldValue = static_cast<T*>(IdToObjectMapBase::set(key, value));
+ if (!oldValue) {
+ return false;
+ }
+ delete oldValue;
+ return true;
+}
+
+template <class T>
+bool IdToObjectMap<T>::remove(KeyType key) {
+ T* oldValue = static_cast<T*>(IdToObjectMapBase::remove(key));
+ if (!oldValue)
+ return false;
+ delete oldValue;
+ return true;
+}
+
+} // namespace emugl
+
+
+#endif // EMUGL_COMMON_ID_TO_OBJECT_MAP_H
diff --git a/emulator/opengl/shared/emugl/common/id_to_object_map_unittest.cpp b/emulator/opengl/shared/emugl/common/id_to_object_map_unittest.cpp
new file mode 100644
index 0000000..50740be
--- /dev/null
+++ b/emulator/opengl/shared/emugl/common/id_to_object_map_unittest.cpp
@@ -0,0 +1,116 @@
+// 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/id_to_object_map.h"
+
+#include <gtest/gtest.h>
+
+namespace emugl {
+
+namespace {
+
+typedef IdToObjectMapBase::KeyType KeyType;
+
+class Foo {
+public:
+ Foo() : mVal(0) {}
+ Foo(int val) : mVal(val) {}
+ ~Foo() {}
+ int val() const { return mVal; }
+ void setVal(int val) { mVal = val; }
+private:
+ int mVal;
+};
+
+} // namespace
+
+TEST(IdToObjectMap, Empty) {
+ IdToObjectMap<Foo> map;
+ EXPECT_TRUE(map.empty());
+ EXPECT_EQ(0U, map.size());
+}
+
+TEST(IdToObjectMap, SetIntegerRange) {
+ IdToObjectMap<Foo> map;
+ KeyType kMax = 10000;
+
+ // Add all items in the map.
+ for (KeyType n = 0; n < kMax; ++n) {
+ EXPECT_FALSE(map.set(n, new Foo(n))) << "For key " << n;
+ }
+
+ // Check final size.
+ EXPECT_EQ(static_cast<size_t>(kMax), map.size());
+
+ // Find all items in the map.
+ for (KeyType n = 0; n < kMax; ++n) {
+ EXPECT_TRUE(map.contains(n)) << "For key " << n;
+ Foo* foo = NULL;
+ EXPECT_TRUE(map.find(n, &foo)) << "For key " << n;
+ if (foo) {
+ EXPECT_EQ(static_cast<int>(n), foo->val()) << "For key " << n;
+ }
+ }
+}
+
+TEST(IdToObjectMap, RemoveAll) {
+ IdToObjectMap<Foo> map;
+ KeyType kMax = 10000;
+
+ // Add all items in the map.
+ for (KeyType n = 0; n < kMax; ++n) {
+ EXPECT_FALSE(map.set(n, new Foo(n))) << "For key " << n;
+ }
+
+ EXPECT_EQ(static_cast<size_t>(kMax), map.size());
+
+ for (KeyType n = 0; n < kMax; ++n) {
+ EXPECT_TRUE(map.remove(n)) << "For key " << n;
+ }
+ EXPECT_EQ(0U, map.size());
+}
+
+TEST(IdToObjectMap, RemoveOdd) {
+ IdToObjectMap<Foo> map;
+ KeyType kMax = 10000;
+
+ // Add all items in the map.
+ for (KeyType n = 0; n < kMax; ++n) {
+ EXPECT_FALSE(map.set(n, new Foo(n))) << "For key " << n;
+ }
+
+ EXPECT_EQ(static_cast<size_t>(kMax), map.size());
+
+ for (KeyType n = 0; n < kMax; ++n) {
+ if (n & 1) {
+ EXPECT_TRUE(map.remove(n)) << "For key " << n;
+ }
+ }
+ EXPECT_EQ(static_cast<size_t>(kMax / 2), map.size());
+
+ for (KeyType n = 0; n < kMax; ++n) {
+ if (n & 1) {
+ EXPECT_FALSE(map.contains(n)) << "For key " << n;
+ } else {
+ EXPECT_TRUE(map.contains(n)) << "For key " << n;
+ Foo* foo = NULL;
+ EXPECT_TRUE(map.find(n, &foo)) << "For key " << n;
+ if (foo) {
+ EXPECT_EQ(static_cast<int>(n), foo->val());
+ }
+ }
+ }
+}
+
+} // namespace emugl
diff --git a/emulator/opengl/shared/emugl/common/lazy_instance.cpp b/emulator/opengl/shared/emugl/common/lazy_instance.cpp
new file mode 100644
index 0000000..ee715fa
--- /dev/null
+++ b/emulator/opengl/shared/emugl/common/lazy_instance.cpp
@@ -0,0 +1,101 @@
+// 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/lazy_instance.h"
+
+#ifdef _WIN32
+# define WIN32_LEAN_AND_MEAN 1
+# include <windows.h>
+#else
+# include <sched.h>
+#endif
+
+namespace emugl {
+namespace internal {
+
+typedef LazyInstanceState::AtomicType AtomicType;
+
+#if defined(__GNUC__)
+static inline void compilerBarrier() {
+ __asm__ __volatile__ ("" : : : "memory");
+}
+#else
+#error "Your compiler is not supported"
+#endif
+
+#if defined(__i386__) || defined(__x86_64__)
+# define acquireBarrier() compilerBarrier()
+# define releaseBarrier() compilerBarrier()
+#else
+# error "Your CPU is not supported"
+#endif
+
+static inline AtomicType loadAcquire(AtomicType volatile* ptr) {
+ AtomicType ret = *ptr;
+ acquireBarrier();
+ return ret;
+}
+
+static inline void storeRelease(AtomicType volatile* ptr, AtomicType value) {
+ releaseBarrier();
+ *ptr = value;
+}
+
+static int atomicCompareAndSwap(AtomicType volatile* ptr,
+ int expected,
+ int value) {
+#ifdef _WIN32
+ return InterlockedCompareExchange(ptr, value, expected);
+#elif defined(__GNUC__)
+ return __sync_val_compare_and_swap(ptr, expected, value);
+#else
+#error "Your compiler is not supported"
+#endif
+}
+
+static void yieldThread() {
+#ifdef _WIN32
+ ::Sleep(0);
+#else
+ sched_yield();
+#endif
+}
+
+bool LazyInstanceState::inInitState() {
+ return loadAcquire(&mState) == STATE_INIT;
+}
+
+bool LazyInstanceState::needConstruction() {
+ AtomicType state = loadAcquire(&mState);
+ if (mState == STATE_DONE)
+ return false;
+
+ state = atomicCompareAndSwap(&mState, STATE_INIT, STATE_CONSTRUCTING);
+ if (state == STATE_INIT)
+ return true;
+
+ do {
+ yieldThread();
+ state = loadAcquire(&mState);
+ } while (state != STATE_DONE);
+
+ return false;
+}
+
+void LazyInstanceState::doneConstructing() {
+ storeRelease(&mState, STATE_DONE);
+}
+
+} // namespace internal
+} // namespace emugl
diff --git a/emulator/opengl/shared/emugl/common/lazy_instance.h b/emulator/opengl/shared/emugl/common/lazy_instance.h
new file mode 100644
index 0000000..6641c93
--- /dev/null
+++ b/emulator/opengl/shared/emugl/common/lazy_instance.h
@@ -0,0 +1,156 @@
+// 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_COMMON_LAZY_INSTANCE_H
+#define EMUGL_COMMON_LAZY_INSTANCE_H
+
+#include <new>
+
+#ifdef _WIN32
+# define WIN32_LEAN_AND_MEAN 1
+# include <windows.h>
+#endif
+
+namespace emugl {
+namespace internal {
+
+// A LazyInstance is a helper template that can be used to perform
+// thread-safe lazy initialization of static C++ objects without forcing
+// the generation of C++ static constructors in the final executable.
+//
+// In a nutshell, you can replace a statement like:
+//
+// static Foo gFoo;
+//
+// With:
+//
+// static LazyInstance<Foo> gFoo = LAZY_INSTANCE_INIT;
+//
+// In the first case, a hidden static C++ constructor is embedded in the
+// final executable, and executed at *load* *time* to call the Foo::Foo
+// constructor on the gFoo object.
+//
+// On the second case, gFoo will only be initialized lazily, i.e. the first
+// time any code actually tries to access the variable.
+//
+// Note that access is slightly different, i.e.:
+//
+// gFoo.get() returns a reference to the lazy-initialized object.
+// gFoo.ptr() returns a pointer to it.
+// gFoo->Something() is equivalent to doing gFoo.ptr()->Something().
+//
+// 'gFoo' is stored in the .bss section and this doesn't use heap allocation.
+// This class can only be used to perform lazy initialization through the
+// class' default constructor. For more specialized cases, you will have
+// to create a derived class, e.g.:
+//
+// class FoorWithDefaultParams : public Foo {
+// public:
+// FooWithDefaultParams() : Foo(<default-parameters>) {}
+// };
+//
+// LazyInstance<FooWithDefaultParams> gFoo = LAZY_INSTANCE_INIT;
+//
+// The implementation of LazyInstance relies on atomic operations and
+// POD-struct class definitions, i.e. one that doesn't have any constructor,
+// destructor, virtual members, or private ones, and that can be
+// zero-initialized at link time.
+//
+// You can also use LazyInstance<> instances as static local variables,
+// e.g.:
+//
+// Foo* getFooSingleton() {
+// static LazyInstance<Foo> sFoo = LAZY_INSTANCE_INIT;
+// return sFoo.ptr();
+// }
+//
+// This is useful on Windows which doesn't support thread-safe lazy
+// initialization of static C++ local variables, or when the code is
+// compiled with -fno-threadsafe-statics.
+//
+// This class is heavily inspired by Chromium's implementation of the
+// same-named class (see $CHROMIUM/src/base/lazy_instance.h).
+
+// Atomic state variable type. Used to ensure to synchronize concurrent
+// initialization and access without incurring the full cost of a mutex
+// lock/unlock.
+struct LazyInstanceState {
+ enum {
+ STATE_INIT = 0,
+ STATE_CONSTRUCTING = 1,
+ STATE_DONE = 2,
+ };
+
+ bool inInitState();
+ bool needConstruction();
+ void doneConstructing();
+
+#ifdef _WIN32
+ typedef LONG volatile AtomicType;
+#else
+ typedef int volatile AtomicType;
+#endif
+
+ volatile AtomicType mState;
+};
+
+#define LAZY_INSTANCE_STATE_INIT \
+ { ::emugl::internal::LazyInstanceState::STATE_INIT }
+
+} // namespace internal
+
+// LazyInstance template definition, see comment above for usage
+// instructions. It is crucial to make this a POD-struct compatible
+// type [1].
+//
+// [1] http://en.wikipedia.org/wiki/Plain_Old_Data_Structures
+//
+template <class T>
+struct LazyInstance {
+ bool hasInstance() const { return !mState.inInitState(); }
+
+ T& get() const { return *ptr(); }
+
+ T* ptr() const;
+
+ const T* operator->() const { return ptr(); }
+
+ T* operator->() { return ptr(); }
+
+ T& operator*() { return get(); }
+
+ // Really private, do not use.
+ union {
+ mutable internal::LazyInstanceState mState;
+ double mPadding;
+ };
+ mutable char mStorage[sizeof(T)];
+};
+
+// Initialization value, must resolve to all-0 to ensure the object
+// instance is actually placed in the .bss
+#define LAZY_INSTANCE_INIT { { LAZY_INSTANCE_STATE_INIT }, { 0 } }
+
+template <class T>
+T* LazyInstance<T>::ptr() const {
+ if (mState.needConstruction()) {
+ new (mStorage) T();
+ mState.doneConstructing();
+ }
+ return reinterpret_cast<T*>(mStorage);
+}
+
+} // namespace emugl
+
+#endif // EMUGL_COMMON_LAZY_INSTANCE_H
diff --git a/emulator/opengl/shared/emugl/common/lazy_instance_unittest.cpp b/emulator/opengl/shared/emugl/common/lazy_instance_unittest.cpp
new file mode 100644
index 0000000..824845f
--- /dev/null
+++ b/emulator/opengl/shared/emugl/common/lazy_instance_unittest.cpp
@@ -0,0 +1,146 @@
+// 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/lazy_instance.h"
+
+#include "emugl/common/mutex.h"
+#include "emugl/common/testing/test_thread.h"
+
+#include <gtest/gtest.h>
+
+namespace emugl {
+
+namespace {
+
+class Foo {
+public:
+ Foo() : mValue(42) {}
+ int get() const { return mValue; }
+ void set(int value) { mValue = value; }
+ ~Foo() { mValue = 13; }
+private:
+ int mValue;
+};
+
+class StaticCounter {
+public:
+ StaticCounter() {
+ Mutex::AutoLock lock(mMutex);
+ mCounter++;
+ }
+
+ int getValue() const {
+ Mutex::AutoLock lock(mMutex);
+ return mCounter;
+ }
+
+private:
+ static Mutex mMutex;
+ static int mCounter;
+};
+
+// NOTE: This introduces a static C++ constructor for this object file,
+// but that's ok because a LazyInstance<Mutex> should not be used to
+// test the behaviour of LazyInstance :-)
+Mutex StaticCounter::mMutex;
+int StaticCounter::mCounter = 0;
+
+} // namespace
+
+TEST(LazyInstance, HasInstance) {
+ LazyInstance<Foo> foo_instance = LAZY_INSTANCE_INIT;
+ EXPECT_FALSE(foo_instance.hasInstance());
+ EXPECT_FALSE(foo_instance.hasInstance());
+ foo_instance.ptr();
+ EXPECT_TRUE(foo_instance.hasInstance());
+}
+
+TEST(LazyInstance, Simple) {
+ LazyInstance<Foo> foo_instance = LAZY_INSTANCE_INIT;
+ Foo* foo1 = foo_instance.ptr();
+ EXPECT_TRUE(foo1);
+ EXPECT_EQ(42, foo_instance->get());
+ foo1->set(10);
+ EXPECT_EQ(10, foo_instance->get());
+ EXPECT_EQ(foo1, foo_instance.ptr());
+}
+
+// For the following test, launch 1000 threads that each try to get
+// the instance pointer of a lazy instance. Then verify that they're all
+// the same value.
+//
+// The lazy instance has a special constructor that will increment a
+// global counter. This allows us to ensure that it is only called once.
+//
+
+namespace {
+
+// The following is the shared structure between all threads.
+struct MultiState {
+ MultiState(LazyInstance<StaticCounter>* staticCounter) :
+ mMutex(), mStaticCounter(staticCounter), mCount(0) {}
+
+ enum {
+ kMaxThreads = 1000,
+ };
+
+ Mutex mMutex;
+ LazyInstance<StaticCounter>* mStaticCounter;
+ size_t mCount;
+ void* mValues[kMaxThreads];
+ TestThread* mThreads[kMaxThreads];
+};
+
+// The thread function for the test below.
+static void* threadFunc(void* param) {
+ MultiState* state = static_cast<MultiState*>(param);
+ Mutex::AutoLock lock(state->mMutex);
+ if (state->mCount < MultiState::kMaxThreads) {
+ state->mValues[state->mCount++] = state->mStaticCounter->ptr();
+ }
+ return NULL;
+}
+
+} // namespace
+
+TEST(LazyInstance, MultipleThreads) {
+ LazyInstance<StaticCounter> counter_instance = LAZY_INSTANCE_INIT;
+ MultiState state(&counter_instance);
+ const size_t kNumThreads = MultiState::kMaxThreads;
+
+ // Create all threads.
+ for (size_t n = 0; n < kNumThreads; ++n) {
+ state.mThreads[n] = new TestThread(threadFunc, &state);
+ }
+
+ // Wait for their completion.
+ for (size_t n = 0; n < kNumThreads; ++n) {
+ state.mThreads[n]->join();
+ }
+
+ // Now check that the constructor was only called once.
+ EXPECT_EQ(1, counter_instance->getValue());
+
+ // Now compare all the store values, they should be the same.
+ StaticCounter* expectedValue = counter_instance.ptr();
+ for (size_t n = 0; n < kNumThreads; ++n) {
+ EXPECT_EQ(expectedValue, state.mValues[n]) << "For thread " << n;
+ }
+
+ for (size_t n = 0; n < kNumThreads; ++n) {
+ delete state.mThreads[n];
+ }
+}
+
+} // namespace emugl
diff --git a/emulator/opengl/shared/emugl/common/mutex.h b/emulator/opengl/shared/emugl/common/mutex.h
new file mode 100644
index 0000000..c6cdcf2
--- /dev/null
+++ b/emulator/opengl/shared/emugl/common/mutex.h
@@ -0,0 +1,92 @@
+// 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_MUTEX_H
+#define EMUGL_MUTEX_H
+
+#ifdef _WIN32
+# define WIN32_LEAN_AND_MEAN 1
+# include <windows.h>
+#else
+# include <pthread.h>
+#endif
+
+namespace emugl {
+
+// Simple wrapper class for mutexes.
+class Mutex {
+public:
+ // Constructor.
+ Mutex() {
+#ifdef _WIN32
+ ::InitializeCriticalSection(&mLock);
+#else
+ ::pthread_mutex_init(&mLock, NULL);
+#endif
+ }
+
+ // Destructor.
+ ~Mutex() {
+#ifdef _WIN32
+ ::DeleteCriticalSection(&mLock);
+#else
+ ::pthread_mutex_destroy(&mLock);
+#endif
+ }
+
+ // Acquire the mutex.
+ void lock() {
+#ifdef _WIN32
+ ::EnterCriticalSection(&mLock);
+#else
+ ::pthread_mutex_lock(&mLock);
+#endif
+ }
+
+ // Release the mutex.
+ void unlock() {
+#ifdef _WIN32
+ ::LeaveCriticalSection(&mLock);
+#else
+ ::pthread_mutex_unlock(&mLock);
+#endif
+ }
+
+ // Helper class to lock / unlock a mutex automatically on scope
+ // entry and exit.
+ class AutoLock {
+ public:
+ AutoLock(Mutex& mutex) : mMutex(&mutex) {
+ mMutex->lock();
+ }
+
+ ~AutoLock() {
+ mMutex->unlock();
+ }
+ private:
+ Mutex* mMutex;
+ };
+
+private:
+#ifdef _WIN32
+ CRITICAL_SECTION mLock;
+#else
+ pthread_mutex_t mLock;
+#endif
+
+};
+
+} // namespace emugl
+
+#endif // EMUGL_MUTEX_H
diff --git a/emulator/opengl/shared/emugl/common/mutex_unittest.cpp b/emulator/opengl/shared/emugl/common/mutex_unittest.cpp
new file mode 100644
index 0000000..e952d75
--- /dev/null
+++ b/emulator/opengl/shared/emugl/common/mutex_unittest.cpp
@@ -0,0 +1,108 @@
+// 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/mutex.h"
+
+#include "emugl/common/testing/test_thread.h"
+
+#include <gtest/gtest.h>
+
+namespace emugl {
+
+// Check that construction and destruction doesn't crash.
+TEST(Mutex, ConstructionDestruction) {
+ Mutex lock;
+}
+
+// Check that a simple lock + unlock works.
+TEST(Mutex, LockUnlock) {
+ Mutex lock;
+ lock.lock();
+ lock.unlock();
+}
+
+// Check that AutoLock compiles and doesn't crash.
+TEST(Mutex, AutoLock) {
+ Mutex mutex;
+ Mutex::AutoLock lock(mutex);
+}
+
+// Wrapper class for threads. Does not use emugl::Thread intentionally.
+// Common data type used by the following tests below.
+struct ThreadParams {
+ ThreadParams() : mutex(), counter(0) {}
+
+ Mutex mutex;
+ int counter;
+};
+
+// This thread function uses Mutex::lock/unlock to synchronize a counter
+// increment operation.
+static void* threadFunction(void* param) {
+ ThreadParams* p = static_cast<ThreadParams*>(param);
+
+ p->mutex.lock();
+ p->counter++;
+ p->mutex.unlock();
+ return NULL;
+}
+
+TEST(Mutex, Synchronization) {
+ const size_t kNumThreads = 2000;
+ TestThread* threads[kNumThreads];
+ ThreadParams p;
+
+ // Create and launch all threads.
+ for (size_t n = 0; n < kNumThreads; ++n) {
+ threads[n] = new TestThread(threadFunction, &p);
+ }
+
+ // Wait until their completion.
+ for (size_t n = 0; n < kNumThreads; ++n) {
+ threads[n]->join();
+ delete threads[n];
+ }
+
+ EXPECT_EQ(static_cast<int>(kNumThreads), p.counter);
+}
+
+// This thread function uses a Mutex::AutoLock to protect the counter.
+static void* threadAutoLockFunction(void* param) {
+ ThreadParams* p = static_cast<ThreadParams*>(param);
+
+ Mutex::AutoLock lock(p->mutex);
+ p->counter++;
+ return NULL;
+}
+
+TEST(Mutex, AutoLockSynchronization) {
+ const size_t kNumThreads = 2000;
+ TestThread* threads[kNumThreads];
+ ThreadParams p;
+
+ // Create and launch all threads.
+ for (size_t n = 0; n < kNumThreads; ++n) {
+ threads[n] = new TestThread(threadAutoLockFunction, &p);
+ }
+
+ // Wait until their completion.
+ for (size_t n = 0; n < kNumThreads; ++n) {
+ threads[n]->join();
+ delete threads[n];
+ }
+
+ EXPECT_EQ(static_cast<int>(kNumThreads), p.counter);
+}
+
+} // namespace emugl
diff --git a/emulator/opengl/shared/emugl/common/pod_vector.cpp b/emulator/opengl/shared/emugl/common/pod_vector.cpp
new file mode 100644
index 0000000..c8ec3a6
--- /dev/null
+++ b/emulator/opengl/shared/emugl/common/pod_vector.cpp
@@ -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.
+
+#include "emugl/common/pod_vector.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#define USE_MALLOC_USABLE_SIZE 0
+
+namespace emugl {
+
+static inline void swapPointers(char** p1, char** p2) {
+ char* tmp = *p1;
+ *p1 = *p2;
+ *p2 = tmp;
+}
+
+PodVectorBase::PodVectorBase(const PodVectorBase& other) {
+ initFrom(other.begin(), other.byteSize());
+}
+
+PodVectorBase& PodVectorBase::operator=(const PodVectorBase& other) {
+ initFrom(other.begin(), other.byteSize());
+ return *this;
+}
+
+PodVectorBase::~PodVectorBase() {
+ if (mBegin) {
+ // Sanity.
+ ::memset(mBegin, 0xee, byteSize());
+ ::free(mBegin);
+ mBegin = NULL;
+ mEnd = NULL;
+ mLimit = NULL;
+ }
+}
+
+void PodVectorBase::initFrom(const void* from, size_t fromLen) {
+ if (!fromLen || !from) {
+ mBegin = NULL;
+ mEnd = NULL;
+ mLimit = NULL;
+ } else {
+ mBegin = static_cast<char*>(::malloc(fromLen));
+ mEnd = mLimit = mBegin + fromLen;
+ ::memcpy(mBegin, from, fromLen);
+ }
+}
+
+void PodVectorBase::assignFrom(const PodVectorBase& other) {
+ resize(other.byteSize(), 1U);
+ ::memmove(begin(), other.begin(), byteSize());
+}
+
+void PodVectorBase::resize(size_t newSize, size_t itemSize) {
+ const size_t kMaxSize = maxItemCapacity(itemSize);
+ size_t oldCapacity = itemCapacity(itemSize);
+ const size_t kMinCapacity = 256 / itemSize;
+
+ if (newSize < oldCapacity) {
+ // Only shrink if the new size is really small.
+ if (newSize < oldCapacity / 2 && oldCapacity > kMinCapacity) {
+ reserve(newSize, itemSize);
+ }
+ } else if (newSize > oldCapacity) {
+ size_t newCapacity = oldCapacity;
+ while (newCapacity < newSize) {
+ size_t newCapacity2 = newCapacity + (newCapacity >> 2) + 8;
+ if (newCapacity2 < newCapacity || newCapacity > kMaxSize) {
+ newCapacity = kMaxSize;
+ } else {
+ newCapacity = newCapacity2;
+ }
+ }
+ reserve(newCapacity, itemSize);
+ }
+ mEnd = mBegin + newSize * itemSize;
+}
+
+void PodVectorBase::reserve(size_t newSize, size_t itemSize) {
+ if (newSize == 0) {
+ ::free(mBegin);
+ mBegin = NULL;
+ mEnd = NULL;
+ mLimit = NULL;
+ return;
+ }
+
+ size_t oldByteSize = byteSize();
+ size_t newByteCapacity = newSize * itemSize;
+ char* newBegin = static_cast<char*>(::realloc(mBegin, newByteCapacity));
+ mBegin = newBegin;
+ mEnd = newBegin + oldByteSize;
+#if USE_MALLOC_USABLE_SIZE
+ size_t usableSize = malloc_usable_size(mBegin);
+ if (usableSize > newByteCapacity) {
+ newByteCapacity = usableSize - (usableSize % itemSize);
+ }
+#endif
+ mLimit = newBegin + newByteCapacity;
+ // Sanity.
+ if (newByteCapacity > oldByteSize) {
+ ::memset(mBegin + oldByteSize, 0, newByteCapacity - oldByteSize);
+ }
+}
+
+void PodVectorBase::removeAt(size_t itemPos, size_t itemSize) {
+ size_t count = itemCount(itemSize);
+ if (itemPos < count) {
+ size_t pos = itemPos * itemSize;
+ ::memmove(mBegin + pos,
+ mBegin + pos + itemSize,
+ byteSize() - pos - itemSize);
+ resize(count - 1U, itemSize);
+ }
+}
+
+void* PodVectorBase::insertAt(size_t itemPos, size_t itemSize) {
+ size_t count = this->itemCount(itemSize);
+ resize(count + 1, itemSize);
+ size_t pos = itemPos * itemSize;
+ if (itemPos < count) {
+ ::memmove(mBegin + pos + itemSize,
+ mBegin + pos,
+ count * itemSize - pos);
+ // Sanity to avoid copying pointers and other bad stuff.
+ ::memset(mBegin + pos, 0, itemSize);
+ }
+ return mBegin + pos;
+}
+
+void PodVectorBase::swapAll(PodVectorBase* other) {
+ swapPointers(&mBegin, &other->mBegin);
+ swapPointers(&mEnd, &other->mEnd);
+ swapPointers(&mLimit, &other->mLimit);
+}
+
+} // namespace emugl
diff --git a/emulator/opengl/shared/emugl/common/pod_vector.h b/emulator/opengl/shared/emugl/common/pod_vector.h
new file mode 100644
index 0000000..c4e184b
--- /dev/null
+++ b/emulator/opengl/shared/emugl/common/pod_vector.h
@@ -0,0 +1,265 @@
+// 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_COMMON_POD_VECTOR_H
+#define EMUGL_COMMON_POD_VECTOR_H
+
+
+#include <stddef.h>
+
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+#ifndef __STDC_FORMAT_MACROS
+#define __STDC_FORMAT_MACROS 1
+#endif
+#include <stdint.h>
+
+#ifndef SIZE_MAX
+#error "You must define __STDC_LIMIT_MACROS before including <stddint.h>"
+#endif
+
+namespace emugl {
+
+// A PodVector is a templated vector-like type that is used to store
+// POD-struct compatible items only. This allows the implementation to
+// use ::memmove() to move items, and also malloc_usable_size() to
+// determine the best capacity.
+//
+// std::vector<> is capable of doing this in theory, using horrible
+// templating tricks that make error messages very difficult to
+// understand.
+//
+// Note that a PodVector can be used to store items that contain pointers,
+// as long as these do not point to items in the same container.
+//
+// The PodVector provides methods that also follow the std::vector<>
+// conventions, i.e. push_back() is an alias for append().
+//
+
+// NOTE: This is a re-implementation of
+// external/qemu/android/base/containers/PodVector.h for emugl.
+
+// PodVectorBase is a base, non-templated, implementation class that all
+// PodVector instances derive from. This is used to reduce template
+// specialization. Do not use directly, i..e it's an implementation detail.
+class PodVectorBase {
+protected:
+ PodVectorBase() : mBegin(NULL), mEnd(NULL), mLimit(NULL) {}
+ explicit PodVectorBase(const PodVectorBase& other);
+ PodVectorBase& operator=(const PodVectorBase& other);
+ ~PodVectorBase();
+
+ bool empty() const { return mEnd == mBegin; }
+
+ size_t byteSize() const { return mEnd - mBegin; }
+
+ size_t byteCapacity() const { return mLimit - mBegin; }
+
+ void* begin() { return mBegin; }
+ const void* begin() const { return mBegin; }
+ void* end() { return mEnd; }
+ const void* end() const { return mEnd; }
+
+ void* itemAt(size_t pos, size_t itemSize) {
+ return mBegin + pos * itemSize;
+ }
+
+ const void* itemAt(size_t pos, size_t itemSize) const {
+ return mBegin + pos * itemSize;
+ }
+
+ void assignFrom(const PodVectorBase& other);
+
+ inline size_t itemCount(size_t itemSize) const {
+ return byteSize() / itemSize;
+ }
+
+ inline size_t itemCapacity(size_t itemSize) const {
+ return byteCapacity() / itemSize;
+ }
+
+ inline size_t maxItemCapacity(size_t itemSize) const {
+ return SIZE_MAX / itemSize;
+ }
+
+ void resize(size_t newSize, size_t itemSize);
+ void reserve(size_t newSize, size_t itemSize);
+
+ void removeAt(size_t index, size_t itemSize);
+ void* insertAt(size_t index, size_t itemSize);
+ void swapAll(PodVectorBase* other);
+
+ char* mBegin;
+ char* mEnd;
+ char* mLimit;
+
+private:
+ void initFrom(const void* from, size_t fromLen);
+};
+
+
+// A PodVector<T> holds a vector (dynamically resizable array) or items
+// that must be POD-struct compatible (i.e. they cannot have constructors,
+// destructors, or virtual members). This allows the implementation to be
+// small, fast and efficient, memory-wise.
+//
+// If you want to implement a vector of C++ objects, consider using
+// std::vector<> instead, but keep in mind that this implies a non-trivial
+// cost when appending, inserting, removing items in the collection.
+//
+template <typename T>
+class PodVector : public PodVectorBase {
+public:
+ // Default constructor for an empty PodVector<T>
+ PodVector() : PodVectorBase() {}
+
+ // Copy constructor. This copies all items from |other| into
+ // the new instance with ::memmove().
+ PodVector(const PodVector& other) : PodVectorBase(other) {}
+
+ // Assignment operator.
+ PodVector& operator=(const PodVector& other) {
+ this->assignFrom(other);
+ return *this;
+ }
+
+ // Destructor, this simply releases the internal storage block that
+ // holds all the items, but doesn't touch them otherwise.
+ ~PodVector() {}
+
+ // Return true iff the PodVector<T> instance is empty, i.e. does not
+ // have any items.
+ bool empty() const { return PodVectorBase::empty(); }
+
+ // Return the number of items in the current PodVector<T> instance.
+ size_t size() const { return PodVectorBase::itemCount(sizeof(T)); }
+
+ // Return the current capacity in the current PodVector<T> instance.
+ // Do not use directly, except if you know what you're doing. Try to
+ // use resize() or reserve() instead.
+ size_t capacity() const {
+ return PodVectorBase::itemCapacity(sizeof(T));
+ }
+
+ // Return the maximum capacity of any PodVector<T> instance.
+ static inline size_t maxCapacity() { return SIZE_MAX / sizeof(T); }
+
+ // Resize the vector to ensure it can hold |newSize|
+ // items. This may or may not call reserve() under the hood.
+ // It's a fatal error to try to resize above maxCapacity().
+ void resize(size_t newSize) {
+ PodVectorBase::resize(newSize, sizeof(T));
+ }
+
+ // Resize the vector's storage array to ensure that it can hold at
+ // least |newSize| items. It's a fatal error to try to resize above
+ // maxCapacity().
+ void reserve(size_t newSize) {
+ PodVectorBase::reserve(newSize, sizeof(T));
+ }
+
+ // Return a pointer to the first item in the vector. This is only
+ // valid until the next call to any function that changes the size
+ // or capacity of the vector. Can be NULL if the vector is empty.
+ T* begin() {
+ return reinterpret_cast<T*>(PodVectorBase::begin());
+ }
+
+ // Return a constant pointer to the first item in the vector. This is
+ // only valid until the next call to any function that changes the
+ // size of capacity of the vector.
+ const T* begin() const {
+ return reinterpret_cast<T*>(PodVectorBase::begin());
+ }
+
+ // Return a pointer past the last item in the vector. I.e. if the
+ // result is not NULL, then |result - 1| points to the last item.
+ // Can be NULL if the vector is empty.
+ T* end() {
+ return reinterpret_cast<T*>(PodVectorBase::end());
+ }
+
+ // Return a constant pointer past the last item in the vector. I.e. if
+ // the result is not NULL, then |result - 1| points to the last item.
+ // Can be NULL if the vector is empty.
+ const T* end() const {
+ return reinterpret_cast<T*>(PodVectorBase::end());
+ }
+
+ // Returns a reference to the item a position |index| in the vector.
+ // It may be a fatal error to access an out-of-bounds position.
+ T& operator[](size_t index) {
+ return *reinterpret_cast<T*>(
+ PodVectorBase::itemAt(index, sizeof(T)));
+ }
+
+ const T& operator[](size_t index) const {
+ return *reinterpret_cast<const T*>(
+ PodVectorBase::itemAt(index, sizeof(T)));
+ }
+
+ // Increase the vector's size by 1, then move all items past a given
+ // position to the right. Return the position of the insertion point
+ // to let the caller copy the content it desires there. It's preferrable
+ // to use insert() directly, which will do the item copy for you.
+ T* emplace(size_t index) {
+ return reinterpret_cast<T*>(
+ PodVectorBase::insertAt(index, sizeof(T)));
+ }
+
+ // Insert an item at a given position. |index| is the insertion position
+ // which must be between 0 and size() included, or a fatal error may
+ // occur. |item| is a reference to an item to copy into the array,
+ // byte-by-byte.
+ void insert(size_t index, const T& item) {
+ *(this->emplace(index)) = item;
+ }
+
+ // Prepend an item at the start of a vector. This moves all vector items
+ // to the right, and is thus costly. |item| is a reference to an item
+ // to copy to the start of the vector.
+ void prepend(const T& item) {
+ *(this->emplace(0U)) = item;
+ }
+
+ // Append an item at the end of a vector. Specialized version of insert()
+ // which always uses size() as the insertion position.
+ void append(const T& item) {
+ *(this->emplace(this->size())) = item;
+ }
+
+ // Remove the item at a given position. |index| is the position of the
+ // item to delete. It must be between 0 and size(), included, or
+ // a fatal error may occur. Deleting the item at position size()
+ // doesn't do anything.
+ void remove(size_t index) {
+ PodVectorBase::removeAt(index, sizeof(T));
+ }
+
+ void swap(PodVector* other) {
+ PodVectorBase::swapAll(other);
+ }
+
+ // Compatibility methods for std::vector<>
+ void push_back(const T& item) { append(item); }
+ void pop() { remove(0U); }
+
+ typedef T* iterator;
+ typedef const T* const_iterator;
+};
+
+} // namespace emugl
+
+#endif // EMUGL_COMMON_POD_VECTOR_H
diff --git a/emulator/opengl/shared/emugl/common/pod_vector_unittest.cpp b/emulator/opengl/shared/emugl/common/pod_vector_unittest.cpp
new file mode 100644
index 0000000..9ce509a
--- /dev/null
+++ b/emulator/opengl/shared/emugl/common/pod_vector_unittest.cpp
@@ -0,0 +1,127 @@
+// 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/pod_vector.h"
+
+#include <gtest/gtest.h>
+
+namespace emugl {
+
+static int hashIndex(size_t n) {
+ return static_cast<int>(((n >> 14) * 13773) + (n * 51));
+}
+
+TEST(PodVector, Empty) {
+ PodVector<int> v;
+ EXPECT_TRUE(v.empty());
+ EXPECT_EQ(0U, v.size());
+}
+
+TEST(PodVector, AppendOneItem) {
+ PodVector<int> v;
+ v.append(10234);
+ EXPECT_FALSE(v.empty());
+ EXPECT_EQ(1U, v.size());
+ EXPECT_EQ(10234, v[0]);
+}
+
+TEST(PodVector, AppendLotsOfItems) {
+ PodVector<int> v;
+ const size_t kMaxCount = 10000;
+ for (size_t n = 0; n < kMaxCount; ++n) {
+ v.append(hashIndex(n));
+ }
+ EXPECT_EQ(kMaxCount, v.size());
+ for (size_t n = 0; n < kMaxCount; ++n) {
+ EXPECT_EQ(hashIndex(n), v[n]) << "At index " << n;
+ }
+}
+
+TEST(PodVector, RemoveFrontItems) {
+ PodVector<int> v;
+ const size_t kMaxCount = 100;
+ for (size_t n = 0; n < kMaxCount; ++n) {
+ v.append(hashIndex(n));
+ }
+ EXPECT_EQ(kMaxCount, v.size());
+ for (size_t n = 0; n < kMaxCount; ++n) {
+ EXPECT_EQ(hashIndex(n), v[0]) << "At index " << n;
+ v.remove(0U);
+ EXPECT_EQ(kMaxCount - n - 1U, v.size()) << "At index " << n;
+ }
+}
+
+TEST(PodVector, PrependItems) {
+ PodVector<int> v;
+ const size_t kMaxCount = 100;
+ for (size_t n = 0; n < kMaxCount; ++n) {
+ v.prepend(hashIndex(n));
+ }
+ EXPECT_EQ(kMaxCount, v.size());
+ for (size_t n = 0; n < kMaxCount; ++n) {
+ EXPECT_EQ(hashIndex(kMaxCount - n - 1), v[n]) << "At index " << n;
+ }
+}
+
+TEST(PodVector, ResizeExpands) {
+ PodVector<int> v;
+ const size_t kMaxCount = 100;
+ const size_t kMaxCount2 = 10000;
+ for (size_t n = 0; n < kMaxCount; ++n) {
+ v.append(hashIndex(n));
+ }
+ EXPECT_EQ(kMaxCount, v.size());
+ v.resize(kMaxCount2);
+ EXPECT_EQ(kMaxCount2, v.size());
+ for (size_t n = 0; n < kMaxCount; ++n) {
+ EXPECT_EQ(hashIndex(n), v[n]) << "At index " << n;
+ }
+}
+
+TEST(PodVector, ResizeTruncates) {
+ PodVector<int> v;
+ const size_t kMaxCount = 10000;
+ const size_t kMaxCount2 = 10;
+ for (size_t n = 0; n < kMaxCount; ++n) {
+ v.append(hashIndex(n));
+ }
+ EXPECT_EQ(kMaxCount, v.size());
+ v.resize(kMaxCount2);
+ EXPECT_EQ(kMaxCount2, v.size());
+ for (size_t n = 0; n < kMaxCount2; ++n) {
+ EXPECT_EQ(hashIndex(n), v[n]) << "At index " << n;
+ }
+}
+
+
+TEST(PodVector, AssignmentOperator) {
+ PodVector<int> v1;
+ const size_t kMaxCount = 10000;
+ for (size_t n = 0; n < kMaxCount; ++n) {
+ v1.append(hashIndex(n));
+ }
+ EXPECT_EQ(kMaxCount, v1.size());
+
+ PodVector<int> v2;
+ v2 = v1;
+
+ v1.reserve(0);
+
+ EXPECT_EQ(kMaxCount, v2.size());
+ for (size_t n = 0; n < kMaxCount; ++n) {
+ EXPECT_EQ(hashIndex(n), v2[n]) << "At index " << n;
+ }
+}
+
+} // namespace emugl
diff --git a/emulator/opengl/shared/emugl/common/scoped_pointer_vector.h b/emulator/opengl/shared/emugl/common/scoped_pointer_vector.h
new file mode 100644
index 0000000..3d263e9
--- /dev/null
+++ b/emulator/opengl/shared/emugl/common/scoped_pointer_vector.h
@@ -0,0 +1,27 @@
+// 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_COMMON_SCOPED_POINTER_VECTOR_H
+#define EMUGL_COMMON_SCOPED_POINTER_VECTOR_H
+
+namespace emugl {
+
+template <class T>
+class ScopedPointerVector {
+ ScopedPointerVector
+};
+
+} // namespace emugl
+
+#endif // EMUGL_COMMON_SCOPED_POINTER_VECTOR_H
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..703487d
--- /dev/null
+++ b/emulator/opengl/shared/emugl/common/smart_ptr.cpp
@@ -0,0 +1,113 @@
+// 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()) {
+ delete old_refcount;
+ 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..73efdd6
--- /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 destructor, 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
diff --git a/emulator/opengl/shared/emugl/common/sockets.cpp b/emulator/opengl/shared/emugl/common/sockets.cpp
new file mode 100644
index 0000000..2a13d72
--- /dev/null
+++ b/emulator/opengl/shared/emugl/common/sockets.cpp
@@ -0,0 +1,222 @@
+// 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/sockets.h"
+
+#include <errno.h>
+
+#ifdef _WIN32
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#else
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <sys/un.h>
+#include <sys/stat.h>
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+namespace emugl {
+
+namespace {
+
+static void socketSetReuseAddress(int s) {
+#ifdef _WIN32
+ // The default behaviour on Windows is equivalent to SO_REUSEADDR
+ // so we don't need to set this option. Moreover, one should never
+ // set this option with WinSock because it's badly implemented and
+ // generates a huge security issue. See:
+ // http://msdn.microsoft.com/en-us/library/windows/desktop/ms740621(v=vs.85).aspx
+#else
+ int val = 1;
+ setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
+#endif
+}
+
+// Helper union to store a socket address.
+struct SockAddr {
+ socklen_t len;
+ union {
+ sockaddr generic;
+ sockaddr_in inet;
+#ifndef _WIN32
+ sockaddr_un local;
+#endif
+ };
+
+ int getFamily() const { return generic.sa_family; }
+
+ void initEmpty() {
+ ::memset(this, 0, sizeof(*this));
+ this->len = static_cast<socklen_t>(sizeof(*this));
+ }
+
+ int initFromInet(uint32_t ip_address, int port) {
+ if (port < 0 || port >= 65536)
+ return -EINVAL;
+
+ ::memset(this, 0, sizeof(*this));
+ this->inet.sin_family = AF_INET;
+ this->inet.sin_port = htons(port);
+ this->inet.sin_addr.s_addr = htonl(ip_address);
+ this->len = sizeof(this->inet);
+ return 0;
+ }
+
+ int initFromLocalhost(int port) {
+ return initFromInet(0x7f000001, port);
+ }
+
+#ifndef _WIN32
+ // Initialize the SockAddr from a Unix path. Returns 0 on success,
+ // or -errno code on failure.
+ int initFromUnixPath(const char* path) {
+ if (!path || !path[0])
+ return -EINVAL;
+
+ size_t pathLen = ::strlen(path);
+ if (pathLen >= sizeof(local.sun_path))
+ return -E2BIG;
+
+ ::memset(this, 0, sizeof(*this));
+ this->local.sun_family = AF_LOCAL;
+ ::memcpy(this->local.sun_path, path, pathLen + 1U);
+ this->len = pathLen + offsetof(sockaddr_un, sun_path);
+ return 0;
+ }
+#endif
+};
+
+int socketBindInternal(const SockAddr* addr, int socketType) {
+ int s = ::socket(addr->getFamily(), socketType, 0);
+ if (s < 0)
+ return -errno;
+
+ // Bind to the socket.
+ if (::bind(s, &addr->generic, addr->len) < 0 ||
+ ::listen(s, 5) < 0) {
+ int ret = -errno;
+ ::close(s);
+ return ret;
+ }
+
+ socketSetReuseAddress(s);
+ return s;
+}
+
+int socketConnectInternal(const SockAddr* addr, int socketType) {
+ int s = ::socket(addr->getFamily(), socketType, 0);
+ if (s < 0)
+ return -errno;
+
+ int ret;
+ do {
+ ret = ::connect(s, &addr->generic, addr->len);
+ } while (ret < 0 && errno == EINTR);
+
+ if (ret < 0) {
+ ret = -errno;
+ ::close(s);
+ return ret;
+ }
+
+ return s;
+}
+
+} // namespace
+
+void socketTcpDisableNagle(int s) {
+ // disable Nagle algorithm to improve bandwidth of small
+ // packets which are quite common in our implementation.
+#ifdef _WIN32
+ DWORD flag;
+#else
+ int flag;
+#endif
+ flag = 1;
+ setsockopt(s, IPPROTO_TCP, TCP_NODELAY,
+ (const char*)&flag, sizeof(flag));
+}
+
+int socketGetPort(int s) {
+ SockAddr addr;
+ addr.initEmpty();
+ if (getsockname(s, &addr.generic, &addr.len) < 0) {
+ return -errno;
+ }
+ switch (addr.generic.sa_family) {
+ case AF_INET:
+ return ntohs(addr.inet.sin_port);
+ default:
+ ;
+ }
+ return -EINVAL;
+}
+
+#ifndef _WIN32
+int socketLocalServer(const char* path, int socketType) {
+ SockAddr addr;
+ int ret = addr.initFromUnixPath(path);
+ if (ret < 0) {
+ return ret;
+ }
+ return socketBindInternal(&addr, socketType);
+}
+
+int socketLocalClient(const char* path, int socketType) {
+ SockAddr addr;
+ int ret = addr.initFromUnixPath(path);
+ if (ret < 0) {
+ return ret;
+ }
+ return socketConnectInternal(&addr, socketType);
+}
+#endif // !_WIN32
+
+int socketTcpLoopbackServer(int port, int socketType) {
+ SockAddr addr;
+ int ret = addr.initFromLocalhost(port);
+ if (ret < 0) {
+ return ret;
+ }
+ return socketBindInternal(&addr, socketType);
+}
+
+int socketTcpLoopbackClient(int port, int socketType) {
+ SockAddr addr;
+ int ret = addr.initFromLocalhost(port);
+ if (ret < 0) {
+ return ret;
+ }
+ return socketConnectInternal(&addr, socketType);
+}
+
+int socketTcpClient(const char* hostname, int port, int socketType) {
+ // TODO(digit): Implement this.
+ return -ENOSYS;
+}
+
+int socketAccept(int serverSocket) {
+ int ret;
+ do {
+ ret = ::accept(serverSocket, NULL, NULL);
+ } while (ret < 0 && errno == EINTR);
+ return ret;
+}
+
+} // namespace emugl
diff --git a/emulator/opengl/shared/emugl/common/sockets.h b/emulator/opengl/shared/emugl/common/sockets.h
new file mode 100644
index 0000000..11e7ac7
--- /dev/null
+++ b/emulator/opengl/shared/emugl/common/sockets.h
@@ -0,0 +1,57 @@
+// 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_COMMON_SOCKETS_H
+#define EMUGL_COMMON_SOCKETS_H
+
+// A set of helper functions used to deal with sockets in a portable way.
+
+namespace emugl {
+
+// Disable Nagle's algorithm for socket descriptor |s|. This assumes
+// that |s| is a TCP socket descriptor.
+void socketTcpDisableNagle(int s);
+
+// Return the port associated with a given IP or IPv6 socket,
+// or -errno code on failure.
+int socketGetPort(int s);
+
+// Bind to a local/Unix path, and return its socket descriptor on success,
+// or -errno code on failure.
+int socketLocalServer(const char* path, int socketType);
+
+// Connect to a Unix local path, and return a new socket descriptor
+// on success, or -errno code on failure.
+int socketLocalClient(const char* path, int socketType);
+
+// Bind to a localhost TCP socket, and return its socket descriptor on
+// success, or -errno code on failure.
+int socketTcpLoopbackServer(int port, int socketType);
+
+// Connect to a localhost TCP port, and return a new socket descriptor on
+// success, or -errno code on failure.
+int socketTcpLoopbackClient(int port, int socketType);
+
+// Connect to a TCP host, and return a new socket descriptor on
+// success, or -errno code on failure.
+int socketTcpClient(const char* hostname, int port, int socketType);
+
+// Accept a new connection. |serverSocket| must be a bound server socket
+// descriptor. Returns new socket descriptor on success, or -errno code
+// on failure.
+int socketAccept(int serverSocket);
+
+} // namespace emugl
+
+#endif // EMUGL_COMMON_SOCKETS_H
diff --git a/emulator/opengl/shared/emugl/common/testing/test_thread.h b/emulator/opengl/shared/emugl/common/testing/test_thread.h
new file mode 100644
index 0000000..2d758b3
--- /dev/null
+++ b/emulator/opengl/shared/emugl/common/testing/test_thread.h
@@ -0,0 +1,78 @@
+// 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_COMMON_TESTING_TEST_THREAD_H
+#define EMUGL_COMMON_TESTING_TEST_THREAD_H
+
+#ifdef _WIN32
+# define WIN32_LEAN_AND_MEAN 1
+# include <windows.h>
+#else
+# include <pthread.h>
+#endif
+
+namespace emugl {
+
+// Very basic platform thread wrapper that only uses a tiny stack.
+// This shall only be used during unit testing, and allows test code
+// to not depend on the implementation of emugl::Thread.
+class TestThread {
+public:
+ // Main thread function type.
+ typedef void* (ThreadFunction)(void* param);
+
+ // Constructor actually launches a new platform thread.
+ TestThread(ThreadFunction* func, void* funcParam) {
+#ifdef _WIN32
+ mThread = CreateThread(NULL,
+ 16384,
+ (DWORD WINAPI (*)(void*))func,
+ funcParam,
+ NULL,
+ NULL);
+#else
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setstacksize(&attr, 16384);
+ pthread_create(&mThread, &attr, func, funcParam);
+ pthread_attr_destroy(&attr);
+#endif
+ }
+
+ ~TestThread() {
+#ifdef _WIN32
+ CloseHandle(mThread);
+#endif
+ }
+
+ void join() {
+#ifdef _WIN32
+ WaitForSingleObject(mThread, INFINITE);
+#else
+ void* ret = NULL;
+ pthread_join(mThread, &ret);
+#endif
+ }
+
+private:
+#ifdef _WIN32
+ HANDLE mThread;
+#else
+ pthread_t mThread;
+#endif
+};
+
+} // namespace emugl
+
+#endif // EMUGL_COMMON_TESTING_TEST_THREAD_H
diff --git a/emulator/opengl/shared/emugl/common/thread_store.cpp b/emulator/opengl/shared/emugl/common/thread_store.cpp
new file mode 100644
index 0000000..ea64c6f
--- /dev/null
+++ b/emulator/opengl/shared/emugl/common/thread_store.cpp
@@ -0,0 +1,242 @@
+// 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/thread_store.h"
+
+#ifdef _WIN32
+#include "emugl/common/lazy_instance.h"
+#endif
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+// Set to 1 to print debug messages.
+#define DEBUG_THREAD_STORE 0
+
+#if DEBUG_THREAD_STORE
+# define D(...) do { printf("%s:%d: ", __FUNCTION__, __LINE__); printf(__VA_ARGS__); fflush(stdout); } while (0)
+#else
+# define D(...) ((void)0)
+#endif
+
+namespace emugl {
+
+#ifdef _WIN32
+
+namespace {
+
+// The ThreadStore implementation on Windows is very tricky, because
+// TlsAlloc() doesn't allow one to provide a destructor function. As
+// such threads are expected to destroy all TLS values explicitely.
+//
+// To solve this issue, this source file provides a static method called
+// ThreadStore::OnThreadExit() that must be called when a thread exits,
+// which will cleanup all values for the current thread.
+//
+// But this forces us to track thread-specific values ourselves.
+
+// Maximum amount of thread-specific slots supported by this implementation.
+enum {
+ kMaxTlsSlots = 64
+};
+
+// TlsSlotArray is a thread-specific array of values. Instances will
+// be stored in a Win32 TLS value controlled by a single master TLS
+// key.
+//
+typedef void* TlsSlotArray[kMaxTlsSlots];
+
+// Global state shared by all threads
+class GlobalState {
+public:
+ GlobalState() {
+ D("Entering\n");
+ mMasterTls = TlsAlloc();
+ D("Master TLS = %d\n", (int)mMasterTls);
+ InitializeCriticalSection(&mSection);
+ mLastIndex = 0;
+ ::memset(mDestructors, 0, sizeof(mDestructors));
+ D("Exiting\n");
+ }
+
+ // Register a new TLS key, or return -1 on error (too many keys).
+ // |destroy| is the destructor function for the key.
+ int registerKey(ThreadStore::Destructor* destroy) {
+ D("Entering destroy=%p\n", destroy);
+ int ret = -1;
+ EnterCriticalSection(&mSection);
+ if (mLastIndex < kMaxTlsSlots) {
+ ret = mLastIndex++;
+ mDestructors[ret] = destroy;
+ }
+ LeaveCriticalSection(&mSection);
+ D("Exiting newKey=%d\n", ret);
+ return ret;
+ }
+
+ void unregisterKey(int key) {
+ D("key=%d\n", key);
+ if (key < 0 || key >= kMaxTlsSlots) {
+ D("Invalid key\n");
+ return;
+ }
+
+ // Note: keys are not reusable, but remove the destructor to avoid
+ // crashes in leaveCurrentThread() when it points to a function that
+ // is going to be unloaded from the process' address space.
+ EnterCriticalSection(&mSection);
+ mDestructors[key] = NULL;
+ LeaveCriticalSection(&mSection);
+ D("Exiting\n");
+ }
+
+ // Get the current thread-local value for a given |key|.
+ void* getValue(int key) const {
+ D("Entering key=%d\n", key);
+ if (key < 0 || key >= kMaxTlsSlots) {
+ D("Invalid key, result=NULL\n");
+ return NULL;
+ }
+
+ TlsSlotArray* array = getArray();
+ void* ret = (*array)[key];
+ D("Exiting keyValue=%p\n", ret);
+ return ret;
+ }
+
+ // Set the current thread-local |value| for a given |key|.
+ void setValue(int key, void* value) {
+ D("Entering key=%d\n",key);
+ if (key < 0 || key >= kMaxTlsSlots) {
+ D("Invalid key, returning\n");
+ return;
+ }
+
+ TlsSlotArray* array = getArray();
+ (*array)[key] = value;
+ D("Exiting\n");
+ }
+
+ // Call this when a thread exits to destroy all its thread-local values.
+ void leaveCurrentThread() {
+ D("Entering\n");
+ TlsSlotArray* array =
+ reinterpret_cast<TlsSlotArray*>(TlsGetValue(mMasterTls));
+ if (!array) {
+ D("Exiting, no thread-local data in this thread\n");
+ return;
+ }
+
+ for (size_t n = 0; n < kMaxTlsSlots; ++n) {
+ void* value = array[n];
+ if (value) {
+ (*array)[n] = NULL;
+ // NOTE: In theory, a destructor could reset the slot to
+ // a new value, and we would have to loop in this function
+ // in interesting ways. In practice, ignore the issue.
+ EnterCriticalSection(&mSection);
+ ThreadStore::Destructor* destroy = mDestructors[n];
+ LeaveCriticalSection(&mSection);
+ if (destroy) {
+ D("Calling destructor %p for key=%d, with value=%p\n",
+ destroy, (int)n, value);
+ (*destroy)(value);
+ }
+ }
+ }
+ TlsSetValue(mMasterTls, NULL);
+ ::free(array);
+ D("Exiting\n");
+ }
+
+private:
+ // Return the thread-local array of TLS slots for the current thread.
+ // Cannot return NULL.
+ TlsSlotArray* getArray() const {
+ D("Entering\n");
+ TlsSlotArray* array =
+ reinterpret_cast<TlsSlotArray*>(TlsGetValue(mMasterTls));
+ if (!array) {
+ array = reinterpret_cast<TlsSlotArray*>(
+ ::calloc(sizeof(*array), 1));
+ TlsSetValue(mMasterTls, array);
+ D("Allocated new array at %p\n", array);
+ } else {
+ D("Retrieved array at %p\n", array);
+ }
+ return array;
+ }
+
+ DWORD mMasterTls;
+ CRITICAL_SECTION mSection;
+ int mLastIndex;
+ ThreadStore::Destructor* mDestructors[kMaxTlsSlots];
+};
+
+LazyInstance<GlobalState> gGlobalState = LAZY_INSTANCE_INIT;
+
+} // namespace
+
+ThreadStore::ThreadStore(Destructor* destroy) {
+ D("Entering this=%p destroy=%p\n", this, destroy);
+ mKey = gGlobalState->registerKey(destroy);
+ D("Exiting this=%p key=%d\n", this, mKey);
+}
+
+ThreadStore::~ThreadStore() {
+ D("Entering this=%p\n", this);
+ GlobalState* state = gGlobalState.ptr();
+ state->unregisterKey(mKey);
+ D("Exiting this=%p\n", this);
+}
+
+void* ThreadStore::get() const {
+ D("Entering this=%p\n", this);
+ void* ret = gGlobalState->getValue(mKey);
+ D("Exiting this=%p value=%p\n", this, ret);
+ return ret;
+}
+
+void ThreadStore::set(void* value) {
+ D("Entering this=%p value=%p\n", this, value);
+ gGlobalState->setValue(mKey, value);
+ D("Exiting this=%p\n", this);
+}
+
+// static
+void ThreadStore::OnThreadExit() {
+ gGlobalState->leaveCurrentThread();
+}
+
+#else // !_WIN32
+
+ThreadStore::ThreadStore(Destructor* destroy) {
+ int ret = pthread_key_create(&mKey, destroy);
+ if (ret != 0) {
+ fprintf(stderr,
+ "Could not create thread store key: %s\n",
+ strerror(ret));
+ exit(1);
+ }
+}
+
+ThreadStore::~ThreadStore() {
+ pthread_key_delete(mKey);
+}
+
+#endif // !_WIN32
+
+} // namespace emugl
diff --git a/emulator/opengl/shared/emugl/common/thread_store.h b/emulator/opengl/shared/emugl/common/thread_store.h
new file mode 100644
index 0000000..5fd08bd
--- /dev/null
+++ b/emulator/opengl/shared/emugl/common/thread_store.h
@@ -0,0 +1,110 @@
+// 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_COMMON_THREAD_STORE_H
+#define EMUGL_COMMON_THREAD_STORE_H
+
+#ifdef _WIN32
+# define WIN32_LEAN_AND_MEAN 1
+# include <windows.h>
+#else
+# include <pthread.h>
+#endif
+
+namespace emugl {
+
+// A class to model storage of thread-specific values, that can be
+// destroyed on thread exit.
+//
+// Note that on Windows, a thread must call OnThreadExit() explicitly
+// here to ensure that the values are probably discarded. This is an
+// unfortunate requirement of the Win32 API, which doesn't support
+// destructors at all.
+//
+// There are various hacks on the web to try to achieve this automatically
+// (e.g. [1]) but they rely on using the Microsoft build tools,
+// which doesn't work for us.
+//
+// Note another important issue with ThreadStore instances: if you create
+// one instance in a shared library, you need to make sure that it is
+// always destroyed before the library is unloaded. Otherwise, future
+// thread exit will likely crash, due to calling a destructor function
+// that is no longer in the process' address space.
+//
+// Finally, destroying an instance does _not_ free the corresponding values,
+// because doing so properly requires coordinating all participating threads,
+// which is impossible to achieve in the most general case. Thus, consider
+// that thread-local values are always leaked on library unload, or on
+// program exit.
+//
+// [1] http://stackoverflow.com/questions/14538159/about-tls-callback-in-windows
+
+class ThreadStore {
+public:
+ // Type of a function used to destroy a thread-specific value that
+ // was previously assigned by calling set().
+ typedef void (Destructor)(void* value);
+
+ // Initialize instance so that is hold keys that must be destroyed
+ // on thread exit by calling |destroy|.
+ explicit ThreadStore(Destructor* destroy);
+
+ // NOTE: Destructor don't free the thread-local values, but are required
+ // to avoid crashes (see note above).
+ ~ThreadStore();
+
+ // Retrieve current thread-specific value from store.
+#ifdef _WIN32
+ void* get() const;
+#else
+ inline void* get() const {
+ return pthread_getspecific(mKey);
+ }
+#endif
+
+ // Set the new thread-specific value.
+#ifdef _WIN32
+ void set(void* value);
+#else
+ inline void set(void* value) {
+ pthread_setspecific(mKey, value);
+ }
+#endif
+
+#ifdef _WIN32
+ // Each thread should call this function on exit to ensure that
+ // all corresponding TLS values are properly freed.
+ static void OnThreadExit();
+#else
+ // Nothing to do on Posix.
+ static inline void OnThreadExit() {}
+#endif
+
+private:
+ // Ensure you can't create an empty ThreadStore instance, or simply
+ // copy it in any way.
+ ThreadStore();
+ ThreadStore(const ThreadStore&);
+ ThreadStore& operator=(const ThreadStore&);
+
+#ifdef _WIN32
+ int mKey;
+#else
+ pthread_key_t mKey;
+#endif
+};
+
+} // namespace emugl
+
+#endif // EMUGL_COMMON_THREAD_STORE_H
diff --git a/emulator/opengl/shared/emugl/common/thread_store_unittest.cpp b/emulator/opengl/shared/emugl/common/thread_store_unittest.cpp
new file mode 100644
index 0000000..6b5dddb
--- /dev/null
+++ b/emulator/opengl/shared/emugl/common/thread_store_unittest.cpp
@@ -0,0 +1,146 @@
+// 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/thread_store.h"
+
+#include "emugl/common/mutex.h"
+#include "emugl/common/testing/test_thread.h"
+
+#include <gtest/gtest.h>
+
+namespace emugl {
+
+namespace {
+
+// Helper class used to count instance creation and destruction.
+class StaticCounter {
+public:
+ enum {
+ kMaxInstances = 1000,
+ };
+
+ StaticCounter() {
+ Mutex::AutoLock lock(mMutex);
+ if (mCreationCount < kMaxInstances)
+ mInstances[mCreationCount] = this;
+ mCreationCount++;
+ }
+
+ ~StaticCounter() {
+ Mutex::AutoLock lock(mMutex);
+ mDestructionCount++;
+ }
+
+ static void reset() {
+ Mutex::AutoLock lock(mMutex);
+ mCreationCount = 0;
+ mDestructionCount = 0;
+ }
+
+ static size_t getCreationCount() {
+ Mutex::AutoLock lock(mMutex);
+ return mCreationCount;
+ }
+
+ static size_t getDestructionCount() {
+ Mutex::AutoLock lock(mMutex);
+ return mDestructionCount;
+ }
+
+ static void freeAll() {
+ for (size_t n = 0; n < kMaxInstances; ++n)
+ delete mInstances[n];
+ }
+
+private:
+ static Mutex mMutex;
+ static size_t mCreationCount;
+ static size_t mDestructionCount;
+ static StaticCounter* mInstances[kMaxInstances];
+};
+
+Mutex StaticCounter::mMutex;
+size_t StaticCounter::mCreationCount = 0;
+size_t StaticCounter::mDestructionCount = 0;
+StaticCounter* StaticCounter::mInstances[kMaxInstances];
+
+} // namespace
+
+// Just check that we can create a new ThreadStore with an empty
+// destructor, and use it in the current thread.
+TEST(ThreadStore, MainThreadWithoutDestructor) {
+ ThreadStore store(NULL);
+ static int x = 42;
+ store.set(&x);
+ EXPECT_EQ(&x, store.get());
+}
+
+// The following test checks that exiting a thread correctly deletes
+// any thread-local value stored in it.
+static void simplyDestroy(void* value) {
+ delete (StaticCounter*) value;
+}
+
+static void* simpleThreadFunc(void* param) {
+ ThreadStore* store = static_cast<ThreadStore*>(param);
+ store->set(new StaticCounter());
+ ThreadStore::OnThreadExit();
+ return NULL;
+}
+
+TEST(ThreadStore, ThreadsWithDestructor) {
+ ThreadStore store(simplyDestroy);
+ const size_t kNumThreads = 1000;
+ TestThread* threads[kNumThreads];
+ StaticCounter::reset();
+
+ for (size_t n = 0; n < kNumThreads; ++n) {
+ threads[n] = new TestThread(&simpleThreadFunc, &store);
+ }
+ for (size_t n = 0; n < kNumThreads; ++n) {
+ threads[n]->join();
+ }
+
+ EXPECT_EQ(kNumThreads, StaticCounter::getCreationCount());
+ EXPECT_EQ(kNumThreads, StaticCounter::getDestructionCount());
+
+ for (size_t n = 0; n < kNumThreads; ++n) {
+ delete threads[n];
+ }
+}
+
+TEST(ThreadStore, ThreadsWithoutDestructor) {
+ ThreadStore store(NULL);
+ const size_t kNumThreads = 1000;
+ TestThread* threads[kNumThreads];
+ StaticCounter::reset();
+
+ for (size_t n = 0; n < kNumThreads; ++n) {
+ threads[n] = new TestThread(&simpleThreadFunc, &store);
+ }
+ for (size_t n = 0; n < kNumThreads; ++n) {
+ threads[n]->join();
+ }
+
+ EXPECT_EQ(kNumThreads, StaticCounter::getCreationCount());
+ EXPECT_EQ(0U, StaticCounter::getDestructionCount());
+
+ StaticCounter::freeAll();
+
+ for (size_t n = 0; n < kNumThreads; ++n) {
+ delete threads[n];
+ }
+}
+
+} // namespace emugl
diff --git a/emulator/opengl/tests/emulator_test_renderer/Android.mk b/emulator/opengl/tests/emulator_test_renderer/Android.mk
index 9c4cfdd..d585513 100644
--- a/emulator/opengl/tests/emulator_test_renderer/Android.mk
+++ b/emulator/opengl/tests/emulator_test_renderer/Android.mk
@@ -5,17 +5,8 @@ $(call emugl-import,libOpenglRender event_injector)
LOCAL_SRC_FILES := main.cpp
-PREBUILT := $(HOST_PREBUILT_TAG)
-LOCAL_SDL_CONFIG ?= prebuilts/tools/$(PREBUILT)/sdl/bin/sdl-config
-LOCAL_SDL_CFLAGS := $(shell $(LOCAL_SDL_CONFIG) --cflags)
-LOCAL_SDL_LDLIBS := $(filter-out %.a %.lib,$(shell $(LOCAL_SDL_CONFIG) --static-libs))
-
-LOCAL_CFLAGS += $(LOCAL_SDL_CFLAGS) -g -O0
-LOCAL_LDLIBS += $(LOCAL_SDL_LDLIBS)
-
-ifeq ($(HOST_OS),windows)
-LOCAL_LDLIBS += -lws2_32
-endif
+LOCAL_CFLAGS += $(EMUGL_SDL_CFLAGS) -g -O0
+LOCAL_LDLIBS += $(EMUGL_SDL_LDLIBS)
LOCAL_STATIC_LIBRARIES += libSDL libSDLmain
diff --git a/emulator/opengl/tests/event_injector/sockets.c b/emulator/opengl/tests/event_injector/sockets.c
index a2cc334..33df32b 100644
--- a/emulator/opengl/tests/event_injector/sockets.c
+++ b/emulator/opengl/tests/event_injector/sockets.c
@@ -24,10 +24,6 @@
#include <stdlib.h>
#include <string.h>
#include <limits.h>
-//#include "android/utils/path.h"
-//#include "android/utils/debug.h"
-//#include "android/utils/misc.h"
-//#include "android/utils/system.h"
#define D(...) ((void)0)
diff --git a/emulator/opengl/tests/translator_tests/GLES_CM/Android.mk b/emulator/opengl/tests/translator_tests/GLES_CM/Android.mk
index a66207e..1f25a33 100644
--- a/emulator/opengl/tests/translator_tests/GLES_CM/Android.mk
+++ b/emulator/opengl/tests/translator_tests/GLES_CM/Android.mk
@@ -3,28 +3,23 @@ LOCAL_PATH:= $(call my-dir)
$(call emugl-begin-host-executable,triangleCM)
$(call emugl-import,libEGL_translator libGLES_CM_translator)
-PREBUILT := $(HOST_PREBUILT_TAG)
-LOCAL_SDL_CONFIG ?= prebuilts/tools/$(PREBUILT)/sdl/bin/sdl-config
-LOCAL_SDL_CFLAGS := $(shell $(LOCAL_SDL_CONFIG) --cflags)
-LOCAL_SDL_LDLIBS := $(filter-out %.a %.lib,$(shell $(LOCAL_SDL_CONFIG) --static-libs))
-
ifeq ($(HOST_OS),darwin)
# SDK 10.6+ deprecates __dyld_func_lookup required by dlcompat_init_func
# in SDL_dlcompat.o this module depends. Instruct linker to resolved it at runtime.
OSX_VERSION_MAJOR := $(shell echo $(mac_sdk_version) | cut -d . -f 2)
OSX_VERSION_MAJOR_GREATER_THAN_OR_EQUAL_TO_6 := $(shell [ $(OSX_VERSION_MAJOR) -ge 6 ] && echo true)
ifeq ($(OSX_VERSION_MAJOR_GREATER_THAN_OR_EQUAL_TO_6),true)
- LOCAL_SDL_LDLIBS += -Wl,-undefined,dynamic_lookup
+ LOCAL_LDLIBS += -Wl,-undefined,dynamic_lookup
endif
endif
LOCAL_SRC_FILES:= \
triangleCM.cpp
-LOCAL_CFLAGS += $(LOCAL_SDL_CFLAGS) -g -O0
-LOCAL_LDLIBS += $(LOCAL_SDL_LDLIBS)
+LOCAL_CFLAGS += $(EMUGL_SDL_CFLAGS) -g -O0
+LOCAL_LDLIBS += $(EMUGL_SDL_LDLIBS) -lstdc++
-LOCAL_STATIC_LIBRARIES += libSDL libSDLmain
+LOCAL_STATIC_LIBRARIES += $(EMUGL_SDL_STATIC_LIBRARIES)
ifeq ($(HOST_OS),darwin)
$(call emugl-import,libMac_view)
diff --git a/emulator/opengl/tests/translator_tests/GLES_CM/triangleCM.cpp b/emulator/opengl/tests/translator_tests/GLES_CM/triangleCM.cpp
index 7547cd0..0e86166 100644
--- a/emulator/opengl/tests/translator_tests/GLES_CM/triangleCM.cpp
+++ b/emulator/opengl/tests/translator_tests/GLES_CM/triangleCM.cpp
@@ -148,13 +148,10 @@ int main(int argc, char **argv)
bool useCopy = false;
bool useSubCopy = false;
- int c;
- extern char *optarg;
-
#ifdef _WIN32
HWND windowId = NULL;
#elif __linux__
- Window windowId = NULL;
+ Window windowId = 0;
#elif __APPLE__
void* windowId = NULL;
#endif
@@ -282,17 +279,17 @@ int main(int argc, char **argv)
#define MIN_T 0
GLbyte byteVertices[] = { -1,-1,0, // Position
- 255,0,0,255, // Color
+ (GLbyte)255,0,0,(GLbyte)255, // Color
MIN_T, MIN_T, // texture
12, //point size
1,-1,0,
- 0,255,0,255,
+ 0,(GLbyte)255,0,(GLbyte)255,
MAX_T,MIN_T,
47,
0,1,0,
- 0,0,255,255,
+ 0,0,(GLbyte)255,(GLbyte)255,
MID_T, MAX_T,
14
};
diff --git a/emulator/opengl/tests/translator_tests/GLES_V2/Android.mk b/emulator/opengl/tests/translator_tests/GLES_V2/Android.mk
index e72da96..10b3b0c 100644
--- a/emulator/opengl/tests/translator_tests/GLES_V2/Android.mk
+++ b/emulator/opengl/tests/translator_tests/GLES_V2/Android.mk
@@ -3,18 +3,13 @@ LOCAL_PATH:= $(call my-dir)
$(call emugl-begin-host-executable,triangleV2)
$(call emugl-import,libEGL_translator libGLES_V2_translator)
-PREBUILT := $(HOST_PREBUILT_TAG)
-LOCAL_SDL_CONFIG ?= prebuilts/tools/$(PREBUILT)/sdl/bin/sdl-config
-LOCAL_SDL_CFLAGS := $(shell $(LOCAL_SDL_CONFIG) --cflags)
-LOCAL_SDL_LDLIBS := $(filter-out %.a %.lib,$(shell $(LOCAL_SDL_CONFIG) --static-libs))
-
LOCAL_SRC_FILES:= \
triangleV2.cpp
-LOCAL_CFLAGS += $(LOCAL_SDL_CFLAGS) -g -O0
-LOCAL_LDLIBS += $(LOCAL_SDL_LDLIBS)
+LOCAL_CFLAGS += $(EMUGL_SDL_CFLAGS) -g -O0
+LOCAL_LDLIBS += $(EMUGL_SDL_LDLIBS) -lstdc++
-LOCAL_STATIC_LIBRARIES += libSDL libSDLmain
+LOCAL_STATIC_LIBRARIES += $(EMUGL_SDL_STATIC_LIBRARIES)
ifeq ($(HOST_OS),darwin)
# SDK 10.6+ deprecates __dyld_func_lookup required by dlcompat_init_func
@@ -28,4 +23,3 @@ ifeq ($(HOST_OS),darwin)
endif
$(call emugl-end-module)
-
diff --git a/emulator/opengl/tests/translator_tests/GLES_V2/triangleV2.cpp b/emulator/opengl/tests/translator_tests/GLES_V2/triangleV2.cpp
index 59535c5..3a8ff0f 100644
--- a/emulator/opengl/tests/translator_tests/GLES_V2/triangleV2.cpp
+++ b/emulator/opengl/tests/translator_tests/GLES_V2/triangleV2.cpp
@@ -313,20 +313,6 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int n
int main(int argc, char **argv)
#endif
{
- GLuint ui32Vbo = 0; // Vertex buffer object handle
- GLuint ui32IndexVbo;
- GLuint ui32Texture;
-
- int nframes = 100;
- bool immidateMode = false;
- bool useIndices = false;
- bool useTexture = true;
- bool useCompTexture = false;
- bool useFixed = true;
- bool usePoints = false;
- bool useCopy = false;
- bool useSubCopy = false;
-
#ifdef _WIN32
int argc;
char **argv = parseCmdLine(lpCmdLine, &argc);
@@ -372,7 +358,7 @@ int main(int argc, char **argv)
#ifdef _WIN32
HWND windowId = NULL;
#elif __linux__
- Window windowId = NULL;
+ Window windowId = 0;
#elif __APPLE__
void* windowId = NULL;
#endif
diff --git a/emulator/opengl/tests/ut_renderer/Android.mk b/emulator/opengl/tests/ut_renderer/Android.mk
index fe8e7ac..91608b2 100644
--- a/emulator/opengl/tests/ut_renderer/Android.mk
+++ b/emulator/opengl/tests/ut_renderer/Android.mk
@@ -3,7 +3,7 @@ LOCAL_PATH:=$(call my-dir)
ifeq ($(HOST_OS), linux)
$(call emugl-begin-host-executable,ut_renderer)
-$(call emugl-import,libut_rendercontrol_dec libGLESv1_dec libGLESv2_dec libEGL_host_wrapper)
+$(call emugl-import,libut_rendercontrol_dec libGLESv1_dec libGLESv2_dec libEGL_host_wrapper libOpenglRender)
LOCAL_SRC_FILES := ut_renderer.cpp \
RenderingThread.cpp \
diff --git a/emulator/opengl/tests/ut_renderer/Renderer.cpp b/emulator/opengl/tests/ut_renderer/Renderer.cpp
index 22afadb..1102014 100644
--- a/emulator/opengl/tests/ut_renderer/Renderer.cpp
+++ b/emulator/opengl/tests/ut_renderer/Renderer.cpp
@@ -56,7 +56,7 @@ Renderer::Renderer()
int Renderer::createSurface(RenderingThread *thread, const ClientHandle & handle)
{
- android::Mutex::Autolock(this->m_mutex);
+ emugl::Mutex::AutoLock(this->m_mutex);
assert(m_surfaces.find(handle) == m_surfaces.end());
if (handle.handle == 0) {
@@ -75,7 +75,7 @@ int Renderer::createSurface(RenderingThread *thread, const ClientHandle & handle
int Renderer::destroySurface(RenderingThread *thread, const ClientHandle &handle)
{
- android::Mutex::Autolock(this->m_mutex);
+ emugl::Mutex::AutoLock(this->m_mutex);
SurfaceMap::iterator i = m_surfaces.find(handle);
if (i == m_surfaces.end()) {
@@ -90,7 +90,7 @@ int Renderer::destroySurface(RenderingThread *thread, const ClientHandle &handle
int Renderer::createContext(RenderingThread *thread, const ClientHandle &handle, ClientHandle shareCtx, int version)
{
- android::Mutex::Autolock(this->m_mutex);
+ emugl::Mutex::AutoLock(this->m_mutex);
assert(m_ctxs.find(handle) == m_ctxs.end());
RendererContext *shared = NULL;
@@ -115,7 +115,7 @@ int Renderer::createContext(RenderingThread *thread, const ClientHandle &handle,
int Renderer::destroyContext(RenderingThread *thread, const ClientHandle &handle)
{
- android::Mutex::Autolock(this->m_mutex);
+ emugl::Mutex::AutoLock(this->m_mutex);
ContextMap::iterator i = m_ctxs.find(handle);
if (i == m_ctxs.end()) {
@@ -133,7 +133,7 @@ int Renderer::makeCurrent(RenderingThread *thread,
const ClientHandle &readSurface,
const ClientHandle & ctx)
{
- android::Mutex::Autolock(this->m_mutex);
+ emugl::Mutex::AutoLock(this->m_mutex);
RendererContext *currentContext = thread->currentContext();
@@ -172,7 +172,7 @@ int Renderer::makeCurrent(RenderingThread *thread,
int Renderer::swapBuffers(RenderingThread *thread,
const ClientHandle &surface)
{
- android::Mutex::Autolock(this->m_mutex);
+ emugl::Mutex::AutoLock(this->m_mutex);
SurfaceMap::iterator s = m_surfaces.find(surface);
if (s == m_surfaces.end()) {
diff --git a/emulator/opengl/tests/ut_renderer/Renderer.h b/emulator/opengl/tests/ut_renderer/Renderer.h
index cdf10b6..81f4077 100644
--- a/emulator/opengl/tests/ut_renderer/Renderer.h
+++ b/emulator/opengl/tests/ut_renderer/Renderer.h
@@ -19,7 +19,7 @@
#include "RendererSurface.h"
#include "RendererContext.h"
#include "NativeWindowing.h"
-#include <utils/threads.h>
+#include "emugl/common/mutex.h"
class RenderingThread;
@@ -57,6 +57,6 @@ private:
NativeWindowing *m_nw;
EGLDisplay m_dpy;
- android::Mutex m_mutex; // single global mutex for the renderer class;
+ emugl::Mutex m_mutex; // single global mutex for the renderer class;
};
#endif