Correct robust buffer access behavior tests
[platform/upstream/VK-GL-CTS.git] / modules / egl / teglAndroidUtil.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program EGL Module
3  * ---------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Android-specific operations.
22  *//*--------------------------------------------------------------------*/
23
24 #include "teglAndroidUtil.hpp"
25
26 #include "deStringUtil.hpp"
27 #include "tcuTextureUtil.hpp"
28 #include "gluTextureUtil.hpp"
29 #include "glwEnums.hpp"
30 #include "eglwLibrary.hpp"
31 #include "eglwEnums.hpp"
32
33 #if (DE_OS == DE_OS_ANDROID)
34 #       include "tcuAndroidInternals.hpp"
35 #endif
36
37 namespace deqp
38 {
39 namespace egl
40 {
41 namespace Image
42 {
43 using std::string;
44 using de::MovePtr;
45 using tcu::PixelBufferAccess;
46 using tcu::TextureFormat;
47 using tcu::Texture2D;
48 using eglu::AttribMap;
49 using namespace glw;
50 using namespace eglw;
51
52 #if (DE_OS != DE_OS_ANDROID)
53
54 MovePtr<ImageSource> createAndroidNativeImageSource     (GLenum format)
55 {
56         return createUnsupportedImageSource("Not Android platform", format);
57 }
58
59 #else // DE_OS == DE_OS_ANDROID
60
61 using tcu::Android::internal::LibUI;
62 using tcu::Android::internal::GraphicBuffer;
63 using tcu::Android::internal::PixelFormat;
64 using tcu::Android::internal::status_t;
65
66 PixelFormat getPixelFormat (GLenum format)
67 {
68         switch (format)
69         {
70                 case GL_RGB565:         return tcu::Android::internal::PIXEL_FORMAT_RGB_565;
71                 case GL_RGB8:           return tcu::Android::internal::PIXEL_FORMAT_RGB_888;
72                 case GL_RGBA4:          return tcu::Android::internal::PIXEL_FORMAT_RGBA_4444;
73                 case GL_RGB5_A1:        return tcu::Android::internal::PIXEL_FORMAT_RGBA_5551;
74                 case GL_RGBA8:          return tcu::Android::internal::PIXEL_FORMAT_RGBA_8888;
75                 default:                        TCU_THROW(NotSupportedError, "Texture format unsupported by Android");
76         }
77 }
78
79 class AndroidNativeClientBuffer : public ClientBuffer
80 {
81 public:
82                                                         AndroidNativeClientBuffer       (const LibUI& lib, GLenum format);
83         EGLClientBuffer                 get                                                     (void) const { return reinterpret_cast<EGLClientBuffer>(m_windowBuffer); }
84         GraphicBuffer&                  getGraphicBuffer                        (void) { return m_graphicBuffer; }
85
86 private:
87         GraphicBuffer                   m_graphicBuffer;
88         ANativeWindowBuffer*    m_windowBuffer;
89 };
90
91 AndroidNativeClientBuffer::AndroidNativeClientBuffer (const LibUI& lib, GLenum format)
92         : m_graphicBuffer       (lib, 64, 64, getPixelFormat(format),
93                                                  GraphicBuffer::USAGE_SW_READ_OFTEN             |
94                                                  GraphicBuffer::USAGE_SW_WRITE_RARELY   |
95                                                  GraphicBuffer::USAGE_HW_TEXTURE                |
96                                                  GraphicBuffer::USAGE_HW_RENDER)
97         , m_windowBuffer        (m_graphicBuffer.getNativeBuffer())
98 {
99 }
100
101 class AndroidNativeImageSource : public ImageSource
102 {
103 public:
104                                                         AndroidNativeImageSource        (GLenum format) : m_format(format), m_libui(DE_NULL) {}
105                                                         ~AndroidNativeImageSource       (void);
106         MovePtr<ClientBuffer>   createBuffer                            (const glw::Functions&, Texture2D*) const;
107         string                                  getRequiredExtension            (void) const { return "EGL_ANDROID_image_native_buffer"; }
108         EGLImageKHR                             createImage                                     (const Library& egl, EGLDisplay dpy, EGLContext ctx, EGLClientBuffer clientBuffer) const;
109         GLenum                                  getEffectiveFormat                      (void) const { return m_format; }
110
111 protected:
112         GLenum                                  m_format;
113
114         const LibUI&                    getLibUI                                        (void) const;
115
116 private:
117         mutable LibUI*                  m_libui;
118 };
119
120 AndroidNativeImageSource::~AndroidNativeImageSource (void)
121 {
122         delete m_libui;
123 }
124
125 const LibUI& AndroidNativeImageSource::getLibUI (void) const
126 {
127         if (!m_libui)
128                 m_libui = new LibUI();
129
130         return *m_libui;
131 }
132
133 void checkStatus (status_t status)
134 {
135         if (status != tcu::Android::internal::OK)
136                 TCU_FAIL(("Android error: status code " + de::toString(status)).c_str());
137 }
138
139 MovePtr<ClientBuffer> AndroidNativeImageSource::createBuffer (const glw::Functions&, Texture2D* ref) const
140 {
141         MovePtr<AndroidNativeClientBuffer>      buffer                  (new AndroidNativeClientBuffer(getLibUI(), m_format));
142         GraphicBuffer&                                          graphicBuffer   = buffer->getGraphicBuffer();
143         if (ref != DE_NULL)
144         {
145                 const TextureFormat     texFormat       = glu::mapGLInternalFormat(m_format);
146                 void*                           bufferData      = DE_NULL;
147
148                 *ref = Texture2D(texFormat, 64, 64);
149                 ref->allocLevel(0);
150                 tcu::fillWithComponentGradients(ref->getLevel(0),
151                                                                                 tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
152                                                                                 tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
153                 checkStatus(graphicBuffer.lock(GraphicBuffer::USAGE_SW_WRITE_RARELY, &bufferData));
154                 {
155                         PixelBufferAccess nativeBuffer(texFormat, 64, 64, 1, bufferData);
156                         tcu::copy(nativeBuffer, ref->getLevel(0));
157                 }
158                 checkStatus(graphicBuffer.unlock());
159         }
160         return MovePtr<ClientBuffer>(buffer);
161 }
162
163 EGLImageKHR AndroidNativeImageSource::createImage (const Library& egl, EGLDisplay dpy, EGLContext, EGLClientBuffer clientBuffer) const
164 {
165         static const EGLint attribs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
166         const EGLImageKHR       image           = egl.createImageKHR(dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, clientBuffer, attribs);
167
168         EGLU_CHECK_MSG(egl, "eglCreateImageKHR()");
169         return image;
170 }
171
172 MovePtr<ImageSource> createAndroidNativeImageSource     (GLenum format)
173 {
174         try
175         {
176                 return MovePtr<ImageSource>(new AndroidNativeImageSource(format));
177         }
178         catch (const std::runtime_error& exc)
179         {
180                 return createUnsupportedImageSource(string("Android native buffers unsupported: ") + exc.what(), format);
181         }
182 }
183
184 #endif // DE_OS == DE_OS_ANDROID
185
186 } // Image
187 } // egl
188 } // deqp