Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; 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 "ClientLayerManager.h" // for ClientLayerManager, etc
7 : #include "ImageContainer.h" // for AutoLockImage, etc
8 : #include "ImageLayers.h" // for ImageLayer
9 : #include "mozilla/Attributes.h" // for override
10 : #include "mozilla/RefPtr.h" // for RefPtr
11 : #include "mozilla/layers/CompositorTypes.h"
12 : #include "mozilla/layers/ImageClient.h" // for ImageClient, etc
13 : #include "mozilla/layers/LayersMessages.h" // for ImageLayerAttributes, etc
14 : #include "mozilla/mozalloc.h" // for operator delete, etc
15 : #include "nsCOMPtr.h" // for already_AddRefed
16 : #include "nsDebug.h" // for NS_ASSERTION
17 : #include "nsISupportsImpl.h" // for Layer::AddRef, etc
18 : #include "nsRegion.h" // for nsIntRegion
19 :
20 : namespace mozilla {
21 : namespace layers {
22 :
23 : using namespace mozilla::gfx;
24 :
25 : class ClientImageLayer : public ImageLayer,
26 : public ClientLayer {
27 : public:
28 0 : explicit ClientImageLayer(ClientLayerManager* aLayerManager)
29 0 : : ImageLayer(aLayerManager, static_cast<ClientLayer*>(this))
30 0 : , mImageClientTypeContainer(CompositableType::UNKNOWN)
31 : {
32 0 : MOZ_COUNT_CTOR(ClientImageLayer);
33 0 : }
34 :
35 : protected:
36 0 : virtual ~ClientImageLayer()
37 0 : {
38 0 : DestroyBackBuffer();
39 0 : MOZ_COUNT_DTOR(ClientImageLayer);
40 0 : }
41 :
42 0 : virtual void SetContainer(ImageContainer* aContainer) override
43 : {
44 0 : ImageLayer::SetContainer(aContainer);
45 0 : mImageClientTypeContainer = CompositableType::UNKNOWN;
46 0 : }
47 :
48 0 : virtual void SetVisibleRegion(const LayerIntRegion& aRegion) override
49 : {
50 0 : NS_ASSERTION(ClientManager()->InConstruction(),
51 : "Can only set properties in construction phase");
52 0 : ImageLayer::SetVisibleRegion(aRegion);
53 0 : }
54 :
55 : virtual void RenderLayer() override;
56 :
57 0 : virtual void ClearCachedResources() override
58 : {
59 0 : DestroyBackBuffer();
60 0 : }
61 :
62 0 : virtual bool SupportsAsyncUpdate() override
63 : {
64 0 : if (GetImageClientType() == CompositableType::IMAGE_BRIDGE) {
65 0 : return true;
66 : }
67 0 : return false;
68 : }
69 :
70 0 : virtual void HandleMemoryPressure() override
71 : {
72 0 : if (mImageClient) {
73 0 : mImageClient->HandleMemoryPressure();
74 : }
75 0 : }
76 :
77 0 : virtual void FillSpecificAttributes(SpecificLayerAttributes& aAttrs) override
78 : {
79 0 : aAttrs = ImageLayerAttributes(mSamplingFilter, mScaleToSize, mScaleMode);
80 0 : }
81 :
82 0 : virtual Layer* AsLayer() override { return this; }
83 0 : virtual ShadowableLayer* AsShadowableLayer() override { return this; }
84 :
85 0 : virtual void Disconnect() override
86 : {
87 0 : DestroyBackBuffer();
88 0 : }
89 :
90 0 : void DestroyBackBuffer()
91 : {
92 0 : if (mImageClient) {
93 0 : mImageClient->SetLayer(nullptr);
94 0 : mImageClient->OnDetach();
95 0 : mImageClient = nullptr;
96 : }
97 0 : }
98 :
99 0 : virtual CompositableClient* GetCompositableClient() override
100 : {
101 0 : return mImageClient;
102 : }
103 :
104 : protected:
105 0 : ClientLayerManager* ClientManager()
106 : {
107 0 : return static_cast<ClientLayerManager*>(mManager);
108 : }
109 :
110 0 : CompositableType GetImageClientType()
111 : {
112 0 : if (mImageClientTypeContainer != CompositableType::UNKNOWN) {
113 0 : return mImageClientTypeContainer;
114 : }
115 :
116 0 : if (mContainer->IsAsync()) {
117 0 : mImageClientTypeContainer = CompositableType::IMAGE_BRIDGE;
118 0 : return mImageClientTypeContainer;
119 : }
120 :
121 0 : AutoLockImage autoLock(mContainer);
122 :
123 0 : mImageClientTypeContainer = autoLock.HasImage()
124 0 : ? CompositableType::IMAGE : CompositableType::UNKNOWN;
125 0 : return mImageClientTypeContainer;
126 : }
127 :
128 : RefPtr<ImageClient> mImageClient;
129 : CompositableType mImageClientTypeContainer;
130 : };
131 :
132 : void
133 0 : ClientImageLayer::RenderLayer()
134 : {
135 0 : RenderMaskLayers(this);
136 :
137 0 : if (!mContainer) {
138 0 : return;
139 : }
140 :
141 0 : if (!mImageClient ||
142 0 : !mImageClient->UpdateImage(mContainer, GetContentFlags())) {
143 0 : CompositableType type = GetImageClientType();
144 0 : if (type == CompositableType::UNKNOWN) {
145 0 : return;
146 : }
147 0 : TextureFlags flags = TextureFlags::DEFAULT;
148 0 : mImageClient = ImageClient::CreateImageClient(type,
149 0 : ClientManager()->AsShadowForwarder(),
150 0 : flags);
151 0 : if (!mImageClient) {
152 0 : return;
153 : }
154 0 : mImageClient->SetLayer(this);
155 0 : if (HasShadow() && !mContainer->IsAsync()) {
156 0 : mImageClient->Connect();
157 0 : ClientManager()->AsShadowForwarder()->Attach(mImageClient, this);
158 : }
159 0 : if (!mImageClient->UpdateImage(mContainer, GetContentFlags())) {
160 0 : return;
161 : }
162 : }
163 0 : ClientManager()->Hold(this);
164 : }
165 :
166 : already_AddRefed<ImageLayer>
167 0 : ClientLayerManager::CreateImageLayer()
168 : {
169 0 : NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
170 : RefPtr<ClientImageLayer> layer =
171 0 : new ClientImageLayer(this);
172 0 : CREATE_SHADOW(Image);
173 0 : return layer.forget();
174 : }
175 :
176 : } // namespace layers
177 : } // namespace mozilla
|