summaryrefslogtreecommitdiff
path: root/opengl/libs/EGL/egl_display.h
diff options
context:
space:
mode:
Diffstat (limited to 'opengl/libs/EGL/egl_display.h')
-rw-r--r--opengl/libs/EGL/egl_display.h154
1 files changed, 106 insertions, 48 deletions
diff --git a/opengl/libs/EGL/egl_display.h b/opengl/libs/EGL/egl_display.h
index 87c2176045..e117314d71 100644
--- a/opengl/libs/EGL/egl_display.h
+++ b/opengl/libs/EGL/egl_display.h
@@ -17,22 +17,26 @@
#ifndef ANDROID_EGL_DISPLAY_H
#define ANDROID_EGL_DISPLAY_H
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-#include <stddef.h>
+
#include <stdint.h>
+#include <stddef.h>
#include <condition_variable>
-#include <map>
-#include <memory>
#include <mutex>
#include <string>
#include <unordered_set>
-#include "../hooks.h"
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include <cutils/compiler.h>
+
#include "egldefs.h"
+#include "../hooks.h"
+// ----------------------------------------------------------------------------
namespace android {
+// ----------------------------------------------------------------------------
class egl_object_t;
class egl_context_t;
@@ -41,25 +45,25 @@ struct egl_connection_t;
bool findExtension(const char* exts, const char* name, size_t nameLen = 0);
bool needsAndroidPEglMitigation();
+// ----------------------------------------------------------------------------
+
class EGLAPI egl_display_t { // marked as EGLAPI for testing purposes
- static std::map<EGLDisplay, std::unique_ptr<egl_display_t>> displayMap;
- static std::mutex displayMapLock;
+ static egl_display_t sDisplay[NUM_DISPLAYS];
EGLDisplay getDisplay(EGLNativeDisplayType display);
- static EGLDisplay getPlatformDisplay(EGLNativeDisplayType display,
- const EGLAttrib* attrib_list);
- void loseCurrentImpl(egl_context_t* cur_c);
+ EGLDisplay getPlatformDisplay(EGLNativeDisplayType display, const EGLAttrib* attrib_list);
+ void loseCurrentImpl(egl_context_t * cur_c);
public:
enum {
NOT_INITIALIZED = 0,
- INITIALIZED = 1,
- TERMINATED = 2,
+ INITIALIZED = 1,
+ TERMINATED = 2
};
egl_display_t();
~egl_display_t();
- EGLBoolean initialize(EGLint* major, EGLint* minor);
+ EGLBoolean initialize(EGLint *major, EGLint *minor);
EGLBoolean terminate();
// add object to this display's list
@@ -72,69 +76,123 @@ public:
static egl_display_t* get(EGLDisplay dpy);
static EGLDisplay getFromNativeDisplay(EGLNativeDisplayType disp, const EGLAttrib* attrib_list);
- EGLBoolean makeCurrent(egl_context_t* c, egl_context_t* cur_c, EGLSurface draw, EGLSurface read,
- EGLContext ctx, EGLSurface impl_draw, EGLSurface impl_read,
- EGLContext impl_ctx);
- static void loseCurrent(egl_context_t* cur_c);
+ EGLBoolean makeCurrent(egl_context_t* c, egl_context_t* cur_c,
+ EGLSurface draw, EGLSurface read, EGLContext ctx,
+ EGLSurface impl_draw, EGLSurface impl_read, EGLContext impl_ctx);
+ static void loseCurrent(egl_context_t * cur_c);
inline bool isReady() const { return (refs > 0); }
inline bool isValid() const { return magic == '_dpy'; }
inline bool isAlive() const { return isValid(); }
- char const* getVendorString() const { return mVendorString.c_str(); }
- char const* getVersionString() const { return mVersionString.c_str(); }
- char const* getClientApiString() const { return mClientApiString.c_str(); }
- char const* getExtensionString() const { return mExtensionString.c_str(); }
+ char const * getVendorString() const { return mVendorString.c_str(); }
+ char const * getVersionString() const { return mVersionString.c_str(); }
+ char const * getClientApiString() const { return mClientApiString.c_str(); }
+ char const * getExtensionString() const { return mExtensionString.c_str(); }
bool haveExtension(const char* name, size_t nameLen = 0) const;
inline uint32_t getRefsCount() const { return refs; }
struct strings_t {
- char const* vendor;
- char const* version;
- char const* clientApi;
- char const* extensions;
+ char const * vendor;
+ char const * version;
+ char const * clientApi;
+ char const * extensions;
};
struct DisplayImpl {
- DisplayImpl() : dpy(EGL_NO_DISPLAY), state(NOT_INITIALIZED) {}
- EGLDisplay dpy;
- EGLint state;
- strings_t queryString;
+ DisplayImpl() : dpy(EGL_NO_DISPLAY), state(NOT_INITIALIZED) { }
+ EGLDisplay dpy;
+ EGLint state;
+ strings_t queryString;
};
private:
- uint32_t magic;
+ uint32_t magic;
+
+public:
+ DisplayImpl disp;
+ bool finishOnSwap; // property: debug.egl.finish
+ bool traceGpuCompletion; // property: debug.egl.traceGpuCompletion
+ bool hasColorSpaceSupport;
+
+private:
+ friend class egl_display_ptr;
+
+ uint32_t refs;
+ bool eglIsInitialized;
+ mutable std::mutex lock;
+ mutable std::mutex refLock;
+ mutable std::condition_variable refCond;
+ std::unordered_set<egl_object_t*> objects;
+ std::string mVendorString;
+ std::string mVersionString;
+ std::string mClientApiString;
+ std::string mExtensionString;
+};
+
+// ----------------------------------------------------------------------------
+// An egl_display_ptr is a kind of smart pointer for egl_display_t objects.
+// It doesn't refcount the egl_display_t, but does ensure that the underlying
+// EGL implementation is "awake" (not hibernating) and ready for use as long
+// as the egl_display_ptr exists.
+class egl_display_ptr {
public:
- DisplayImpl disp;
- bool finishOnSwap; // property: debug.egl.finish
- bool traceGpuCompletion; // property: debug.egl.traceGpuCompletion
- bool hasColorSpaceSupport;
+ explicit egl_display_ptr(egl_display_t* dpy): mDpy(dpy) {}
+
+ // We only really need a C++11 move constructor, not a copy constructor.
+ // A move constructor would save an enter()/leave() pair on every EGL API
+ // call. But enabling -std=c++0x causes lots of errors elsewhere, so I
+ // can't use a move constructor until those are cleaned up.
+ //
+ // egl_display_ptr(egl_display_ptr&& other) {
+ // mDpy = other.mDpy;
+ // other.mDpy = NULL;
+ // }
+ //
+ egl_display_ptr(const egl_display_ptr& other): mDpy(other.mDpy) {}
+
+ ~egl_display_ptr() {}
+
+ const egl_display_t* operator->() const { return mDpy; }
+ egl_display_t* operator->() { return mDpy; }
+
+ const egl_display_t* get() const { return mDpy; }
+ egl_display_t* get() { return mDpy; }
+
+ operator bool() const { return mDpy != nullptr; }
private:
- uint32_t refs;
- bool eglIsInitialized;
- mutable std::mutex lock;
- mutable std::mutex refLock;
- mutable std::condition_variable refCond;
- std::unordered_set<egl_object_t*> objects;
- std::string mVendorString;
- std::string mVersionString;
- std::string mClientApiString;
- std::string mExtensionString;
+ egl_display_t* mDpy;
+
+ // non-assignable
+ egl_display_ptr& operator=(const egl_display_ptr&);
};
-inline egl_display_t* get_display(EGLDisplay dpy) {
+// ----------------------------------------------------------------------------
+
+inline egl_display_ptr get_display(EGLDisplay dpy) {
+ return egl_display_ptr(egl_display_t::get(dpy));
+}
+
+// Does not ensure EGL is unhibernated. Use with caution: calls into the
+// underlying EGL implementation are not safe.
+inline egl_display_t* get_display_nowake(EGLDisplay dpy) {
return egl_display_t::get(dpy);
}
-egl_display_t* validate_display(EGLDisplay dpy);
-egl_display_t* validate_display_connection(EGLDisplay dpy, egl_connection_t** outCnx);
+// ----------------------------------------------------------------------------
+
+egl_display_ptr validate_display(EGLDisplay dpy);
+egl_display_ptr validate_display_connection(EGLDisplay dpy,
+ egl_connection_t*& cnx);
EGLBoolean validate_display_context(EGLDisplay dpy, EGLContext ctx);
EGLBoolean validate_display_surface(EGLDisplay dpy, EGLSurface surface);
+// ----------------------------------------------------------------------------
}; // namespace android
+// ----------------------------------------------------------------------------
#endif // ANDROID_EGL_DISPLAY_H