OSDN Git Service

Refactor Android includes.
[android-x86/external-swiftshader.git] / src / OpenGL / common / Image.hpp
1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #ifndef egl_Image_hpp
16 #define egl_Image_hpp
17
18 #include "libEGL/Texture.hpp"
19 #include "Renderer/Surface.hpp"
20
21 #include <GLES3/gl3.h>
22 #include <GLES2/gl2ext.h>
23
24 #if defined(__ANDROID__)
25 #include <system/window.h>
26 #include "../../Common/GrallocAndroid.hpp"
27 #include "../../Common/DebugAndroid.hpp"
28 #define LOGLOCK(fmt, ...) // ALOGI(fmt " tid=%d", ##__VA_ARGS__, gettid())
29 #else
30 #include <assert.h>
31 #define LOGLOCK(...)
32 #endif
33
34 // Implementation-defined formats
35 #define SW_YV12_BT601 0x32315659   // YCrCb 4:2:0 Planar, 16-byte aligned, BT.601 color space, studio swing
36 #define SW_YV12_BT709 0x48315659   // YCrCb 4:2:0 Planar, 16-byte aligned, BT.709 color space, studio swing
37 #define SW_YV12_JFIF  0x4A315659   // YCrCb 4:2:0 Planar, 16-byte aligned, BT.601 color space, full swing
38
39 namespace egl
40 {
41
42 class Context;
43
44 sw::Format ConvertFormatType(GLenum format, GLenum type);
45 sw::Format SelectInternalFormat(GLenum format, GLenum type);
46 GLsizei ComputePitch(GLsizei width, GLenum format, GLenum type, GLint alignment);
47 GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format);
48 size_t ComputePackingOffset(GLenum format, GLenum type, GLsizei width, GLsizei height, GLint alignment, GLint skipImages, GLint skipRows, GLint skipPixels);
49
50 class [[clang::lto_visibility_public]] Image : public sw::Surface, public gl::Object
51 {
52 protected:
53         // 2D texture image
54         Image(Texture *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type)
55                 : sw::Surface(parentTexture->getResource(), width, height, 1, SelectInternalFormat(format, type), true, true),
56                   width(width), height(height), format(format), type(type), internalFormat(SelectInternalFormat(format, type)), depth(1),
57                   parentTexture(parentTexture)
58         {
59                 shared = false;
60                 Object::addRef();
61                 parentTexture->addRef();
62         }
63
64         // 3D texture image
65         Image(Texture *parentTexture, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type)
66                 : sw::Surface(parentTexture->getResource(), width, height, depth, SelectInternalFormat(format, type), true, true),
67                   width(width), height(height), format(format), type(type), internalFormat(SelectInternalFormat(format, type)), depth(depth),
68                   parentTexture(parentTexture)
69         {
70                 shared = false;
71                 Object::addRef();
72                 parentTexture->addRef();
73         }
74
75         // Native EGL image
76         Image(GLsizei width, GLsizei height, GLenum format, GLenum type, int pitchP)
77                 : sw::Surface(nullptr, width, height, 1, SelectInternalFormat(format, type), true, true, pitchP),
78                   width(width), height(height), format(format), type(type), internalFormat(SelectInternalFormat(format, type)), depth(1),
79                   parentTexture(nullptr)
80         {
81                 shared = true;
82                 Object::addRef();
83         }
84
85         // Render target
86         Image(GLsizei width, GLsizei height, sw::Format internalFormat, int multiSampleDepth, bool lockable)
87                 : sw::Surface(nullptr, width, height, multiSampleDepth, internalFormat, lockable, true),
88                   width(width), height(height), format(0 /*GL_NONE*/), type(0 /*GL_NONE*/), internalFormat(internalFormat), depth(multiSampleDepth),
89                   parentTexture(nullptr)
90         {
91                 shared = false;
92                 Object::addRef();
93         }
94
95 public:
96         // 2D texture image
97         static Image *create(Texture *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type);
98
99         // 3D texture image
100         static Image *create(Texture *parentTexture, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type);
101
102         // Native EGL image
103         static Image *create(GLsizei width, GLsizei height, GLenum format, GLenum type, int pitchP);
104
105         // Render target
106         static Image *create(GLsizei width, GLsizei height, sw::Format internalFormat, int multiSampleDepth, bool lockable);
107
108         GLsizei getWidth() const
109         {
110                 return width;
111         }
112
113         GLsizei getHeight() const
114         {
115                 return height;
116         }
117
118         int getDepth() const
119         {
120                 // FIXME: add member if the depth dimension (for 3D textures or 2D testure arrays)
121                 // and multi sample depth are ever simultaneously required.
122                 return depth;
123         }
124
125         GLenum getFormat() const
126         {
127                 return format;
128         }
129
130         GLenum getType() const
131         {
132                 return type;
133         }
134
135         sw::Format getInternalFormat() const
136         {
137                 return internalFormat;
138         }
139
140         bool isShared() const
141         {
142                 return shared;
143         }
144
145         void markShared()
146         {
147                 shared = true;
148         }
149
150         virtual void *lock(unsigned int left, unsigned int top, sw::Lock lock)
151         {
152                 return lockExternal(left, top, 0, lock, sw::PUBLIC);
153         }
154
155         unsigned int getPitch() const
156         {
157                 return getExternalPitchB();
158         }
159
160         virtual void unlock()
161         {
162                 unlockExternal();
163         }
164
165         void *lockInternal(int x, int y, int z, sw::Lock lock, sw::Accessor client) override = 0;
166         void unlockInternal() override = 0;
167
168         struct UnpackInfo
169         {
170                 UnpackInfo() : alignment(4), rowLength(0), imageHeight(0), skipPixels(0), skipRows(0), skipImages(0) {}
171
172                 GLint alignment;
173                 GLint rowLength;
174                 GLint imageHeight;
175                 GLint skipPixels;
176                 GLint skipRows;
177                 GLint skipImages;
178         };
179
180         void loadImageData(Context *context, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const UnpackInfo& unpackInfo, const void *input);
181         void loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
182
183         void release() override = 0;
184         void unbind(const Texture *parent);   // Break parent ownership and release
185         bool isChildOf(const Texture *parent) const;
186
187         virtual void destroyShared()   // Release a shared image
188         {
189                 assert(shared);
190                 shared = false;
191                 release();
192         }
193
194 protected:
195         const GLsizei width;
196         const GLsizei height;
197         const GLenum format;
198         const GLenum type;
199         const sw::Format internalFormat;
200         const int depth;
201
202         bool shared;   // Used as an EGLImage
203
204         egl::Texture *parentTexture;
205
206         ~Image() override = 0;
207
208         void loadD24S8ImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, int inputPitch, int inputHeight, const void *input, void *buffer);
209         void loadD32FS8ImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, int inputPitch, int inputHeight, const void *input, void *buffer);
210 };
211
212 #ifdef __ANDROID__
213
214 inline GLenum GLPixelFormatFromAndroid(int halFormat)
215 {
216         switch(halFormat)
217         {
218         case HAL_PIXEL_FORMAT_RGBA_8888: return GL_RGBA8;
219 #if ANDROID_PLATFORM_SDK_VERSION > 16
220         case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: return GL_RGB8;
221 #endif
222         case HAL_PIXEL_FORMAT_RGBX_8888: return GL_RGB8;
223         case HAL_PIXEL_FORMAT_RGB_888:   return GL_NONE;   // Unsupported
224         case HAL_PIXEL_FORMAT_BGRA_8888: return GL_BGRA8_EXT;
225         case HAL_PIXEL_FORMAT_RGB_565:   return GL_RGB565;
226         case HAL_PIXEL_FORMAT_YV12:      return SW_YV12_BT601;
227 #ifdef GRALLOC_MODULE_API_VERSION_0_2
228         case HAL_PIXEL_FORMAT_YCbCr_420_888: return SW_YV12_BT601;
229 #endif
230         default:                         return GL_NONE;
231         }
232 }
233
234 inline GLenum GLPixelTypeFromAndroid(int halFormat)
235 {
236         switch(halFormat)
237         {
238         case HAL_PIXEL_FORMAT_RGBA_8888: return GL_UNSIGNED_BYTE;
239 #if ANDROID_PLATFORM_SDK_VERSION > 16
240         case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: return GL_UNSIGNED_BYTE;
241 #endif
242         case HAL_PIXEL_FORMAT_RGBX_8888: return GL_UNSIGNED_BYTE;
243         case HAL_PIXEL_FORMAT_RGB_888:   return GL_NONE;   // Unsupported
244         case HAL_PIXEL_FORMAT_BGRA_8888: return GL_UNSIGNED_BYTE;
245         case HAL_PIXEL_FORMAT_RGB_565:   return GL_UNSIGNED_SHORT_5_6_5;
246         case HAL_PIXEL_FORMAT_YV12:      return GL_UNSIGNED_BYTE;
247 #ifdef GRALLOC_MODULE_API_VERSION_0_2
248         case HAL_PIXEL_FORMAT_YCbCr_420_888: return GL_UNSIGNED_BYTE;
249 #endif
250         default:                         return GL_NONE;
251         }
252 }
253
254 class AndroidNativeImage : public egl::Image
255 {
256 public:
257         explicit AndroidNativeImage(ANativeWindowBuffer *nativeBuffer)
258                 : egl::Image(nativeBuffer->width, nativeBuffer->height,
259                              GLPixelFormatFromAndroid(nativeBuffer->format),
260                              GLPixelTypeFromAndroid(nativeBuffer->format),
261                              nativeBuffer->stride),
262                   nativeBuffer(nativeBuffer)
263         {
264                 nativeBuffer->common.incRef(&nativeBuffer->common);
265         }
266
267 private:
268         ANativeWindowBuffer *nativeBuffer;
269
270         ~AndroidNativeImage() override
271         {
272                 sync();   // Wait for any threads that use this image to finish.
273
274                 nativeBuffer->common.decRef(&nativeBuffer->common);
275         }
276
277         void *lockInternal(int x, int y, int z, sw::Lock lock, sw::Accessor client) override
278         {
279                 LOGLOCK("image=%p op=%s.swsurface lock=%d", this, __FUNCTION__, lock);
280
281                 // Always do this for reference counting.
282                 void *data = sw::Surface::lockInternal(x, y, z, lock, client);
283
284                 if(nativeBuffer)
285                 {
286                         if(x != 0 || y != 0 || z != 0)
287                         {
288                                 ALOGI("badness: %s called with unsupported parms: image=%p x=%d y=%d z=%d", __FUNCTION__, this, x, y, z);
289                         }
290
291                         LOGLOCK("image=%p op=%s.ani lock=%d", this, __FUNCTION__, lock);
292
293                         // Lock the ANativeWindowBuffer and use its address.
294                         data = lockNativeBuffer(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
295
296                         if(lock == sw::LOCK_UNLOCKED)
297                         {
298                                 // We're never going to get a corresponding unlock, so unlock
299                                 // immediately. This keeps the gralloc reference counts sane.
300                                 unlockNativeBuffer();
301                         }
302                 }
303
304                 return data;
305         }
306
307         void unlockInternal() override
308         {
309                 if(nativeBuffer)   // Unlock the buffer from ANativeWindowBuffer
310                 {
311                         LOGLOCK("image=%p op=%s.ani", this, __FUNCTION__);
312                         unlockNativeBuffer();
313                 }
314
315                 LOGLOCK("image=%p op=%s.swsurface", this, __FUNCTION__);
316                 sw::Surface::unlockInternal();
317         }
318
319         void *lock(unsigned int left, unsigned int top, sw::Lock lock) override
320         {
321                 LOGLOCK("image=%p op=%s lock=%d", this, __FUNCTION__, lock);
322                 (void)sw::Surface::lockExternal(left, top, 0, lock, sw::PUBLIC);
323
324                 return lockNativeBuffer(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
325         }
326
327         void unlock() override
328         {
329                 LOGLOCK("image=%p op=%s.ani", this, __FUNCTION__);
330                 unlockNativeBuffer();
331
332                 LOGLOCK("image=%p op=%s.swsurface", this, __FUNCTION__);
333                 sw::Surface::unlockExternal();
334         }
335
336         void *lockNativeBuffer(int usage)
337         {
338                 void *buffer = nullptr;
339                 GrallocModule::getInstance()->lock(nativeBuffer->handle, usage, 0, 0, nativeBuffer->width, nativeBuffer->height, &buffer);
340
341                 return buffer;
342         }
343
344         void unlockNativeBuffer()
345         {
346                 GrallocModule::getInstance()->unlock(nativeBuffer->handle);
347         }
348
349         void release() override
350         {
351                 Image::release();
352         }
353 };
354
355 #endif  // __ANDROID__
356
357 }
358
359 #endif   // egl_Image_hpp