1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #ifndef GFX_GPU_VIDEO_IMAGE_H
8 #define GFX_GPU_VIDEO_IMAGE_H
9 
10 #include "mozilla/RefPtr.h"
11 #include "ImageContainer.h"
12 #include "mozilla/layers/GPUVideoTextureClient.h"
13 #include "mozilla/layers/CompositableClient.h"
14 #include "mozilla/layers/ImageBridgeChild.h"
15 
16 namespace mozilla {
17 namespace gl {
18 class GLBlitHelper;
19 }
20 namespace layers {
21 
22 class IGPUVideoSurfaceManager {
23  protected:
24   virtual ~IGPUVideoSurfaceManager() = default;
25 
26  public:
27   NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
28 
29   virtual already_AddRefed<gfx::SourceSurface> Readback(
30       const SurfaceDescriptorGPUVideo& aSD) = 0;
31   virtual void DeallocateSurfaceDescriptor(
32       const SurfaceDescriptorGPUVideo& aSD) = 0;
33 };
34 
35 // Represents an animated Image that is known to the GPU process.
36 class GPUVideoImage final : public Image {
37   friend class gl::GLBlitHelper;
38 
39  public:
GPUVideoImage(IGPUVideoSurfaceManager * aManager,const SurfaceDescriptorGPUVideo & aSD,const gfx::IntSize & aSize)40   GPUVideoImage(IGPUVideoSurfaceManager* aManager,
41                 const SurfaceDescriptorGPUVideo& aSD, const gfx::IntSize& aSize)
42       : Image(nullptr, ImageFormat::GPU_VIDEO), mSize(aSize) {
43     // Create the TextureClient immediately since the GPUVideoTextureData
44     // is responsible for deallocating the SurfaceDescriptor.
45     //
46     // Use the RECYCLE texture flag, since it's likely that our 'real'
47     // TextureData (in the decoder thread of the GPU process) is using
48     // it too, and we want to make sure we don't send the delete message
49     // until we've stopped being used on the compositor.
50     mTextureClient = TextureClient::CreateWithData(
51         new GPUVideoTextureData(aManager, aSD, aSize), TextureFlags::RECYCLE,
52         ImageBridgeChild::GetSingleton().get());
53   }
54 
55   virtual ~GPUVideoImage() = default;
56 
GetSize()57   gfx::IntSize GetSize() const override { return mSize; }
58 
GetDesc()59   Maybe<SurfaceDescriptor> GetDesc() override {
60     return GetDescFromTexClient(mTextureClient);
61   }
62 
63  private:
GetData()64   GPUVideoTextureData* GetData() const {
65     if (!mTextureClient) {
66       return nullptr;
67     }
68     TextureData* data = mTextureClient->GetInternalData();
69     if (!data) {
70       return nullptr;
71     }
72     return data->AsGPUVideoTextureData();
73   }
74 
75  public:
GetAsSourceSurface()76   already_AddRefed<gfx::SourceSurface> GetAsSourceSurface() override {
77     GPUVideoTextureData* data = GetData();
78     if (!data) {
79       return nullptr;
80     }
81     return data->GetAsSourceSurface();
82   }
83 
GetTextureClient(KnowsCompositor * aKnowsCompositor)84   TextureClient* GetTextureClient(KnowsCompositor* aKnowsCompositor) override {
85     MOZ_ASSERT(aKnowsCompositor == ImageBridgeChild::GetSingleton(),
86                "Must only use GPUVideo on ImageBridge");
87     return mTextureClient;
88   }
89 
90  private:
91   gfx::IntSize mSize;
92   RefPtr<TextureClient> mTextureClient;
93 };
94 
95 }  // namespace layers
96 }  // namespace mozilla
97 
98 #endif  // GFX_GPU_VIDEO_IMAGE_H
99