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,
79               EGLConfig *configs, EGLint config_size,
80               EGLint *num_config) {
81    memset(configs, 9, sizeof(EGLConfig) * config_size);
82    *num_config = config_size;
83    return EGL_TRUE;
84}
85
86EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
87                  EGLNativeWindowType win,
88                  const EGLint *attrib_list) {
89    return (EGLSurface) malloc(sizeof(void*));
90}
91
92EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
93                   const EGLint *attrib_list) {
94    return (EGLSurface) malloc(sizeof(void*));
95}
96
97EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface) {
98    free(surface);
99    return EGL_TRUE;
100}
101
102EGLBoolean eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
103               EGLint attribute, EGLint *value) {
104    *value = 1000;
105    return EGL_TRUE;
106}
107
108EGLBoolean eglReleaseThread(void) {
109    return EGL_TRUE;
110}
111
112EGLBoolean eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
113                EGLint attribute, EGLint value) {
114    return EGL_TRUE;
115}
116
117EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval) {
118    return EGL_TRUE;
119}
120
121EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config,
122                EGLContext share_context,
123                const EGLint *attrib_list) {
124    return (EGLContext) malloc(sizeof(void*));
125}
126EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx) {
127    free(ctx);
128    return EGL_TRUE;
129}
130
131EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw,
132              EGLSurface read, EGLContext ctx) {
133    ThreadState* state = getThreadState();
134    state->surface = draw;
135    state->context = ctx;
136    return EGL_TRUE;
137}
138
139EGLContext eglGetCurrentContext(void) {
140    return getThreadState()->context;
141}
142
143EGLSurface eglGetCurrentSurface(EGLint readdraw) {
144    return getThreadState()->surface;
145}
146
147EGLDisplay eglGetCurrentDisplay(void) {
148    return gDisplay;
149}
150
151EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) {
152    return EGL_TRUE;
153}
154
155EGLBoolean eglSwapBuffersWithDamageKHR(EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint rectCount) {
156    return EGL_TRUE;
157}
158
159EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list) {
160    return (EGLImageKHR) malloc(sizeof(EGLImageKHR));
161}
162
163EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list) {
164    return gFence;
165}
166
167EGLBoolean eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync) {
168    return EGL_TRUE;
169}
170
171EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout) {
172    return EGL_CONDITION_SATISFIED_KHR;
173}
174
175EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image) {
176    free(image);
177    return EGL_TRUE;
178}
179
180void eglBeginFrame(EGLDisplay dpy, EGLSurface surface) {}
181