1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
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
7 // http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include "libEGL/Texture.hpp"
19 #include "Renderer/Surface.hpp"
21 #include <GLES3/gl3.h>
22 #include <GLES2/gl2ext.h>
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())
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
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);
50 class [[clang::lto_visibility_public]] Image : public sw::Surface, public gl::Object
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)
61 parentTexture->addRef();
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)
72 parentTexture->addRef();
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)
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)
97 static Image *create(Texture *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type);
100 static Image *create(Texture *parentTexture, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type);
103 static Image *create(GLsizei width, GLsizei height, GLenum format, GLenum type, int pitchP);
106 static Image *create(GLsizei width, GLsizei height, sw::Format internalFormat, int multiSampleDepth, bool lockable);
108 GLsizei getWidth() const
113 GLsizei getHeight() const
120 // FIXME: add member if the depth dimension (for 3D textures or 2D testure arrays)
121 // and multi sample depth are ever simultaneously required.
125 GLenum getFormat() const
130 GLenum getType() const
135 sw::Format getInternalFormat() const
137 return internalFormat;
140 bool isShared() const
150 virtual void *lock(unsigned int left, unsigned int top, sw::Lock lock)
152 return lockExternal(left, top, 0, lock, sw::PUBLIC);
155 unsigned int getPitch() const
157 return getExternalPitchB();
160 virtual void unlock()
165 void *lockInternal(int x, int y, int z, sw::Lock lock, sw::Accessor client) override = 0;
166 void unlockInternal() override = 0;
170 UnpackInfo() : alignment(4), rowLength(0), imageHeight(0), skipPixels(0), skipRows(0), skipImages(0) {}
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);
183 void release() override = 0;
184 void unbind(const Texture *parent); // Break parent ownership and release
185 bool isChildOf(const Texture *parent) const;
187 virtual void destroyShared() // Release a shared image
196 const GLsizei height;
199 const sw::Format internalFormat;
202 bool shared; // Used as an EGLImage
204 egl::Texture *parentTexture;
206 ~Image() override = 0;
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);
214 inline GLenum GLPixelFormatFromAndroid(int halFormat)
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;
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;
230 default: return GL_NONE;
234 inline GLenum GLPixelTypeFromAndroid(int halFormat)
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;
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;
250 default: return GL_NONE;
254 class AndroidNativeImage : public egl::Image
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)
264 nativeBuffer->common.incRef(&nativeBuffer->common);
268 ANativeWindowBuffer *nativeBuffer;
270 ~AndroidNativeImage() override
272 sync(); // Wait for any threads that use this image to finish.
274 nativeBuffer->common.decRef(&nativeBuffer->common);
277 void *lockInternal(int x, int y, int z, sw::Lock lock, sw::Accessor client) override
279 LOGLOCK("image=%p op=%s.swsurface lock=%d", this, __FUNCTION__, lock);
281 // Always do this for reference counting.
282 void *data = sw::Surface::lockInternal(x, y, z, lock, client);
286 if(x != 0 || y != 0 || z != 0)
288 ALOGI("badness: %s called with unsupported parms: image=%p x=%d y=%d z=%d", __FUNCTION__, this, x, y, z);
291 LOGLOCK("image=%p op=%s.ani lock=%d", this, __FUNCTION__, lock);
293 // Lock the ANativeWindowBuffer and use its address.
294 data = lockNativeBuffer(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
296 if(lock == sw::LOCK_UNLOCKED)
298 // We're never going to get a corresponding unlock, so unlock
299 // immediately. This keeps the gralloc reference counts sane.
300 unlockNativeBuffer();
307 void unlockInternal() override
309 if(nativeBuffer) // Unlock the buffer from ANativeWindowBuffer
311 LOGLOCK("image=%p op=%s.ani", this, __FUNCTION__);
312 unlockNativeBuffer();
315 LOGLOCK("image=%p op=%s.swsurface", this, __FUNCTION__);
316 sw::Surface::unlockInternal();
319 void *lock(unsigned int left, unsigned int top, sw::Lock lock) override
321 LOGLOCK("image=%p op=%s lock=%d", this, __FUNCTION__, lock);
322 (void)sw::Surface::lockExternal(left, top, 0, lock, sw::PUBLIC);
324 return lockNativeBuffer(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
327 void unlock() override
329 LOGLOCK("image=%p op=%s.ani", this, __FUNCTION__);
330 unlockNativeBuffer();
332 LOGLOCK("image=%p op=%s.swsurface", this, __FUNCTION__);
333 sw::Surface::unlockExternal();
336 void *lockNativeBuffer(int usage)
338 void *buffer = nullptr;
339 GrallocModule::getInstance()->lock(nativeBuffer->handle, usage, 0, 0, nativeBuffer->width, nativeBuffer->height, &buffer);
344 void unlockNativeBuffer()
346 GrallocModule::getInstance()->unlock(nativeBuffer->handle);
349 void release() override
355 #endif // __ANDROID__
359 #endif // egl_Image_hpp