gfx/layers/opengl/GrallocTextureClient.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
michael@0 2 // * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #ifdef MOZ_WIDGET_GONK
michael@0 7
michael@0 8 #include "mozilla/gfx/2D.h"
michael@0 9 #include "mozilla/layers/GrallocTextureClient.h"
michael@0 10 #include "mozilla/layers/CompositableForwarder.h"
michael@0 11 #include "mozilla/layers/ISurfaceAllocator.h"
michael@0 12 #include "mozilla/layers/ShadowLayerUtilsGralloc.h"
michael@0 13 #include "gfx2DGlue.h"
michael@0 14
michael@0 15 namespace mozilla {
michael@0 16 namespace layers {
michael@0 17
michael@0 18 using namespace mozilla::gfx;
michael@0 19 using namespace android;
michael@0 20
michael@0 21 class GrallocTextureClientData : public TextureClientData {
michael@0 22 public:
michael@0 23 GrallocTextureClientData(GrallocBufferActor* aActor)
michael@0 24 : mGrallocActor(aActor)
michael@0 25 {
michael@0 26 MOZ_COUNT_CTOR(GrallocTextureClientData);
michael@0 27 }
michael@0 28
michael@0 29 ~GrallocTextureClientData()
michael@0 30 {
michael@0 31 MOZ_COUNT_DTOR(GrallocTextureClientData);
michael@0 32 MOZ_ASSERT(!mGrallocActor);
michael@0 33 }
michael@0 34
michael@0 35 virtual void DeallocateSharedData(ISurfaceAllocator* allocator) MOZ_OVERRIDE
michael@0 36 {
michael@0 37 allocator->DeallocGrallocBuffer(mGrallocActor);
michael@0 38 mGrallocActor = nullptr;
michael@0 39 }
michael@0 40
michael@0 41 private:
michael@0 42 GrallocBufferActor* mGrallocActor;
michael@0 43 };
michael@0 44
michael@0 45 TextureClientData*
michael@0 46 GrallocTextureClientOGL::DropTextureData()
michael@0 47 {
michael@0 48 TextureClientData* result = new GrallocTextureClientData(mGrallocActor);
michael@0 49 mGrallocActor = nullptr;
michael@0 50 mGraphicBuffer = nullptr;
michael@0 51 return result;
michael@0 52 }
michael@0 53
michael@0 54 GrallocTextureClientOGL::GrallocTextureClientOGL(GrallocBufferActor* aActor,
michael@0 55 gfx::IntSize aSize,
michael@0 56 gfx::BackendType aMoz2dBackend,
michael@0 57 TextureFlags aFlags)
michael@0 58 : BufferTextureClient(nullptr, gfx::SurfaceFormat::UNKNOWN, aMoz2dBackend, aFlags)
michael@0 59 , mMappedBuffer(nullptr)
michael@0 60 , mMediaBuffer(nullptr)
michael@0 61 {
michael@0 62 InitWith(aActor, aSize);
michael@0 63 MOZ_COUNT_CTOR(GrallocTextureClientOGL);
michael@0 64 }
michael@0 65
michael@0 66 GrallocTextureClientOGL::GrallocTextureClientOGL(ISurfaceAllocator* aAllocator,
michael@0 67 gfx::SurfaceFormat aFormat,
michael@0 68 gfx::BackendType aMoz2dBackend,
michael@0 69 TextureFlags aFlags)
michael@0 70 : BufferTextureClient(aAllocator, aFormat, aMoz2dBackend, aFlags)
michael@0 71 , mMappedBuffer(nullptr)
michael@0 72 , mMediaBuffer(nullptr)
michael@0 73 {
michael@0 74 MOZ_COUNT_CTOR(GrallocTextureClientOGL);
michael@0 75 }
michael@0 76
michael@0 77 GrallocTextureClientOGL::~GrallocTextureClientOGL()
michael@0 78 {
michael@0 79 MOZ_COUNT_DTOR(GrallocTextureClientOGL);
michael@0 80 if (ShouldDeallocateInDestructor()) {
michael@0 81 ISurfaceAllocator* allocator = GetAllocator();
michael@0 82 allocator->DeallocGrallocBuffer(mGrallocActor);
michael@0 83 }
michael@0 84 }
michael@0 85
michael@0 86 void
michael@0 87 GrallocTextureClientOGL::InitWith(GrallocBufferActor* aActor, gfx::IntSize aSize)
michael@0 88 {
michael@0 89 MOZ_ASSERT(aActor);
michael@0 90 MOZ_ASSERT(!IsAllocated());
michael@0 91 MOZ_ASSERT(IsValid());
michael@0 92 mGrallocActor = aActor;
michael@0 93 mGraphicBuffer = aActor->GetGraphicBuffer();
michael@0 94 mSize = aSize;
michael@0 95 }
michael@0 96
michael@0 97 bool
michael@0 98 GrallocTextureClientOGL::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
michael@0 99 {
michael@0 100 MOZ_ASSERT(IsValid());
michael@0 101 if (!IsAllocated()) {
michael@0 102 return false;
michael@0 103 }
michael@0 104
michael@0 105 aOutDescriptor = NewSurfaceDescriptorGralloc(nullptr, mGrallocActor, mSize);
michael@0 106 return true;
michael@0 107 }
michael@0 108
michael@0 109 void
michael@0 110 GrallocTextureClientOGL::SetReleaseFenceHandle(FenceHandle aReleaseFenceHandle)
michael@0 111 {
michael@0 112 mReleaseFenceHandle = aReleaseFenceHandle;
michael@0 113 }
michael@0 114
michael@0 115 void
michael@0 116 GrallocTextureClientOGL::WaitReleaseFence()
michael@0 117 {
michael@0 118 #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
michael@0 119 if (mReleaseFenceHandle.IsValid()) {
michael@0 120 android::sp<Fence> fence = mReleaseFenceHandle.mFence;
michael@0 121 #if ANDROID_VERSION == 17
michael@0 122 fence->waitForever(1000, "GrallocTextureClientOGL::Lock");
michael@0 123 // 1000 is what Android uses. It is warning timeout ms.
michael@0 124 // This timeous is removed since ANDROID_VERSION 18.
michael@0 125 #else
michael@0 126 fence->waitForever("GrallocTextureClientOGL::Lock");
michael@0 127 #endif
michael@0 128 mReleaseFenceHandle = FenceHandle();
michael@0 129 }
michael@0 130 #endif
michael@0 131 }
michael@0 132
michael@0 133 bool
michael@0 134 GrallocTextureClientOGL::Lock(OpenMode aMode)
michael@0 135 {
michael@0 136 MOZ_ASSERT(IsValid());
michael@0 137 if (!IsValid() || !IsAllocated()) {
michael@0 138 return false;
michael@0 139 }
michael@0 140
michael@0 141 if (mMappedBuffer) {
michael@0 142 return true;
michael@0 143 }
michael@0 144
michael@0 145 WaitReleaseFence();
michael@0 146
michael@0 147 uint32_t usage = 0;
michael@0 148 if (aMode & OPEN_READ) {
michael@0 149 usage |= GRALLOC_USAGE_SW_READ_OFTEN;
michael@0 150 }
michael@0 151 if (aMode & OPEN_WRITE) {
michael@0 152 usage |= GRALLOC_USAGE_SW_WRITE_OFTEN;
michael@0 153 }
michael@0 154 int32_t rv = mGraphicBuffer->lock(usage, reinterpret_cast<void**>(&mMappedBuffer));
michael@0 155 if (rv) {
michael@0 156 mMappedBuffer = nullptr;
michael@0 157 NS_WARNING("Couldn't lock graphic buffer");
michael@0 158 return false;
michael@0 159 }
michael@0 160 return BufferTextureClient::Lock(aMode);
michael@0 161 }
michael@0 162
michael@0 163 void
michael@0 164 GrallocTextureClientOGL::Unlock()
michael@0 165 {
michael@0 166 BufferTextureClient::Unlock();
michael@0 167 mDrawTarget = nullptr;
michael@0 168 if (mMappedBuffer) {
michael@0 169 mMappedBuffer = nullptr;
michael@0 170 mGraphicBuffer->unlock();
michael@0 171 }
michael@0 172 }
michael@0 173
michael@0 174 uint8_t*
michael@0 175 GrallocTextureClientOGL::GetBuffer() const
michael@0 176 {
michael@0 177 MOZ_ASSERT(IsValid());
michael@0 178 NS_WARN_IF_FALSE(mMappedBuffer, "Trying to get a gralloc buffer without getting the lock?");
michael@0 179 return mMappedBuffer;
michael@0 180 }
michael@0 181
michael@0 182 static gfx::SurfaceFormat
michael@0 183 SurfaceFormatForPixelFormat(android::PixelFormat aFormat)
michael@0 184 {
michael@0 185 switch (aFormat) {
michael@0 186 case PIXEL_FORMAT_RGBA_8888:
michael@0 187 return gfx::SurfaceFormat::R8G8B8A8;
michael@0 188 case PIXEL_FORMAT_BGRA_8888:
michael@0 189 return gfx::SurfaceFormat::B8G8R8A8;
michael@0 190 case PIXEL_FORMAT_RGBX_8888:
michael@0 191 return gfx::SurfaceFormat::R8G8B8X8;
michael@0 192 case PIXEL_FORMAT_RGB_565:
michael@0 193 return gfx::SurfaceFormat::R5G6B5;
michael@0 194 default:
michael@0 195 MOZ_CRASH("Unknown gralloc pixel format");
michael@0 196 }
michael@0 197 return gfx::SurfaceFormat::R8G8B8A8;
michael@0 198 }
michael@0 199
michael@0 200 TemporaryRef<gfx::DrawTarget>
michael@0 201 GrallocTextureClientOGL::GetAsDrawTarget()
michael@0 202 {
michael@0 203 MOZ_ASSERT(IsValid());
michael@0 204 MOZ_ASSERT(mMappedBuffer, "Calling TextureClient::GetAsDrawTarget without locking :(");
michael@0 205
michael@0 206 if (mDrawTarget) {
michael@0 207 return mDrawTarget;
michael@0 208 }
michael@0 209
michael@0 210 gfx::SurfaceFormat format = SurfaceFormatForPixelFormat(mGraphicBuffer->getPixelFormat());
michael@0 211 long pixelStride = mGraphicBuffer->getStride();
michael@0 212 long byteStride = pixelStride * BytesPerPixel(format);
michael@0 213 mDrawTarget = gfxPlatform::GetPlatform()->CreateDrawTargetForData(GetBuffer(),
michael@0 214 mSize,
michael@0 215 byteStride,
michael@0 216 mFormat);
michael@0 217 return mDrawTarget;
michael@0 218 }
michael@0 219
michael@0 220 bool
michael@0 221 GrallocTextureClientOGL::AllocateForSurface(gfx::IntSize aSize,
michael@0 222 TextureAllocationFlags)
michael@0 223 {
michael@0 224 MOZ_ASSERT(IsValid());
michael@0 225
michael@0 226 uint32_t format;
michael@0 227 uint32_t usage = android::GraphicBuffer::USAGE_SW_READ_OFTEN |
michael@0 228 android::GraphicBuffer::USAGE_SW_WRITE_OFTEN |
michael@0 229 android::GraphicBuffer::USAGE_HW_TEXTURE;
michael@0 230
michael@0 231 switch (mFormat) {
michael@0 232 case gfx::SurfaceFormat::R8G8B8A8:
michael@0 233 format = android::PIXEL_FORMAT_RGBA_8888;
michael@0 234 break;
michael@0 235 case gfx::SurfaceFormat::B8G8R8A8:
michael@0 236 format = android::PIXEL_FORMAT_RGBA_8888;
michael@0 237 mFlags |= TEXTURE_RB_SWAPPED;
michael@0 238 break;
michael@0 239 case gfx::SurfaceFormat::R8G8B8X8:
michael@0 240 format = android::PIXEL_FORMAT_RGBX_8888;
michael@0 241 break;
michael@0 242 case gfx::SurfaceFormat::B8G8R8X8:
michael@0 243 format = android::PIXEL_FORMAT_RGBX_8888;
michael@0 244 mFlags |= TEXTURE_RB_SWAPPED;
michael@0 245 break;
michael@0 246 case gfx::SurfaceFormat::R5G6B5:
michael@0 247 format = android::PIXEL_FORMAT_RGB_565;
michael@0 248 break;
michael@0 249 case gfx::SurfaceFormat::A8:
michael@0 250 NS_WARNING("gralloc does not support gfx::SurfaceFormat::A8");
michael@0 251 return false;
michael@0 252 default:
michael@0 253 NS_WARNING("Unsupported surface format");
michael@0 254 return false;
michael@0 255 }
michael@0 256
michael@0 257 return AllocateGralloc(aSize, format, usage);
michael@0 258 }
michael@0 259
michael@0 260 bool
michael@0 261 GrallocTextureClientOGL::AllocateForYCbCr(gfx::IntSize aYSize, gfx::IntSize aCbCrSize, StereoMode aStereoMode)
michael@0 262 {
michael@0 263 MOZ_ASSERT(IsValid());
michael@0 264 return AllocateGralloc(aYSize,
michael@0 265 HAL_PIXEL_FORMAT_YV12,
michael@0 266 android::GraphicBuffer::USAGE_SW_READ_OFTEN);
michael@0 267 }
michael@0 268
michael@0 269 bool
michael@0 270 GrallocTextureClientOGL::AllocateForGLRendering(gfx::IntSize aSize)
michael@0 271 {
michael@0 272 MOZ_ASSERT(IsValid());
michael@0 273
michael@0 274 uint32_t format;
michael@0 275 uint32_t usage = android::GraphicBuffer::USAGE_HW_RENDER |
michael@0 276 android::GraphicBuffer::USAGE_HW_TEXTURE;
michael@0 277
michael@0 278 switch (mFormat) {
michael@0 279 case gfx::SurfaceFormat::R8G8B8A8:
michael@0 280 case gfx::SurfaceFormat::B8G8R8A8:
michael@0 281 format = android::PIXEL_FORMAT_RGBA_8888;
michael@0 282 break;
michael@0 283 case gfx::SurfaceFormat::R8G8B8X8:
michael@0 284 case gfx::SurfaceFormat::B8G8R8X8:
michael@0 285 // there is no android BGRX format?
michael@0 286 format = android::PIXEL_FORMAT_RGBX_8888;
michael@0 287 break;
michael@0 288 case gfx::SurfaceFormat::R5G6B5:
michael@0 289 format = android::PIXEL_FORMAT_RGB_565;
michael@0 290 break;
michael@0 291 default:
michael@0 292 NS_WARNING("Unsupported surface format");
michael@0 293 return false;
michael@0 294 }
michael@0 295
michael@0 296 return AllocateGralloc(aSize, format, usage);
michael@0 297 }
michael@0 298
michael@0 299 bool
michael@0 300 GrallocTextureClientOGL::AllocateGralloc(gfx::IntSize aSize,
michael@0 301 uint32_t aAndroidFormat,
michael@0 302 uint32_t aUsage)
michael@0 303 {
michael@0 304 MOZ_ASSERT(IsValid());
michael@0 305 ISurfaceAllocator* allocator = GetAllocator();
michael@0 306
michael@0 307 MaybeMagicGrallocBufferHandle handle;
michael@0 308 PGrallocBufferChild* actor =
michael@0 309 allocator->AllocGrallocBuffer(aSize,
michael@0 310 aAndroidFormat,
michael@0 311 aUsage,
michael@0 312 &handle);
michael@0 313 if (!actor) {
michael@0 314 return false;
michael@0 315 }
michael@0 316 GrallocBufferActor* gba = static_cast<GrallocBufferActor*>(actor);
michael@0 317 gba->InitFromHandle(handle.get_MagicGrallocBufferHandle());
michael@0 318
michael@0 319 sp<GraphicBuffer> graphicBuffer = gba->GetGraphicBuffer();
michael@0 320 if (!graphicBuffer.get()) {
michael@0 321 return false;
michael@0 322 }
michael@0 323
michael@0 324 if (graphicBuffer->initCheck() != NO_ERROR) {
michael@0 325 return false;
michael@0 326 }
michael@0 327
michael@0 328 mGrallocActor = gba;
michael@0 329 mGraphicBuffer = graphicBuffer;
michael@0 330 mSize = aSize;
michael@0 331 return true;
michael@0 332 }
michael@0 333
michael@0 334 bool
michael@0 335 GrallocTextureClientOGL::IsAllocated() const
michael@0 336 {
michael@0 337 return !!mGraphicBuffer.get();
michael@0 338 }
michael@0 339
michael@0 340 bool
michael@0 341 GrallocTextureClientOGL::Allocate(uint32_t aSize)
michael@0 342 {
michael@0 343 // see Bug 908196
michael@0 344 MOZ_CRASH("This method should never be called.");
michael@0 345 return false;
michael@0 346 }
michael@0 347
michael@0 348 size_t
michael@0 349 GrallocTextureClientOGL::GetBufferSize() const
michael@0 350 {
michael@0 351 // see Bug 908196
michael@0 352 MOZ_CRASH("This method should never be called.");
michael@0 353 return 0;
michael@0 354 }
michael@0 355
michael@0 356 } // namesapace layers
michael@0 357 } // namesapace mozilla
michael@0 358
michael@0 359 #endif // MOZ_WIDGET_GONK

mercurial