1/*
2Copyright (c) 2012, Broadcom Europe Ltd
3All rights reserved.
4
5Redistribution and use in source and binary forms, with or without
6modification, are permitted provided that the following conditions are met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in the
11 documentation and/or other materials provided with the distribution.
12 * Neither the name of the copyright holder nor the
13 names of its contributors may be used to endorse or promote products
14 derived from this software without specific prior written permission.
15
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#define GL_GLEXT_PROTOTYPES /* we want the prototypes so the compiler will check that the signatures match */
29#define VCOS_LOG_CATEGORY (&gl_oes_egl_image_client_log)
30
31#include "interface/khronos/common/khrn_client_mangle.h"
32
33#include "interface/khronos/common/khrn_int_common.h"
34
35#include "interface/khronos/glxx/glxx_client.h"
36#include "interface/khronos/common/khrn_client_rpc.h"
37
38#ifdef RPC_DIRECT
39#include "interface/khronos/glxx/glxx_int_impl.h"
40#include "interface/khronos/glxx/gl20_int_impl.h"
41#endif
42
43#include "interface/khronos/include/GLES2/gl2.h"
44#include "interface/khronos/include/GLES2/gl2ext.h"
45
46VCOS_LOG_CAT_T gl_oes_egl_image_client_log = VCOS_LOG_INIT("gl_oes_egl_image", VCOS_LOG_WARN);
47
48static void set_error(GLXX_CLIENT_STATE_T *state, GLenum error)
49{
50 if (state->error == GL_NO_ERROR)
51 state->error = error;
52}
53
54static bool check_global_image_egl_image(GLuint global_image_id[2],
55 GLeglImageOES image, CLIENT_THREAD_STATE_T *thread,
56 bool render) /* else texture */
57{
58 CLIENT_PROCESS_STATE_T *process = CLIENT_GET_PROCESS_STATE();
59 uint64_t id;
60 uint32_t format, width, height;
61
62 CLIENT_LOCK();
63 id = process->inited ? khrn_global_image_map_lookup(&process->global_image_egl_images, (uint32_t)(uintptr_t)image) : 0;
64 CLIENT_UNLOCK();
65 if (!id) {
66 return false;
67 }
68 global_image_id[0] = (GLuint)id;
69 global_image_id[1] = (GLuint)(id >> 32);
70
71 platform_get_global_image_info(global_image_id[0], global_image_id[1], &format, &width, &height);
72
73 if (!(format & ((thread->opengl.context->type == OPENGL_ES_11) ?
74 (render ? EGL_PIXEL_FORMAT_RENDER_GLES_BRCM : EGL_PIXEL_FORMAT_GLES_TEXTURE_BRCM) :
75 (render ? EGL_PIXEL_FORMAT_RENDER_GLES2_BRCM : EGL_PIXEL_FORMAT_GLES2_TEXTURE_BRCM))) ||
76 (width == 0) || (height == 0)) {
77 return false;
78 }
79
80 /* format and max width/height checks done on server */
81
82 return true;
83}
84
85GL_API void GL_APIENTRY glEGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image)
86{
87 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
88
89 if (IS_OPENGLES_11_OR_20(thread)) {
90#if EGL_BRCM_global_image
91 if ((uintptr_t)image & (1u << 31)) {
92 GLuint global_image_id[2];
93 if (check_global_image_egl_image(global_image_id, image, thread, false)) {
94 RPC_CALL3(glGlobalImageTexture2DOES_impl,
95 thread,
96 GLGLOBALIMAGETEXTURE2DOES_ID,
97 RPC_ENUM(target),
98 RPC_UINT(global_image_id[0]),
99 RPC_UINT(global_image_id[1]));
100 } else {
101 set_error(GLXX_GET_CLIENT_STATE(thread), GL_INVALID_VALUE);
102 }
103 } else {
104#endif
105 RPC_CALL2(glEGLImageTargetTexture2DOES_impl,
106 thread,
107 GLEGLIMAGETARGETTEXTURE2DOES_ID,
108 RPC_ENUM(target),
109 RPC_EGLID(image));
110 RPC_FLUSH(thread);
111#if EGL_BRCM_global_image
112 }
113#endif
114 }
115}
116
117GL_API void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES (GLenum target, GLeglImageOES image)
118{
119 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
120
121 if (IS_OPENGLES_11(thread)) {
122 /* OES_framebuffer_object not supported for GLES1.1 */
123 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
124 if (state->error == GL_NO_ERROR)
125 state->error = GL_INVALID_OPERATION;
126 }
127 else if (IS_OPENGLES_20(thread)) {
128#if EGL_BRCM_global_image
129 if ((uintptr_t)image & (1u << 31)) {
130 GLuint global_image_id[2];
131 if (check_global_image_egl_image(global_image_id, image, thread, true)) {
132 RPC_CALL3(glGlobalImageRenderbufferStorageOES_impl_20,
133 thread,
134 GLGLOBALIMAGERENDERBUFFERSTORAGEOES_ID_20,
135 RPC_ENUM(target),
136 RPC_UINT(global_image_id[0]),
137 RPC_UINT(global_image_id[1]));
138 } else {
139 set_error(GLXX_GET_CLIENT_STATE(thread), GL_INVALID_VALUE);
140 }
141 } else {
142#endif
143 RPC_CALL2(glEGLImageTargetRenderbufferStorageOES_impl_20,
144 thread,
145 GLEGLIMAGETARGETRENDERBUFFERSTORAGEOES_ID_20,
146 RPC_ENUM(target),
147 RPC_EGLID(image));
148#if EGL_BRCM_global_image
149 }
150#endif
151 }
152}
153