14774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall/*
2518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ** Copyright 2007, The Android Open Source Project
3518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian **
44774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall ** Licensed under the Apache License, Version 2.0 (the "License");
54774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall ** you may not use this file except in compliance with the License.
64774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall ** You may obtain a copy of the License at
7518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian **
84774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall **     http://www.apache.org/licenses/LICENSE-2.0
9518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian **
104774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall ** Unless required by applicable law or agreed to in writing, software
114774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall ** distributed under the License is distributed on an "AS IS" BASIS,
124774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall ** See the License for the specific language governing permissions and
14518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ** limitations under the License.
15518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */
16518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
17518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#ifndef ANDROID_EGL_OBJECT_H
18518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#define ANDROID_EGL_OBJECT_H
19518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
20518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
21518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include <ctype.h>
22518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include <stdint.h>
23518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include <stdlib.h>
24518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
25518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include <EGL/egl.h>
26518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include <EGL/eglext.h>
27518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
28518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include <utils/threads.h>
2948d438d05f14c2f4bd83ae89f520368cd49122dfMathias Agopian#include <utils/String8.h>
30518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
31518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include <system/window.h>
32518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
33518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include "egl_display.h"
34518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
35518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
36518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopiannamespace android {
37518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
38518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
39518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianstruct egl_display_t;
40518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
41518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianclass egl_object_t {
42518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_display_t *display;
43518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    mutable volatile int32_t count;
44518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
455b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopianprotected:
465b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    virtual ~egl_object_t();
475b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian
48518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianpublic:
49518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_object_t(egl_display_t* display);
505b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    void destroy();
51518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
52518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    inline int32_t incRef() { return android_atomic_inc(&count); }
53518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    inline int32_t decRef() { return android_atomic_dec(&count); }
54f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian    inline egl_display_t* getDisplay() const { return display; }
55518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
56518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianprivate:
575b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    void terminate();
58f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian    static bool get(egl_display_t const* display, egl_object_t* object);
59518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
60518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianpublic:
61518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    template <typename N, typename T>
625b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    class LocalRef {
635b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian        egl_object_t* ref;
645b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian        LocalRef();
655b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian        LocalRef(const LocalRef* rhs);
665b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    public:
675b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian        ~LocalRef();
685b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian        explicit LocalRef(egl_object_t* rhs);
69f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian        explicit LocalRef(egl_display_t const* display, T o) : ref(0) {
705b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian            egl_object_t* native = reinterpret_cast<N*>(o);
71f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian            if (o && egl_object_t::get(display, native)) {
72518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                ref = native;
73518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            }
74518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
75518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        inline N* get() {
765b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian            return static_cast<N*>(ref);
77518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
785b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian        void acquire() const;
795b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian        void release() const;
805b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian        void terminate();
81518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    };
825b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    template <typename N, typename T>
835b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    friend class LocalRef;
84518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian};
85518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
865b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopiantemplate<typename N, typename T>
875b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopianegl_object_t::LocalRef<N, T>::LocalRef(egl_object_t* rhs) : ref(rhs) {
885b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (ref) {
895b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian        ref->incRef();
905b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    }
915b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian}
925b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian
935b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopiantemplate <typename N, typename T>
945b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopianegl_object_t::LocalRef<N,T>::~LocalRef() {
955b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (ref) {
965b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian        ref->destroy();
975b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    }
985b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian}
995b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian
1005b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopiantemplate <typename N, typename T>
1015b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopianvoid egl_object_t::LocalRef<N,T>::acquire() const {
1025b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (ref) {
1035b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian        ref->incRef();
1045b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    }
1055b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian}
1065b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian
1075b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopiantemplate <typename N, typename T>
1085b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopianvoid egl_object_t::LocalRef<N,T>::release() const {
1095b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (ref) {
1105b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian        if (ref->decRef() == 1) {
1115b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian            // shouldn't happen because this is called from LocalRef
112e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE("LocalRef::release() removed the last reference!");
1135b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian        }
1145b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    }
1155b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian}
1165b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian
1175b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopiantemplate <typename N, typename T>
1185b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopianvoid egl_object_t::LocalRef<N,T>::terminate() {
1195b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (ref) {
1205b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian        ref->terminate();
1215b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    }
1225b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian}
1235b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian
124518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
125518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
126ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopianclass egl_surface_t : public egl_object_t {
1275b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopianprotected:
128258385978c517a47626161b1e644c48bcee28de1Jesse Hall    ~egl_surface_t();
1295b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopianpublic:
130518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    typedef egl_object_t::LocalRef<egl_surface_t, EGLSurface> Ref;
131518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
132b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    egl_surface_t(egl_display_t* dpy, EGLConfig config,
133b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall            EGLNativeWindowType win, EGLSurface surface,
134258385978c517a47626161b1e644c48bcee28de1Jesse Hall            egl_connection_t const* cnx);
135258385978c517a47626161b1e644c48bcee28de1Jesse Hall
136518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLSurface surface;
137518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLConfig config;
138518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    sp<ANativeWindow> win;
139518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_connection_t const* cnx;
140518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian};
141518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1425b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopianclass egl_context_t: public egl_object_t {
1435b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopianprotected:
1445b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    ~egl_context_t() {}
1455b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopianpublic:
146518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    typedef egl_object_t::LocalRef<egl_context_t, EGLContext> Ref;
147518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
148518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_context_t(EGLDisplay dpy, EGLContext context, EGLConfig config,
149ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            egl_connection_t const* cnx, int version);
15048d438d05f14c2f4bd83ae89f520368cd49122dfMathias Agopian
15148d438d05f14c2f4bd83ae89f520368cd49122dfMathias Agopian    void onLooseCurrent();
15248d438d05f14c2f4bd83ae89f520368cd49122dfMathias Agopian    void onMakeCurrent(EGLSurface draw, EGLSurface read);
15348d438d05f14c2f4bd83ae89f520368cd49122dfMathias Agopian
154518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLDisplay dpy;
155518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLContext context;
156518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLConfig config;
157518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLSurface read;
158518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLSurface draw;
159518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_connection_t const* cnx;
160518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    int version;
16148d438d05f14c2f4bd83ae89f520368cd49122dfMathias Agopian    String8 gl_extensions;
162518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian};
163518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
164518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
165518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
166518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopiantypedef egl_surface_t::Ref  SurfaceRef;
167518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopiantypedef egl_context_t::Ref  ContextRef;
168518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
169518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
170518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
171518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopiantemplate<typename NATIVE, typename EGL>
172518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianstatic inline NATIVE* egl_to_native_cast(EGL arg) {
173518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return reinterpret_cast<NATIVE*>(arg);
174518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
175518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
176518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianstatic inline
177518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianegl_surface_t* get_surface(EGLSurface surface) {
178518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return egl_to_native_cast<egl_surface_t>(surface);
179518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
180518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
181518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianstatic inline
182518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianegl_context_t* get_context(EGLContext context) {
183518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return egl_to_native_cast<egl_context_t>(context);
184518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
185518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
186518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
187518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}; // namespace android
188518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
189518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
190518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#endif // ANDROID_EGL_OBJECT_H
191