Bug 971946 - Remove TextureClientData r=nical
[gecko.git] / gfx / layers / opengl / GrallocTextureClient.cpp
blobeab6cc109a9514d38d3916f73163d8b365ce50fe
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifdef MOZ_WIDGET_GONK
8 #include "mozilla/gfx/2D.h"
9 #include "mozilla/layers/GrallocTextureClient.h"
10 #include "mozilla/layers/CompositableForwarder.h"
11 #include "mozilla/layers/ISurfaceAllocator.h"
12 #include "mozilla/layers/ShadowLayerUtilsGralloc.h"
13 #include "gfx2DGlue.h"
15 namespace mozilla {
16 namespace layers {
18 using namespace mozilla::gfx;
19 using namespace android;
21 GrallocTextureClientOGL::GrallocTextureClientOGL(MaybeMagicGrallocBufferHandle buffer,
22 gfx::IntSize aSize,
23 gfx::BackendType aMoz2dBackend,
24 TextureFlags aFlags)
25 : BufferTextureClient(nullptr, gfx::SurfaceFormat::UNKNOWN, aMoz2dBackend, aFlags)
26 , mGrallocHandle(buffer)
27 , mMappedBuffer(nullptr)
28 , mMediaBuffer(nullptr)
30 InitWith(buffer, aSize);
31 MOZ_COUNT_CTOR(GrallocTextureClientOGL);
34 GrallocTextureClientOGL::GrallocTextureClientOGL(ISurfaceAllocator* aAllocator,
35 gfx::SurfaceFormat aFormat,
36 gfx::BackendType aMoz2dBackend,
37 TextureFlags aFlags)
38 : BufferTextureClient(aAllocator, aFormat, aMoz2dBackend, aFlags)
39 , mMappedBuffer(nullptr)
40 , mMediaBuffer(nullptr)
42 MOZ_COUNT_CTOR(GrallocTextureClientOGL);
45 GrallocTextureClientOGL::~GrallocTextureClientOGL()
47 MOZ_COUNT_DTOR(GrallocTextureClientOGL);
48 if (ShouldDeallocateInDestructor()) {
49 ISurfaceAllocator* allocator = GetAllocator();
50 allocator->DeallocGrallocBuffer(&mGrallocHandle);
54 void
55 GrallocTextureClientOGL::InitWith(MaybeMagicGrallocBufferHandle aHandle, gfx::IntSize aSize)
57 MOZ_ASSERT(!IsAllocated());
58 MOZ_ASSERT(IsValid());
59 mGrallocHandle = aHandle;
60 mGraphicBuffer = GetGraphicBufferFrom(aHandle);
61 mSize = aSize;
64 bool
65 GrallocTextureClientOGL::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
67 MOZ_ASSERT(IsValid());
68 if (!IsAllocated()) {
69 return false;
72 aOutDescriptor = NewSurfaceDescriptorGralloc(mGrallocHandle, mSize);
73 return true;
76 void
77 GrallocTextureClientOGL::SetReleaseFenceHandle(FenceHandle aReleaseFenceHandle)
79 mReleaseFenceHandle = aReleaseFenceHandle;
82 void
83 GrallocTextureClientOGL::WaitReleaseFence()
85 #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
86 if (mReleaseFenceHandle.IsValid()) {
87 android::sp<Fence> fence = mReleaseFenceHandle.mFence;
88 #if ANDROID_VERSION == 17
89 fence->waitForever(1000, "GrallocTextureClientOGL::Lock");
90 // 1000 is what Android uses. It is warning timeout ms.
91 // This timeous is removed since ANDROID_VERSION 18.
92 #else
93 fence->waitForever("GrallocTextureClientOGL::Lock");
94 #endif
95 mReleaseFenceHandle = FenceHandle();
97 #endif
100 bool
101 GrallocTextureClientOGL::Lock(OpenMode aMode)
103 MOZ_ASSERT(IsValid());
104 if (!IsValid() || !IsAllocated()) {
105 return false;
108 if (mMappedBuffer) {
109 return true;
112 WaitReleaseFence();
114 uint32_t usage = 0;
115 if (aMode & OpenMode::OPEN_READ) {
116 usage |= GRALLOC_USAGE_SW_READ_OFTEN;
118 if (aMode & OpenMode::OPEN_WRITE) {
119 usage |= GRALLOC_USAGE_SW_WRITE_OFTEN;
121 int32_t rv = mGraphicBuffer->lock(usage, reinterpret_cast<void**>(&mMappedBuffer));
122 if (rv) {
123 mMappedBuffer = nullptr;
124 NS_WARNING("Couldn't lock graphic buffer");
125 return false;
127 return BufferTextureClient::Lock(aMode);
130 void
131 GrallocTextureClientOGL::Unlock()
133 BufferTextureClient::Unlock();
134 mDrawTarget = nullptr;
135 if (mMappedBuffer) {
136 mMappedBuffer = nullptr;
137 mGraphicBuffer->unlock();
141 uint8_t*
142 GrallocTextureClientOGL::GetBuffer() const
144 MOZ_ASSERT(IsValid());
145 NS_WARN_IF_FALSE(mMappedBuffer, "Trying to get a gralloc buffer without getting the lock?");
146 return mMappedBuffer;
149 static gfx::SurfaceFormat
150 SurfaceFormatForPixelFormat(android::PixelFormat aFormat)
152 switch (aFormat) {
153 case PIXEL_FORMAT_RGBA_8888:
154 return gfx::SurfaceFormat::R8G8B8A8;
155 case PIXEL_FORMAT_BGRA_8888:
156 return gfx::SurfaceFormat::B8G8R8A8;
157 case PIXEL_FORMAT_RGBX_8888:
158 return gfx::SurfaceFormat::R8G8B8X8;
159 case PIXEL_FORMAT_RGB_565:
160 return gfx::SurfaceFormat::R5G6B5;
161 default:
162 MOZ_CRASH("Unknown gralloc pixel format");
164 return gfx::SurfaceFormat::R8G8B8A8;
167 TemporaryRef<gfx::DrawTarget>
168 GrallocTextureClientOGL::GetAsDrawTarget()
170 MOZ_ASSERT(IsValid());
171 MOZ_ASSERT(mMappedBuffer, "Calling TextureClient::GetAsDrawTarget without locking :(");
173 if (mDrawTarget) {
174 return mDrawTarget;
177 gfx::SurfaceFormat format = SurfaceFormatForPixelFormat(mGraphicBuffer->getPixelFormat());
178 long pixelStride = mGraphicBuffer->getStride();
179 long byteStride = pixelStride * BytesPerPixel(format);
180 mDrawTarget = gfxPlatform::GetPlatform()->CreateDrawTargetForData(GetBuffer(),
181 mSize,
182 byteStride,
183 mFormat);
184 return mDrawTarget;
187 bool
188 GrallocTextureClientOGL::AllocateForSurface(gfx::IntSize aSize,
189 TextureAllocationFlags)
191 MOZ_ASSERT(IsValid());
193 uint32_t format;
194 uint32_t usage = android::GraphicBuffer::USAGE_SW_READ_OFTEN |
195 android::GraphicBuffer::USAGE_SW_WRITE_OFTEN |
196 android::GraphicBuffer::USAGE_HW_TEXTURE;
198 switch (mFormat) {
199 case gfx::SurfaceFormat::R8G8B8A8:
200 format = android::PIXEL_FORMAT_RGBA_8888;
201 break;
202 case gfx::SurfaceFormat::B8G8R8A8:
203 format = android::PIXEL_FORMAT_RGBA_8888;
204 mFlags |= TextureFlags::RB_SWAPPED;
205 break;
206 case gfx::SurfaceFormat::R8G8B8X8:
207 format = android::PIXEL_FORMAT_RGBX_8888;
208 break;
209 case gfx::SurfaceFormat::B8G8R8X8:
210 format = android::PIXEL_FORMAT_RGBX_8888;
211 mFlags |= TextureFlags::RB_SWAPPED;
212 break;
213 case gfx::SurfaceFormat::R5G6B5:
214 format = android::PIXEL_FORMAT_RGB_565;
215 break;
216 case gfx::SurfaceFormat::A8:
217 NS_WARNING("gralloc does not support gfx::SurfaceFormat::A8");
218 return false;
219 default:
220 NS_WARNING("Unsupported surface format");
221 return false;
224 return AllocateGralloc(aSize, format, usage);
227 bool
228 GrallocTextureClientOGL::AllocateForYCbCr(gfx::IntSize aYSize, gfx::IntSize aCbCrSize, StereoMode aStereoMode)
230 MOZ_ASSERT(IsValid());
231 return AllocateGralloc(aYSize,
232 HAL_PIXEL_FORMAT_YV12,
233 android::GraphicBuffer::USAGE_SW_READ_OFTEN);
236 bool
237 GrallocTextureClientOGL::AllocateForGLRendering(gfx::IntSize aSize)
239 MOZ_ASSERT(IsValid());
241 uint32_t format;
242 uint32_t usage = android::GraphicBuffer::USAGE_HW_RENDER |
243 android::GraphicBuffer::USAGE_HW_TEXTURE;
245 switch (mFormat) {
246 case gfx::SurfaceFormat::R8G8B8A8:
247 case gfx::SurfaceFormat::B8G8R8A8:
248 format = android::PIXEL_FORMAT_RGBA_8888;
249 break;
250 case gfx::SurfaceFormat::R8G8B8X8:
251 case gfx::SurfaceFormat::B8G8R8X8:
252 // there is no android BGRX format?
253 format = android::PIXEL_FORMAT_RGBX_8888;
254 break;
255 case gfx::SurfaceFormat::R5G6B5:
256 format = android::PIXEL_FORMAT_RGB_565;
257 break;
258 default:
259 NS_WARNING("Unsupported surface format");
260 return false;
263 return AllocateGralloc(aSize, format, usage);
266 bool
267 GrallocTextureClientOGL::AllocateGralloc(gfx::IntSize aSize,
268 uint32_t aAndroidFormat,
269 uint32_t aUsage)
271 MOZ_ASSERT(IsValid());
272 ISurfaceAllocator* allocator = GetAllocator();
274 MaybeMagicGrallocBufferHandle handle;
275 bool allocateResult =
276 allocator->AllocGrallocBuffer(aSize,
277 aAndroidFormat,
278 aUsage,
279 &handle);
280 if (!allocateResult) {
281 return false;
284 sp<GraphicBuffer> graphicBuffer = GetGraphicBufferFrom(handle);
285 if (!graphicBuffer.get()) {
286 return false;
289 if (graphicBuffer->initCheck() != NO_ERROR) {
290 return false;
293 mGrallocHandle = handle;
294 mGraphicBuffer = graphicBuffer;
295 mSize = aSize;
296 return true;
299 bool
300 GrallocTextureClientOGL::IsAllocated() const
302 return !!mGraphicBuffer.get();
305 bool
306 GrallocTextureClientOGL::Allocate(uint32_t aSize)
308 // see Bug 908196
309 MOZ_CRASH("This method should never be called.");
310 return false;
313 size_t
314 GrallocTextureClientOGL::GetBufferSize() const
316 // see Bug 908196
317 MOZ_CRASH("This method should never be called.");
318 return 0;
321 } // namesapace layers
322 } // namesapace mozilla
324 #endif // MOZ_WIDGET_GONK