1/*
2 * Copyright (C) 2015 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#include <EGL/egl.h>
18#include <EGL/eglext.h>
19
20#include <pthread.h>
21#include <stdlib.h>
22#include <string.h>
23
24static EGLDisplay gDisplay = (EGLDisplay)1;
25static EGLSyncKHR gFence = (EGLSyncKHR)1;
26
27typedef struct {
28    EGLSurface surface;
29    EGLContext context;
30} ThreadState;
31
32static pthread_key_t ThreadStateKey;
33static pthread_once_t ThreadStateSetupOnce = PTHREAD_ONCE_INIT;
34
35static void destroyThreadState(void* state) {
36    free(state);
37}
38
39static void makeThreadState() {
40    pthread_key_create(&ThreadStateKey, destroyThreadState);
41}
42
43ThreadState* getThreadState() {
44    ThreadState* ptr;
45    pthread_once(&ThreadStateSetupOnce, makeThreadState);
46    if ((ptr = (ThreadState*)pthread_getspecific(ThreadStateKey)) == NULL) {
47        ptr = (ThreadState*)calloc(1, sizeof(ThreadState));
48        ptr->context = EGL_NO_CONTEXT;
49        ptr->surface = EGL_NO_SURFACE;
50        pthread_setspecific(ThreadStateKey, ptr);
51    }
52    return ptr;
53}
54
55EGLint eglGetError(void) {
56    return EGL_SUCCESS;
57}
58
59EGLDisplay eglGetDisplay(EGLNativeDisplayType display_id) {
60    return gDisplay;
61}
62
63EGLBoolean eglInitialize(EGLDisplay dpy, EGLint* major, EGLint* minor) {
64    return EGL_TRUE;
65}
66
67EGLBoolean eglTerminate(EGLDisplay dpy) {
68    return EGL_TRUE;
69}
70
71const char* eglQueryString(EGLDisplay dpy, EGLint name) {
72    if (name == EGL_EXTENSIONS) {
73        return "EGL_KHR_swap_buffers_with_damage";
74    }
75    return "";
76}
77
78EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint* attrib_list, EGLConfig* configs,
79                           EGLint config_size, EGLint* num_config) {
80    memset(configs, 9, sizeof(EGLConfig) * config_size);
81    *num_config = config_size;
82    return EGL_TRUE;
83}
84
85EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win,
86                                  const EGLint* attrib_list) {
87    return (EGLSurface)malloc(sizeof(void*));
88}
89
90EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint* attrib_list) {
91    return (EGLSurface)malloc(sizeof(void*));
92}
93
94EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface) {
95    free(surface);
96    return EGL_TRUE;
97}
98
99EGLBoolean eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint* value) {
100    *value = 1000;
101    return EGL_TRUE;
102}
103
104EGLBoolean eglReleaseThread(void) {
105    return EGL_TRUE;
106}
107
108EGLBoolean eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value) {
109    return EGL_TRUE;
110}
111
112EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval) {
113    return EGL_TRUE;
114}
115
116EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context,
117                            const EGLint* attrib_list) {
118    return (EGLContext)malloc(sizeof(void*));
119}
120EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx) {
121    free(ctx);
122    return EGL_TRUE;
123}
124
125EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) {
126    ThreadState* state = getThreadState();
127    state->surface = draw;
128    state->context = ctx;
129    return EGL_TRUE;
130}
131
132EGLContext eglGetCurrentContext(void) {
133    return getThreadState()->context;
134}
135
136EGLSurface eglGetCurrentSurface(EGLint readdraw) {
137    return getThreadState()->surface;
138}
139
140EGLDisplay eglGetCurrentDisplay(void) {
141    return gDisplay;
142}
143
144EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) {
145    return EGL_TRUE;
146}
147
148EGLBoolean eglSwapBuffersWithDamageKHR(EGLDisplay dpy, EGLSurface surface, EGLint* rects,
149                                       EGLint rectCount) {
150    return EGL_TRUE;
151}
152
153EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
154                              EGLClientBuffer buffer, const EGLint* attrib_list) {
155    return (EGLImageKHR)malloc(sizeof(EGLImageKHR));
156}
157
158EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint* attrib_list) {
159    return gFence;
160}
161
162EGLBoolean eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync) {
163    return EGL_TRUE;
164}
165
166EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout) {
167    return EGL_CONDITION_SATISFIED_KHR;
168}
169
170EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image) {
171    free(image);
172    return EGL_TRUE;
173}
174
175void eglBeginFrame(EGLDisplay dpy, EGLSurface surface) {}
176