gfx/layers/composite/TextureHost.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

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 #include "mozilla/layers/TextureHost.h"
michael@0 7 #include "CompositableHost.h" // for CompositableHost
michael@0 8 #include "LayersLogging.h" // for AppendToString
michael@0 9 #include "gfx2DGlue.h" // for ToIntSize
michael@0 10 #include "mozilla/gfx/2D.h" // for DataSourceSurface, Factory
michael@0 11 #include "mozilla/ipc/Shmem.h" // for Shmem
michael@0 12 #include "mozilla/layers/Compositor.h" // for Compositor
michael@0 13 #include "mozilla/layers/ISurfaceAllocator.h" // for ISurfaceAllocator
michael@0 14 #include "mozilla/layers/ImageDataSerializer.h"
michael@0 15 #include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor, etc
michael@0 16 #include "mozilla/layers/TextureHostOGL.h" // for TextureHostOGL
michael@0 17 #ifdef MOZ_X11
michael@0 18 #include "mozilla/layers/X11TextureHost.h"
michael@0 19 #endif
michael@0 20 #include "mozilla/layers/YCbCrImageDataSerializer.h"
michael@0 21 #include "nsAString.h"
michael@0 22 #include "nsAutoPtr.h" // for nsRefPtr
michael@0 23 #include "nsPrintfCString.h" // for nsPrintfCString
michael@0 24 #include "mozilla/layers/PTextureParent.h"
michael@0 25 #include "mozilla/unused.h"
michael@0 26 #include <limits>
michael@0 27
michael@0 28 #if 0
michael@0 29 #define RECYCLE_LOG(...) printf_stderr(__VA_ARGS__)
michael@0 30 #else
michael@0 31 #define RECYCLE_LOG(...) do { } while (0)
michael@0 32 #endif
michael@0 33
michael@0 34 struct nsIntPoint;
michael@0 35
michael@0 36 namespace mozilla {
michael@0 37 namespace layers {
michael@0 38
michael@0 39 /**
michael@0 40 * TextureParent is the host-side IPDL glue between TextureClient and TextureHost.
michael@0 41 * It is an IPDL actor just like LayerParent, CompositableParent, etc.
michael@0 42 */
michael@0 43 class TextureParent : public PTextureParent
michael@0 44 {
michael@0 45 public:
michael@0 46 TextureParent(ISurfaceAllocator* aAllocator);
michael@0 47
michael@0 48 ~TextureParent();
michael@0 49
michael@0 50 bool Init(const SurfaceDescriptor& aSharedData,
michael@0 51 const TextureFlags& aFlags);
michael@0 52
michael@0 53 void CompositorRecycle();
michael@0 54 virtual bool RecvClientRecycle() MOZ_OVERRIDE;
michael@0 55
michael@0 56 virtual bool RecvRemoveTexture() MOZ_OVERRIDE;
michael@0 57
michael@0 58 virtual bool RecvRemoveTextureSync() MOZ_OVERRIDE;
michael@0 59
michael@0 60 TextureHost* GetTextureHost() { return mTextureHost; }
michael@0 61
michael@0 62 void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
michael@0 63
michael@0 64 ISurfaceAllocator* mAllocator;
michael@0 65 RefPtr<TextureHost> mWaitForClientRecycle;
michael@0 66 RefPtr<TextureHost> mTextureHost;
michael@0 67 };
michael@0 68
michael@0 69 // static
michael@0 70 PTextureParent*
michael@0 71 TextureHost::CreateIPDLActor(ISurfaceAllocator* aAllocator,
michael@0 72 const SurfaceDescriptor& aSharedData,
michael@0 73 TextureFlags aFlags)
michael@0 74 {
michael@0 75 if (aSharedData.type() == SurfaceDescriptor::TSurfaceDescriptorMemory &&
michael@0 76 !aAllocator->IsSameProcess())
michael@0 77 {
michael@0 78 NS_ERROR("A client process is trying to peek at our address space using a MemoryTexture!");
michael@0 79 return nullptr;
michael@0 80 }
michael@0 81 TextureParent* actor = new TextureParent(aAllocator);
michael@0 82 if (!actor->Init(aSharedData, aFlags)) {
michael@0 83 delete actor;
michael@0 84 return nullptr;
michael@0 85 }
michael@0 86 return actor;
michael@0 87 }
michael@0 88
michael@0 89 // static
michael@0 90 bool
michael@0 91 TextureHost::DestroyIPDLActor(PTextureParent* actor)
michael@0 92 {
michael@0 93 delete actor;
michael@0 94 return true;
michael@0 95 }
michael@0 96
michael@0 97 // static
michael@0 98 bool
michael@0 99 TextureHost::SendDeleteIPDLActor(PTextureParent* actor)
michael@0 100 {
michael@0 101 return PTextureParent::Send__delete__(actor);
michael@0 102 }
michael@0 103
michael@0 104 // static
michael@0 105 TextureHost*
michael@0 106 TextureHost::AsTextureHost(PTextureParent* actor)
michael@0 107 {
michael@0 108 return actor? static_cast<TextureParent*>(actor)->mTextureHost : nullptr;
michael@0 109 }
michael@0 110
michael@0 111 PTextureParent*
michael@0 112 TextureHost::GetIPDLActor()
michael@0 113 {
michael@0 114 return mActor;
michael@0 115 }
michael@0 116
michael@0 117 // implemented in TextureHostOGL.cpp
michael@0 118 TemporaryRef<TextureHost> CreateTextureHostOGL(const SurfaceDescriptor& aDesc,
michael@0 119 ISurfaceAllocator* aDeallocator,
michael@0 120 TextureFlags aFlags);
michael@0 121
michael@0 122 // implemented in TextureHostBasic.cpp
michael@0 123 TemporaryRef<TextureHost> CreateTextureHostBasic(const SurfaceDescriptor& aDesc,
michael@0 124 ISurfaceAllocator* aDeallocator,
michael@0 125 TextureFlags aFlags);
michael@0 126
michael@0 127 // implemented in TextureD3D11.cpp
michael@0 128 TemporaryRef<TextureHost> CreateTextureHostD3D11(const SurfaceDescriptor& aDesc,
michael@0 129 ISurfaceAllocator* aDeallocator,
michael@0 130 TextureFlags aFlags);
michael@0 131
michael@0 132 // implemented in TextureD3D9.cpp
michael@0 133 TemporaryRef<TextureHost> CreateTextureHostD3D9(const SurfaceDescriptor& aDesc,
michael@0 134 ISurfaceAllocator* aDeallocator,
michael@0 135 TextureFlags aFlags);
michael@0 136
michael@0 137 // static
michael@0 138 TemporaryRef<TextureHost>
michael@0 139 TextureHost::Create(const SurfaceDescriptor& aDesc,
michael@0 140 ISurfaceAllocator* aDeallocator,
michael@0 141 TextureFlags aFlags)
michael@0 142 {
michael@0 143 switch (aDesc.type()) {
michael@0 144 case SurfaceDescriptor::TSurfaceDescriptorShmem:
michael@0 145 case SurfaceDescriptor::TSurfaceDescriptorMemory:
michael@0 146 return CreateBackendIndependentTextureHost(aDesc, aDeallocator, aFlags);
michael@0 147 case SurfaceDescriptor::TSharedTextureDescriptor:
michael@0 148 case SurfaceDescriptor::TNewSurfaceDescriptorGralloc:
michael@0 149 case SurfaceDescriptor::TSurfaceStreamDescriptor:
michael@0 150 return CreateTextureHostOGL(aDesc, aDeallocator, aFlags);
michael@0 151 case SurfaceDescriptor::TSurfaceDescriptorMacIOSurface:
michael@0 152 if (Compositor::GetBackend() == LayersBackend::LAYERS_OPENGL) {
michael@0 153 return CreateTextureHostOGL(aDesc, aDeallocator, aFlags);
michael@0 154 } else {
michael@0 155 return CreateTextureHostBasic(aDesc, aDeallocator, aFlags);
michael@0 156 }
michael@0 157 #ifdef MOZ_X11
michael@0 158 case SurfaceDescriptor::TSurfaceDescriptorX11: {
michael@0 159 const SurfaceDescriptorX11& desc = aDesc.get_SurfaceDescriptorX11();
michael@0 160 RefPtr<TextureHost> result = new X11TextureHost(aFlags, desc);
michael@0 161 return result;
michael@0 162 }
michael@0 163 #endif
michael@0 164 #ifdef XP_WIN
michael@0 165 case SurfaceDescriptor::TSurfaceDescriptorD3D9:
michael@0 166 case SurfaceDescriptor::TSurfaceDescriptorDIB:
michael@0 167 return CreateTextureHostD3D9(aDesc, aDeallocator, aFlags);
michael@0 168 case SurfaceDescriptor::TSurfaceDescriptorD3D10:
michael@0 169 if (Compositor::GetBackend() == LayersBackend::LAYERS_D3D9) {
michael@0 170 return CreateTextureHostD3D9(aDesc, aDeallocator, aFlags);
michael@0 171 } else {
michael@0 172 return CreateTextureHostD3D11(aDesc, aDeallocator, aFlags);
michael@0 173 }
michael@0 174 #endif
michael@0 175 default:
michael@0 176 MOZ_CRASH("Unsupported Surface type");
michael@0 177 }
michael@0 178 }
michael@0 179
michael@0 180 TemporaryRef<TextureHost>
michael@0 181 CreateBackendIndependentTextureHost(const SurfaceDescriptor& aDesc,
michael@0 182 ISurfaceAllocator* aDeallocator,
michael@0 183 TextureFlags aFlags)
michael@0 184 {
michael@0 185 RefPtr<TextureHost> result;
michael@0 186 switch (aDesc.type()) {
michael@0 187 case SurfaceDescriptor::TSurfaceDescriptorShmem: {
michael@0 188 const SurfaceDescriptorShmem& descriptor = aDesc.get_SurfaceDescriptorShmem();
michael@0 189 result = new ShmemTextureHost(descriptor.data(),
michael@0 190 descriptor.format(),
michael@0 191 aDeallocator,
michael@0 192 aFlags);
michael@0 193 break;
michael@0 194 }
michael@0 195 case SurfaceDescriptor::TSurfaceDescriptorMemory: {
michael@0 196 const SurfaceDescriptorMemory& descriptor = aDesc.get_SurfaceDescriptorMemory();
michael@0 197 result = new MemoryTextureHost(reinterpret_cast<uint8_t*>(descriptor.data()),
michael@0 198 descriptor.format(),
michael@0 199 aFlags);
michael@0 200 break;
michael@0 201 }
michael@0 202 default: {
michael@0 203 NS_WARNING("No backend independent TextureHost for this descriptor type");
michael@0 204 }
michael@0 205 }
michael@0 206 return result;
michael@0 207 }
michael@0 208
michael@0 209 void
michael@0 210 TextureHost::CompositorRecycle()
michael@0 211 {
michael@0 212 if (!mActor) {
michael@0 213 return;
michael@0 214 }
michael@0 215 static_cast<TextureParent*>(mActor)->CompositorRecycle();
michael@0 216 }
michael@0 217
michael@0 218 void
michael@0 219 TextureHost::SetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData)
michael@0 220 {
michael@0 221 mCompositableBackendData = aBackendData;
michael@0 222 }
michael@0 223
michael@0 224
michael@0 225 TextureHost::TextureHost(TextureFlags aFlags)
michael@0 226 : mActor(nullptr)
michael@0 227 , mFlags(aFlags)
michael@0 228 {}
michael@0 229
michael@0 230 TextureHost::~TextureHost()
michael@0 231 {
michael@0 232 }
michael@0 233
michael@0 234 void TextureHost::Finalize()
michael@0 235 {
michael@0 236 if (!(GetFlags() & TEXTURE_DEALLOCATE_CLIENT)) {
michael@0 237 DeallocateSharedData();
michael@0 238 DeallocateDeviceData();
michael@0 239 }
michael@0 240 }
michael@0 241
michael@0 242 void
michael@0 243 TextureHost::PrintInfo(nsACString& aTo, const char* aPrefix)
michael@0 244 {
michael@0 245 aTo += aPrefix;
michael@0 246 aTo += nsPrintfCString("%s (0x%p)", Name(), this);
michael@0 247 // Note: the TextureHost needs to be locked before it is safe to call
michael@0 248 // GetSize() and GetFormat() on it.
michael@0 249 if (Lock()) {
michael@0 250 AppendToString(aTo, GetSize(), " [size=", "]");
michael@0 251 AppendToString(aTo, GetFormat(), " [format=", "]");
michael@0 252 Unlock();
michael@0 253 }
michael@0 254 AppendToString(aTo, mFlags, " [flags=", "]");
michael@0 255 }
michael@0 256
michael@0 257 void
michael@0 258 TextureSource::SetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData)
michael@0 259 {
michael@0 260 mCompositableBackendData = aBackendData;
michael@0 261 }
michael@0 262
michael@0 263 TextureSource::TextureSource()
michael@0 264 {
michael@0 265 MOZ_COUNT_CTOR(TextureSource);
michael@0 266 }
michael@0 267 TextureSource::~TextureSource()
michael@0 268 {
michael@0 269 MOZ_COUNT_DTOR(TextureSource);
michael@0 270 }
michael@0 271
michael@0 272 BufferTextureHost::BufferTextureHost(gfx::SurfaceFormat aFormat,
michael@0 273 TextureFlags aFlags)
michael@0 274 : TextureHost(aFlags)
michael@0 275 , mCompositor(nullptr)
michael@0 276 , mFormat(aFormat)
michael@0 277 , mUpdateSerial(1)
michael@0 278 , mLocked(false)
michael@0 279 , mPartialUpdate(false)
michael@0 280 {}
michael@0 281
michael@0 282 BufferTextureHost::~BufferTextureHost()
michael@0 283 {}
michael@0 284
michael@0 285 void
michael@0 286 BufferTextureHost::Updated(const nsIntRegion* aRegion)
michael@0 287 {
michael@0 288 ++mUpdateSerial;
michael@0 289 if (aRegion) {
michael@0 290 mPartialUpdate = true;
michael@0 291 mMaybeUpdatedRegion = *aRegion;
michael@0 292 } else {
michael@0 293 mPartialUpdate = false;
michael@0 294 }
michael@0 295 if (GetFlags() & TEXTURE_IMMEDIATE_UPLOAD) {
michael@0 296 DebugOnly<bool> result = MaybeUpload(mPartialUpdate ? &mMaybeUpdatedRegion : nullptr);
michael@0 297 NS_WARN_IF_FALSE(result, "Failed to upload a texture");
michael@0 298 }
michael@0 299 }
michael@0 300
michael@0 301 void
michael@0 302 BufferTextureHost::SetCompositor(Compositor* aCompositor)
michael@0 303 {
michael@0 304 if (mCompositor == aCompositor) {
michael@0 305 return;
michael@0 306 }
michael@0 307 RefPtr<NewTextureSource> it = mFirstSource;
michael@0 308 while (it) {
michael@0 309 it->SetCompositor(aCompositor);
michael@0 310 it = it->GetNextSibling();
michael@0 311 }
michael@0 312 mCompositor = aCompositor;
michael@0 313 }
michael@0 314
michael@0 315 void
michael@0 316 BufferTextureHost::DeallocateDeviceData()
michael@0 317 {
michael@0 318 RefPtr<NewTextureSource> it = mFirstSource;
michael@0 319 while (it) {
michael@0 320 it->DeallocateDeviceData();
michael@0 321 it = it->GetNextSibling();
michael@0 322 }
michael@0 323 }
michael@0 324
michael@0 325 bool
michael@0 326 BufferTextureHost::Lock()
michael@0 327 {
michael@0 328 mLocked = true;
michael@0 329 return true;
michael@0 330 }
michael@0 331
michael@0 332 void
michael@0 333 BufferTextureHost::Unlock()
michael@0 334 {
michael@0 335 mLocked = false;
michael@0 336 }
michael@0 337
michael@0 338 NewTextureSource*
michael@0 339 BufferTextureHost::GetTextureSources()
michael@0 340 {
michael@0 341 MOZ_ASSERT(mLocked, "should never be called while not locked");
michael@0 342 if (!MaybeUpload(mPartialUpdate ? &mMaybeUpdatedRegion : nullptr)) {
michael@0 343 return nullptr;
michael@0 344 }
michael@0 345 return mFirstSource;
michael@0 346 }
michael@0 347
michael@0 348 gfx::SurfaceFormat
michael@0 349 BufferTextureHost::GetFormat() const
michael@0 350 {
michael@0 351 // mFormat is the format of the data that we share with the content process.
michael@0 352 // GetFormat, on the other hand, expects the format that we present to the
michael@0 353 // Compositor (it is used to choose the effect type).
michael@0 354 // if the compositor does not support YCbCr effects, we give it a RGBX texture
michael@0 355 // instead (see BufferTextureHost::Upload)
michael@0 356 if (mFormat == gfx::SurfaceFormat::YUV &&
michael@0 357 mCompositor &&
michael@0 358 !mCompositor->SupportsEffect(EFFECT_YCBCR)) {
michael@0 359 return gfx::SurfaceFormat::R8G8B8X8;
michael@0 360 }
michael@0 361 return mFormat;
michael@0 362 }
michael@0 363
michael@0 364 bool
michael@0 365 BufferTextureHost::MaybeUpload(nsIntRegion *aRegion)
michael@0 366 {
michael@0 367 if (mFirstSource && mFirstSource->GetUpdateSerial() == mUpdateSerial) {
michael@0 368 return true;
michael@0 369 }
michael@0 370 if (!Upload(aRegion)) {
michael@0 371 return false;
michael@0 372 }
michael@0 373 mFirstSource->SetUpdateSerial(mUpdateSerial);
michael@0 374 return true;
michael@0 375 }
michael@0 376
michael@0 377 bool
michael@0 378 BufferTextureHost::Upload(nsIntRegion *aRegion)
michael@0 379 {
michael@0 380 if (!GetBuffer()) {
michael@0 381 // We don't have a buffer; a possible cause is that the IPDL actor
michael@0 382 // is already dead. This inevitably happens as IPDL actors can die
michael@0 383 // at any time, so we want to silently return in this case.
michael@0 384 return false;
michael@0 385 }
michael@0 386 if (!mCompositor) {
michael@0 387 NS_WARNING("Tried to upload without a compositor. Skipping texture upload...");
michael@0 388 // If we are in this situation it means we should have called SetCompositor
michael@0 389 // earlier. It is conceivable that on certain rare conditions with async-video
michael@0 390 // we may end up here for the first frame, but this should not happen repeatedly.
michael@0 391 return false;
michael@0 392 }
michael@0 393 if (mFormat == gfx::SurfaceFormat::UNKNOWN) {
michael@0 394 NS_WARNING("BufferTextureHost: unsupported format!");
michael@0 395 return false;
michael@0 396 } else if (mFormat == gfx::SurfaceFormat::YUV) {
michael@0 397 YCbCrImageDataDeserializer yuvDeserializer(GetBuffer(), GetBufferSize());
michael@0 398 MOZ_ASSERT(yuvDeserializer.IsValid());
michael@0 399
michael@0 400 if (!mCompositor->SupportsEffect(EFFECT_YCBCR)) {
michael@0 401 RefPtr<gfx::DataSourceSurface> surf = yuvDeserializer.ToDataSourceSurface();
michael@0 402 if (!mFirstSource) {
michael@0 403 mFirstSource = mCompositor->CreateDataTextureSource(mFlags);
michael@0 404 }
michael@0 405 mFirstSource->Update(surf, aRegion);
michael@0 406 return true;
michael@0 407 }
michael@0 408
michael@0 409 RefPtr<DataTextureSource> srcY;
michael@0 410 RefPtr<DataTextureSource> srcU;
michael@0 411 RefPtr<DataTextureSource> srcV;
michael@0 412 if (!mFirstSource) {
michael@0 413 // We don't support BigImages for YCbCr compositing.
michael@0 414 srcY = mCompositor->CreateDataTextureSource(mFlags|TEXTURE_DISALLOW_BIGIMAGE);
michael@0 415 srcU = mCompositor->CreateDataTextureSource(mFlags|TEXTURE_DISALLOW_BIGIMAGE);
michael@0 416 srcV = mCompositor->CreateDataTextureSource(mFlags|TEXTURE_DISALLOW_BIGIMAGE);
michael@0 417 mFirstSource = srcY;
michael@0 418 srcY->SetNextSibling(srcU);
michael@0 419 srcU->SetNextSibling(srcV);
michael@0 420 } else {
michael@0 421 // mFormat never changes so if this was created as a YCbCr host and already
michael@0 422 // contains a source it should already have 3 sources.
michael@0 423 // BufferTextureHost only uses DataTextureSources so it is safe to assume
michael@0 424 // all 3 sources are DataTextureSource.
michael@0 425 MOZ_ASSERT(mFirstSource->GetNextSibling());
michael@0 426 MOZ_ASSERT(mFirstSource->GetNextSibling()->GetNextSibling());
michael@0 427 srcY = mFirstSource;
michael@0 428 srcU = mFirstSource->GetNextSibling()->AsDataTextureSource();
michael@0 429 srcV = mFirstSource->GetNextSibling()->GetNextSibling()->AsDataTextureSource();
michael@0 430 }
michael@0 431
michael@0 432
michael@0 433 RefPtr<gfx::DataSourceSurface> tempY =
michael@0 434 gfx::Factory::CreateWrappingDataSourceSurface(yuvDeserializer.GetYData(),
michael@0 435 yuvDeserializer.GetYStride(),
michael@0 436 yuvDeserializer.GetYSize(),
michael@0 437 gfx::SurfaceFormat::A8);
michael@0 438 RefPtr<gfx::DataSourceSurface> tempCb =
michael@0 439 gfx::Factory::CreateWrappingDataSourceSurface(yuvDeserializer.GetCbData(),
michael@0 440 yuvDeserializer.GetCbCrStride(),
michael@0 441 yuvDeserializer.GetCbCrSize(),
michael@0 442 gfx::SurfaceFormat::A8);
michael@0 443 RefPtr<gfx::DataSourceSurface> tempCr =
michael@0 444 gfx::Factory::CreateWrappingDataSourceSurface(yuvDeserializer.GetCrData(),
michael@0 445 yuvDeserializer.GetCbCrStride(),
michael@0 446 yuvDeserializer.GetCbCrSize(),
michael@0 447 gfx::SurfaceFormat::A8);
michael@0 448 // We don't support partial updates for Y U V textures
michael@0 449 NS_ASSERTION(!aRegion, "Unsupported partial updates for YCbCr textures");
michael@0 450 if (!srcY->Update(tempY) ||
michael@0 451 !srcU->Update(tempCb) ||
michael@0 452 !srcV->Update(tempCr)) {
michael@0 453 NS_WARNING("failed to update the DataTextureSource");
michael@0 454 return false;
michael@0 455 }
michael@0 456 } else {
michael@0 457 // non-YCbCr case
michael@0 458 if (!mFirstSource) {
michael@0 459 mFirstSource = mCompositor->CreateDataTextureSource();
michael@0 460 }
michael@0 461 ImageDataDeserializer deserializer(GetBuffer(), GetBufferSize());
michael@0 462 if (!deserializer.IsValid()) {
michael@0 463 NS_ERROR("Failed to deserialize image!");
michael@0 464 return false;
michael@0 465 }
michael@0 466
michael@0 467 RefPtr<gfx::DataSourceSurface> surf = deserializer.GetAsSurface();
michael@0 468 if (!surf) {
michael@0 469 return false;
michael@0 470 }
michael@0 471
michael@0 472 if (!mFirstSource->Update(surf.get(), aRegion)) {
michael@0 473 NS_WARNING("failed to update the DataTextureSource");
michael@0 474 return false;
michael@0 475 }
michael@0 476 }
michael@0 477 return true;
michael@0 478 }
michael@0 479
michael@0 480 TemporaryRef<gfx::DataSourceSurface>
michael@0 481 BufferTextureHost::GetAsSurface()
michael@0 482 {
michael@0 483 RefPtr<gfx::DataSourceSurface> result;
michael@0 484 if (mFormat == gfx::SurfaceFormat::UNKNOWN) {
michael@0 485 NS_WARNING("BufferTextureHost: unsupported format!");
michael@0 486 return nullptr;
michael@0 487 } else if (mFormat == gfx::SurfaceFormat::YUV) {
michael@0 488 YCbCrImageDataDeserializer yuvDeserializer(GetBuffer(), GetBufferSize());
michael@0 489 if (!yuvDeserializer.IsValid()) {
michael@0 490 return nullptr;
michael@0 491 }
michael@0 492 result = yuvDeserializer.ToDataSourceSurface();
michael@0 493 } else {
michael@0 494 ImageDataDeserializer deserializer(GetBuffer(), GetBufferSize());
michael@0 495 if (!deserializer.IsValid()) {
michael@0 496 NS_ERROR("Failed to deserialize image!");
michael@0 497 return nullptr;
michael@0 498 }
michael@0 499 result = deserializer.GetAsSurface();
michael@0 500 }
michael@0 501 return result.forget();
michael@0 502 }
michael@0 503
michael@0 504 ShmemTextureHost::ShmemTextureHost(const ipc::Shmem& aShmem,
michael@0 505 gfx::SurfaceFormat aFormat,
michael@0 506 ISurfaceAllocator* aDeallocator,
michael@0 507 TextureFlags aFlags)
michael@0 508 : BufferTextureHost(aFormat, aFlags)
michael@0 509 , mShmem(new ipc::Shmem(aShmem))
michael@0 510 , mDeallocator(aDeallocator)
michael@0 511 {
michael@0 512 MOZ_COUNT_CTOR(ShmemTextureHost);
michael@0 513 }
michael@0 514
michael@0 515 ShmemTextureHost::~ShmemTextureHost()
michael@0 516 {
michael@0 517 DeallocateDeviceData();
michael@0 518 delete mShmem;
michael@0 519 MOZ_COUNT_DTOR(ShmemTextureHost);
michael@0 520 }
michael@0 521
michael@0 522 void
michael@0 523 ShmemTextureHost::DeallocateSharedData()
michael@0 524 {
michael@0 525 if (mShmem) {
michael@0 526 MOZ_ASSERT(mDeallocator,
michael@0 527 "Shared memory would leak without a ISurfaceAllocator");
michael@0 528 mDeallocator->DeallocShmem(*mShmem);
michael@0 529 delete mShmem;
michael@0 530 mShmem = nullptr;
michael@0 531 }
michael@0 532 }
michael@0 533
michael@0 534 void
michael@0 535 ShmemTextureHost::ForgetSharedData()
michael@0 536 {
michael@0 537 if (mShmem) {
michael@0 538 delete mShmem;
michael@0 539 mShmem = nullptr;
michael@0 540 }
michael@0 541 }
michael@0 542
michael@0 543 void
michael@0 544 ShmemTextureHost::OnShutdown()
michael@0 545 {
michael@0 546 delete mShmem;
michael@0 547 mShmem = nullptr;
michael@0 548 }
michael@0 549
michael@0 550 uint8_t* ShmemTextureHost::GetBuffer()
michael@0 551 {
michael@0 552 return mShmem ? mShmem->get<uint8_t>() : nullptr;
michael@0 553 }
michael@0 554
michael@0 555 size_t ShmemTextureHost::GetBufferSize()
michael@0 556 {
michael@0 557 return mShmem ? mShmem->Size<uint8_t>() : 0;
michael@0 558 }
michael@0 559
michael@0 560 MemoryTextureHost::MemoryTextureHost(uint8_t* aBuffer,
michael@0 561 gfx::SurfaceFormat aFormat,
michael@0 562 TextureFlags aFlags)
michael@0 563 : BufferTextureHost(aFormat, aFlags)
michael@0 564 , mBuffer(aBuffer)
michael@0 565 {
michael@0 566 MOZ_COUNT_CTOR(MemoryTextureHost);
michael@0 567 }
michael@0 568
michael@0 569 MemoryTextureHost::~MemoryTextureHost()
michael@0 570 {
michael@0 571 DeallocateDeviceData();
michael@0 572 NS_ASSERTION(!mBuffer || (mFlags & TEXTURE_DEALLOCATE_CLIENT),
michael@0 573 "Leaking our buffer");
michael@0 574 MOZ_COUNT_DTOR(MemoryTextureHost);
michael@0 575 }
michael@0 576
michael@0 577 void
michael@0 578 MemoryTextureHost::DeallocateSharedData()
michael@0 579 {
michael@0 580 if (mBuffer) {
michael@0 581 GfxMemoryImageReporter::WillFree(mBuffer);
michael@0 582 }
michael@0 583 delete[] mBuffer;
michael@0 584 mBuffer = nullptr;
michael@0 585 }
michael@0 586
michael@0 587 void
michael@0 588 MemoryTextureHost::ForgetSharedData()
michael@0 589 {
michael@0 590 mBuffer = nullptr;
michael@0 591 }
michael@0 592
michael@0 593 uint8_t* MemoryTextureHost::GetBuffer()
michael@0 594 {
michael@0 595 return mBuffer;
michael@0 596 }
michael@0 597
michael@0 598 size_t MemoryTextureHost::GetBufferSize()
michael@0 599 {
michael@0 600 // MemoryTextureHost just trusts that the buffer size is large enough to read
michael@0 601 // anything we need to. That's because MemoryTextureHost has to trust the buffer
michael@0 602 // pointer anyway, so the security model here is just that MemoryTexture's
michael@0 603 // are restricted to same-process clients.
michael@0 604 return std::numeric_limits<size_t>::max();
michael@0 605 }
michael@0 606
michael@0 607 TextureParent::TextureParent(ISurfaceAllocator* aAllocator)
michael@0 608 : mAllocator(aAllocator)
michael@0 609 {
michael@0 610 MOZ_COUNT_CTOR(TextureParent);
michael@0 611 }
michael@0 612
michael@0 613 TextureParent::~TextureParent()
michael@0 614 {
michael@0 615 MOZ_COUNT_DTOR(TextureParent);
michael@0 616 if (mTextureHost) {
michael@0 617 mTextureHost->ClearRecycleCallback();
michael@0 618 }
michael@0 619 }
michael@0 620
michael@0 621 static void RecycleCallback(TextureHost* textureHost, void* aClosure) {
michael@0 622 TextureParent* tp = reinterpret_cast<TextureParent*>(aClosure);
michael@0 623 tp->CompositorRecycle();
michael@0 624 }
michael@0 625
michael@0 626 void
michael@0 627 TextureParent::CompositorRecycle()
michael@0 628 {
michael@0 629 mTextureHost->ClearRecycleCallback();
michael@0 630
michael@0 631 MaybeFenceHandle handle = null_t();
michael@0 632 #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
michael@0 633 if (mTextureHost) {
michael@0 634 TextureHostOGL* hostOGL = mTextureHost->AsHostOGL();
michael@0 635 android::sp<android::Fence> fence = hostOGL->GetAndResetReleaseFence();
michael@0 636 if (fence.get() && fence->isValid()) {
michael@0 637 handle = FenceHandle(fence);
michael@0 638 // HWC might not provide Fence.
michael@0 639 // In this case, HWC implicitly handles buffer's fence.
michael@0 640 }
michael@0 641 }
michael@0 642 #endif
michael@0 643 mozilla::unused << SendCompositorRecycle(handle);
michael@0 644
michael@0 645 // Don't forget to prepare for the next reycle
michael@0 646 // if TextureClient request it.
michael@0 647 if (mTextureHost->GetFlags() & TEXTURE_RECYCLE) {
michael@0 648 mWaitForClientRecycle = mTextureHost;
michael@0 649 }
michael@0 650 }
michael@0 651
michael@0 652 bool
michael@0 653 TextureParent::RecvClientRecycle()
michael@0 654 {
michael@0 655 // This will allow the RecycleCallback to be called once the compositor
michael@0 656 // releases any external references to TextureHost.
michael@0 657 mTextureHost->SetRecycleCallback(RecycleCallback, this);
michael@0 658 if (!mWaitForClientRecycle) {
michael@0 659 RECYCLE_LOG("Not a recycable tile");
michael@0 660 }
michael@0 661 mWaitForClientRecycle = nullptr;
michael@0 662 return true;
michael@0 663 }
michael@0 664
michael@0 665 bool
michael@0 666 TextureParent::Init(const SurfaceDescriptor& aSharedData,
michael@0 667 const TextureFlags& aFlags)
michael@0 668 {
michael@0 669 mTextureHost = TextureHost::Create(aSharedData,
michael@0 670 mAllocator,
michael@0 671 aFlags);
michael@0 672 if (mTextureHost) {
michael@0 673 mTextureHost->mActor = this;
michael@0 674 if (aFlags & TEXTURE_RECYCLE) {
michael@0 675 mWaitForClientRecycle = mTextureHost;
michael@0 676 RECYCLE_LOG("Setup recycling for tile %p\n", this);
michael@0 677 }
michael@0 678 }
michael@0 679
michael@0 680 return !!mTextureHost;
michael@0 681 }
michael@0 682
michael@0 683 bool
michael@0 684 TextureParent::RecvRemoveTexture()
michael@0 685 {
michael@0 686 return PTextureParent::Send__delete__(this);
michael@0 687 }
michael@0 688
michael@0 689 bool
michael@0 690 TextureParent::RecvRemoveTextureSync()
michael@0 691 {
michael@0 692 // we don't need to send a reply in the synchronous case since the child side
michael@0 693 // has the guarantee that this message has been handled synchronously.
michael@0 694 return PTextureParent::Send__delete__(this);
michael@0 695 }
michael@0 696
michael@0 697 void
michael@0 698 TextureParent::ActorDestroy(ActorDestroyReason why)
michael@0 699 {
michael@0 700 if (!mTextureHost) {
michael@0 701 return;
michael@0 702 }
michael@0 703
michael@0 704 switch (why) {
michael@0 705 case AncestorDeletion:
michael@0 706 case Deletion:
michael@0 707 case NormalShutdown:
michael@0 708 case AbnormalShutdown:
michael@0 709 break;
michael@0 710 case FailedConstructor:
michael@0 711 NS_RUNTIMEABORT("FailedConstructor isn't possible in PTexture");
michael@0 712 }
michael@0 713
michael@0 714 if (mTextureHost->GetFlags() & TEXTURE_RECYCLE) {
michael@0 715 RECYCLE_LOG("clear recycling for tile %p\n", this);
michael@0 716 mTextureHost->ClearRecycleCallback();
michael@0 717 }
michael@0 718 if (mTextureHost->GetFlags() & TEXTURE_DEALLOCATE_CLIENT) {
michael@0 719 mTextureHost->ForgetSharedData();
michael@0 720 }
michael@0 721
michael@0 722 // Clear recycle callback.
michael@0 723 mTextureHost->ClearRecycleCallback();
michael@0 724 mWaitForClientRecycle = nullptr;
michael@0 725
michael@0 726 mTextureHost->mActor = nullptr;
michael@0 727 mTextureHost = nullptr;
michael@0 728 }
michael@0 729
michael@0 730 } // namespace
michael@0 731 } // namespace

mercurial