blob: ecb2514d77592e40bf24a11d01beda1c65c11ac6 [file] [log] [blame]
Mathias Agopian518ec112011-05-13 16:21:08 -07001/*
2 ** Copyright 2007, The Android Open Source Project
3 **
4 ** Licensed under the Apache License, Version 2.0 (the "License");
5 ** you may not use this file except in compliance with the License.
6 ** You may obtain a copy of the License at
7 **
8 ** http://www.apache.org/licenses/LICENSE-2.0
9 **
10 ** Unless required by applicable law or agreed to in writing, software
11 ** distributed under the License is distributed on an "AS IS" BASIS,
12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 ** See the License for the specific language governing permissions and
14 ** limitations under the License.
15 */
16
17#ifndef ANDROID_EGL_OBJECT_H
18#define ANDROID_EGL_OBJECT_H
19
20
21#include <ctype.h>
22#include <stdint.h>
23#include <stdlib.h>
24
25#include <EGL/egl.h>
26#include <EGL/eglext.h>
27#include <GLES/gl.h>
28#include <GLES/glext.h>
29
30#include <utils/threads.h>
31
32#include <system/window.h>
33
34#include "egl_display.h"
35
36// ----------------------------------------------------------------------------
37namespace android {
38// ----------------------------------------------------------------------------
39
40struct egl_display_t;
41
42class egl_object_t {
43 egl_display_t *display;
44 volatile int32_t terminated;
45 mutable volatile int32_t count;
46
47public:
48 egl_object_t(egl_display_t* display);
49
50 inline bool isAlive() const { return !terminated; }
51 inline int32_t incRef() { return android_atomic_inc(&count); }
52 inline int32_t decRef() { return android_atomic_dec(&count); }
53
54private:
55 bool get();
56 bool put();
57
58public:
59 template <typename N, typename T>
60 struct LocalRef {
61 N* ref;
62 LocalRef(T o) : ref(0) {
63 N* native = reinterpret_cast<N*>(o);
64 if (o && native->get()) {
65 ref = native;
66 }
67 }
68 ~LocalRef() {
69 if (ref && ref->put()) {
70 delete ref;
71 }
72 }
73 inline N* get() {
74 return ref;
75 }
76 void acquire() const {
77 if (ref) {
78 android_atomic_inc(&ref->count);
79 }
80 }
81 void release() const {
82 if (ref) {
83 int32_t c = android_atomic_dec(&ref->count);
84 // ref->count cannot be 1 prior atomic_dec because we have
85 // a reference, and if we have one, it means there was
86 // already one before us.
87 LOGE_IF(c==1, "refcount is now 0 in release()");
88 }
89 }
90 void terminate() {
91 if (ref) {
92 ref->terminated = 1;
93 release();
94 }
95 }
96 };
97};
98
99// ----------------------------------------------------------------------------
100
101struct egl_surface_t: public egl_object_t {
102 typedef egl_object_t::LocalRef<egl_surface_t, EGLSurface> Ref;
103
104 egl_surface_t(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win,
105 EGLSurface surface, int impl, egl_connection_t const* cnx) :
106 egl_object_t(get_display(dpy)), dpy(dpy), surface(surface),
107 config(config), win(win), impl(impl), cnx(cnx) {
108 }
109 ~egl_surface_t() {
110 }
111 EGLDisplay dpy;
112 EGLSurface surface;
113 EGLConfig config;
114 sp<ANativeWindow> win;
115 int impl;
116 egl_connection_t const* cnx;
117};
118
119struct egl_context_t: public egl_object_t {
120 typedef egl_object_t::LocalRef<egl_context_t, EGLContext> Ref;
121
122 egl_context_t(EGLDisplay dpy, EGLContext context, EGLConfig config,
123 int impl, egl_connection_t const* cnx, int version) :
124 egl_object_t(get_display(dpy)), dpy(dpy), context(context),
125 config(config), read(0), draw(0), impl(impl), cnx(cnx),
126 version(version) {
127 }
128 ~egl_context_t() {
129 }
130 EGLDisplay dpy;
131 EGLContext context;
132 EGLConfig config;
133 EGLSurface read;
134 EGLSurface draw;
135 int impl;
136 egl_connection_t const* cnx;
137 int version;
138};
139
140struct egl_image_t: public egl_object_t {
141 typedef egl_object_t::LocalRef<egl_image_t, EGLImageKHR> Ref;
142
143 egl_image_t(EGLDisplay dpy, EGLContext context) :
144 egl_object_t(get_display(dpy)), dpy(dpy), context(context) {
145 memset(images, 0, sizeof(images));
146 }
147 EGLDisplay dpy;
148 EGLContext context;
149 EGLImageKHR images[IMPL_NUM_IMPLEMENTATIONS];
150};
151
152struct egl_sync_t: public egl_object_t {
153 typedef egl_object_t::LocalRef<egl_sync_t, EGLSyncKHR> Ref;
154
155 egl_sync_t(EGLDisplay dpy, EGLContext context, EGLSyncKHR sync) :
156 egl_object_t(get_display(dpy)), dpy(dpy), context(context), sync(sync) {
157 }
158 EGLDisplay dpy;
159 EGLContext context;
160 EGLSyncKHR sync;
161};
162
163// ----------------------------------------------------------------------------
164
165typedef egl_surface_t::Ref SurfaceRef;
166typedef egl_context_t::Ref ContextRef;
167typedef egl_image_t::Ref ImageRef;
168typedef egl_sync_t::Ref SyncRef;
169
170// ----------------------------------------------------------------------------
171
172template<typename NATIVE, typename EGL>
173static inline NATIVE* egl_to_native_cast(EGL arg) {
174 return reinterpret_cast<NATIVE*>(arg);
175}
176
177static inline
178egl_surface_t* get_surface(EGLSurface surface) {
179 return egl_to_native_cast<egl_surface_t>(surface);
180}
181
182static inline
183egl_context_t* get_context(EGLContext context) {
184 return egl_to_native_cast<egl_context_t>(context);
185}
186
187static inline
188egl_image_t* get_image(EGLImageKHR image) {
189 return egl_to_native_cast<egl_image_t>(image);
190}
191
192static inline
193egl_sync_t* get_sync(EGLSyncKHR sync) {
194 return egl_to_native_cast<egl_sync_t>(sync);
195}
196
197// ----------------------------------------------------------------------------
198}; // namespace android
199// ----------------------------------------------------------------------------
200
201#endif // ANDROID_EGL_OBJECT_H
202