gfx/layers/composite/TextureHost.cpp

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

mercurial