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/. */
8 #include "mozilla/gfx/2D.h"
9 #include "mozilla/layers/AsyncTransactionTracker.h" // for AsyncTransactionTracker
10 #include "mozilla/layers/GrallocTextureClient.h"
11 #include "mozilla/layers/CompositableForwarder.h"
12 #include "mozilla/layers/ISurfaceAllocator.h"
13 #include "mozilla/layers/ShadowLayerUtilsGralloc.h"
14 #include "gfx2DGlue.h"
19 using namespace mozilla::gfx
;
20 using namespace android
;
22 GrallocTextureClientOGL::GrallocTextureClientOGL(MaybeMagicGrallocBufferHandle buffer
,
24 gfx::BackendType aMoz2dBackend
,
26 : BufferTextureClient(nullptr, gfx::SurfaceFormat::UNKNOWN
, aMoz2dBackend
, aFlags
)
27 , mGrallocHandle(buffer
)
28 , mMappedBuffer(nullptr)
29 , mMediaBuffer(nullptr)
31 InitWith(buffer
, aSize
);
32 MOZ_COUNT_CTOR(GrallocTextureClientOGL
);
35 GrallocTextureClientOGL::GrallocTextureClientOGL(ISurfaceAllocator
* aAllocator
,
36 gfx::SurfaceFormat aFormat
,
37 gfx::BackendType aMoz2dBackend
,
39 : BufferTextureClient(aAllocator
, aFormat
, aMoz2dBackend
, aFlags
)
40 , mGrallocHandle(null_t())
41 , mMappedBuffer(nullptr)
42 , mMediaBuffer(nullptr)
44 MOZ_COUNT_CTOR(GrallocTextureClientOGL
);
47 GrallocTextureClientOGL::~GrallocTextureClientOGL()
49 MOZ_COUNT_DTOR(GrallocTextureClientOGL
);
50 ISurfaceAllocator
* allocator
= GetAllocator();
51 if (ShouldDeallocateInDestructor()) {
52 allocator
->DeallocGrallocBuffer(&mGrallocHandle
);
54 allocator
->DropGrallocBuffer(&mGrallocHandle
);
59 GrallocTextureClientOGL::InitWith(MaybeMagicGrallocBufferHandle aHandle
, gfx::IntSize aSize
)
61 MOZ_ASSERT(!IsAllocated());
62 MOZ_ASSERT(IsValid());
63 mGrallocHandle
= aHandle
;
64 mGraphicBuffer
= GetGraphicBufferFrom(aHandle
);
69 GrallocTextureClientOGL::ToSurfaceDescriptor(SurfaceDescriptor
& aOutDescriptor
)
71 MOZ_ASSERT(IsValid());
76 aOutDescriptor
= NewSurfaceDescriptorGralloc(mGrallocHandle
, mSize
);
81 GrallocTextureClientOGL::SetRemoveFromCompositableTracker(AsyncTransactionTracker
* aTracker
)
83 mRemoveFromCompositableTracker
= aTracker
;
87 GrallocTextureClientOGL::WaitForBufferOwnership()
89 if (mRemoveFromCompositableTracker
) {
90 mRemoveFromCompositableTracker
->WaitComplete();
91 mRemoveFromCompositableTracker
= nullptr;
94 #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
95 if (mReleaseFenceHandle
.IsValid()) {
96 android::sp
<Fence
> fence
= mReleaseFenceHandle
.mFence
;
97 #if ANDROID_VERSION == 17
98 fence
->waitForever(1000, "GrallocTextureClientOGL::Lock");
99 // 1000 is what Android uses. It is warning timeout ms.
100 // This timeous is removed since ANDROID_VERSION 18.
102 fence
->waitForever("GrallocTextureClientOGL::Lock");
104 mReleaseFenceHandle
= FenceHandle();
110 GrallocTextureClientOGL::Lock(OpenMode aMode
)
112 MOZ_ASSERT(IsValid());
113 if (!IsValid() || !IsAllocated()) {
121 WaitForBufferOwnership();
124 if (aMode
& OpenMode::OPEN_READ
) {
125 usage
|= GRALLOC_USAGE_SW_READ_OFTEN
;
127 if (aMode
& OpenMode::OPEN_WRITE
) {
128 usage
|= GRALLOC_USAGE_SW_WRITE_OFTEN
;
130 int32_t rv
= mGraphicBuffer
->lock(usage
, reinterpret_cast<void**>(&mMappedBuffer
));
132 mMappedBuffer
= nullptr;
133 NS_WARNING("Couldn't lock graphic buffer");
136 return BufferTextureClient::Lock(aMode
);
140 GrallocTextureClientOGL::Unlock()
142 BufferTextureClient::Unlock();
143 mDrawTarget
= nullptr;
145 mMappedBuffer
= nullptr;
146 mGraphicBuffer
->unlock();
151 GrallocTextureClientOGL::GetBuffer() const
153 MOZ_ASSERT(IsValid());
154 NS_WARN_IF_FALSE(mMappedBuffer
, "Trying to get a gralloc buffer without getting the lock?");
155 return mMappedBuffer
;
158 static gfx::SurfaceFormat
159 SurfaceFormatForPixelFormat(android::PixelFormat aFormat
)
162 case PIXEL_FORMAT_RGBA_8888
:
163 return gfx::SurfaceFormat::R8G8B8A8
;
164 case PIXEL_FORMAT_BGRA_8888
:
165 return gfx::SurfaceFormat::B8G8R8A8
;
166 case PIXEL_FORMAT_RGBX_8888
:
167 return gfx::SurfaceFormat::R8G8B8X8
;
168 case PIXEL_FORMAT_RGB_565
:
169 return gfx::SurfaceFormat::R5G6B5
;
171 MOZ_CRASH("Unknown gralloc pixel format");
173 return gfx::SurfaceFormat::R8G8B8A8
;
177 GrallocTextureClientOGL::BorrowDrawTarget()
179 MOZ_ASSERT(IsValid());
180 MOZ_ASSERT(mMappedBuffer
, "Calling TextureClient::BorrowDrawTarget without locking :(");
182 if (!IsValid() || !IsAllocated()) {
190 gfx::SurfaceFormat format
= SurfaceFormatForPixelFormat(mGraphicBuffer
->getPixelFormat());
191 long pixelStride
= mGraphicBuffer
->getStride();
192 long byteStride
= pixelStride
* BytesPerPixel(format
);
193 mDrawTarget
= gfxPlatform::GetPlatform()->CreateDrawTargetForData(GetBuffer(),
201 GrallocTextureClientOGL::AllocateForSurface(gfx::IntSize aSize
,
202 TextureAllocationFlags
)
204 MOZ_ASSERT(IsValid());
207 uint32_t usage
= android::GraphicBuffer::USAGE_SW_READ_OFTEN
|
208 android::GraphicBuffer::USAGE_SW_WRITE_OFTEN
|
209 android::GraphicBuffer::USAGE_HW_TEXTURE
;
212 case gfx::SurfaceFormat::R8G8B8A8
:
213 format
= android::PIXEL_FORMAT_RGBA_8888
;
215 case gfx::SurfaceFormat::B8G8R8A8
:
216 format
= android::PIXEL_FORMAT_RGBA_8888
;
217 mFlags
|= TextureFlags::RB_SWAPPED
;
219 case gfx::SurfaceFormat::R8G8B8X8
:
220 format
= android::PIXEL_FORMAT_RGBX_8888
;
222 case gfx::SurfaceFormat::B8G8R8X8
:
223 format
= android::PIXEL_FORMAT_RGBX_8888
;
224 mFlags
|= TextureFlags::RB_SWAPPED
;
226 case gfx::SurfaceFormat::R5G6B5
:
227 format
= android::PIXEL_FORMAT_RGB_565
;
229 case gfx::SurfaceFormat::A8
:
230 NS_WARNING("gralloc does not support gfx::SurfaceFormat::A8");
233 NS_WARNING("Unsupported surface format");
237 return AllocateGralloc(aSize
, format
, usage
);
241 GrallocTextureClientOGL::AllocateForYCbCr(gfx::IntSize aYSize
, gfx::IntSize aCbCrSize
, StereoMode aStereoMode
)
243 MOZ_ASSERT(IsValid());
244 return AllocateGralloc(aYSize
,
245 HAL_PIXEL_FORMAT_YV12
,
246 android::GraphicBuffer::USAGE_SW_READ_OFTEN
);
250 GrallocTextureClientOGL::AllocateForGLRendering(gfx::IntSize aSize
)
252 MOZ_ASSERT(IsValid());
255 uint32_t usage
= android::GraphicBuffer::USAGE_HW_RENDER
|
256 android::GraphicBuffer::USAGE_HW_TEXTURE
;
259 case gfx::SurfaceFormat::R8G8B8A8
:
260 case gfx::SurfaceFormat::B8G8R8A8
:
261 format
= android::PIXEL_FORMAT_RGBA_8888
;
263 case gfx::SurfaceFormat::R8G8B8X8
:
264 case gfx::SurfaceFormat::B8G8R8X8
:
265 // there is no android BGRX format?
266 format
= android::PIXEL_FORMAT_RGBX_8888
;
268 case gfx::SurfaceFormat::R5G6B5
:
269 format
= android::PIXEL_FORMAT_RGB_565
;
272 NS_WARNING("Unsupported surface format");
276 return AllocateGralloc(aSize
, format
, usage
);
280 GrallocTextureClientOGL::AllocateGralloc(gfx::IntSize aSize
,
281 uint32_t aAndroidFormat
,
284 MOZ_ASSERT(IsValid());
285 ISurfaceAllocator
* allocator
= GetAllocator();
287 MaybeMagicGrallocBufferHandle handle
;
288 bool allocateResult
=
289 allocator
->AllocGrallocBuffer(aSize
,
293 if (!allocateResult
) {
297 sp
<GraphicBuffer
> graphicBuffer
= GetGraphicBufferFrom(handle
);
298 if (!graphicBuffer
.get()) {
302 if (graphicBuffer
->initCheck() != NO_ERROR
) {
306 mGrallocHandle
= handle
;
307 mGraphicBuffer
= graphicBuffer
;
313 GrallocTextureClientOGL::IsAllocated() const
315 return !!mGraphicBuffer
.get();
319 GrallocTextureClientOGL::Allocate(uint32_t aSize
)
322 MOZ_CRASH("This method should never be called.");
327 GrallocTextureClientOGL::GetBufferSize() const
330 MOZ_CRASH("This method should never be called.");
334 } // namesapace layers
335 } // namesapace mozilla
337 #endif // MOZ_WIDGET_GONK