egl_object.h revision 518ec112f468eb67bf681b3eec896d7bfb4ff98d
1/*
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
203