gfx/layers/composite/ImageHost.cpp

branch
TOR_BUG_9701
changeset 8
97036ab72558
equal deleted inserted replaced
-1:000000000000 0:2aa8dc91be3c
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 "ImageHost.h"
7 #include "LayersLogging.h" // for AppendToString
8 #include "composite/CompositableHost.h" // for CompositableHost, etc
9 #include "ipc/IPCMessageUtils.h" // for null_t
10 #include "mozilla/layers/Compositor.h" // for Compositor
11 #include "mozilla/layers/Effects.h" // for TexturedEffect, Effect, etc
12 #include "nsAString.h"
13 #include "nsDebug.h" // for NS_WARNING, NS_ASSERTION
14 #include "nsPrintfCString.h" // for nsPrintfCString
15 #include "nsString.h" // for nsAutoCString
16
17 class nsIntRegion;
18
19 namespace mozilla {
20 namespace gfx {
21 class Matrix4x4;
22 }
23
24 using namespace gfx;
25
26 namespace layers {
27
28 class ISurfaceAllocator;
29
30 ImageHost::ImageHost(const TextureInfo& aTextureInfo)
31 : CompositableHost(aTextureInfo)
32 , mFrontBuffer(nullptr)
33 , mHasPictureRect(false)
34 {}
35
36 ImageHost::~ImageHost() {}
37
38 void
39 ImageHost::UseTextureHost(TextureHost* aTexture)
40 {
41 CompositableHost::UseTextureHost(aTexture);
42 mFrontBuffer = aTexture;
43 }
44
45 void
46 ImageHost::RemoveTextureHost(TextureHost* aTexture)
47 {
48 CompositableHost::RemoveTextureHost(aTexture);
49 if (aTexture && mFrontBuffer == aTexture) {
50 aTexture->SetCompositableBackendSpecificData(nullptr);
51 mFrontBuffer = nullptr;
52 }
53 }
54
55 TextureHost*
56 ImageHost::GetAsTextureHost()
57 {
58 return mFrontBuffer;
59 }
60
61 void
62 ImageHost::Composite(EffectChain& aEffectChain,
63 float aOpacity,
64 const gfx::Matrix4x4& aTransform,
65 const gfx::Filter& aFilter,
66 const gfx::Rect& aClipRect,
67 const nsIntRegion* aVisibleRegion,
68 TiledLayerProperties* aLayerProperties)
69 {
70 if (!GetCompositor()) {
71 // should only happen when a tab is dragged to another window and
72 // async-video is still sending frames but we haven't attached the
73 // set the new compositor yet.
74 return;
75 }
76 if (!mFrontBuffer) {
77 return;
78 }
79
80 // Make sure the front buffer has a compositor
81 mFrontBuffer->SetCompositor(GetCompositor());
82 mFrontBuffer->SetCompositableBackendSpecificData(GetCompositableBackendSpecificData());
83
84 AutoLockTextureHost autoLock(mFrontBuffer);
85 if (autoLock.Failed()) {
86 NS_WARNING("failed to lock front buffer");
87 return;
88 }
89 RefPtr<NewTextureSource> source = mFrontBuffer->GetTextureSources();
90 if (!source) {
91 return;
92 }
93 RefPtr<TexturedEffect> effect = CreateTexturedEffect(mFrontBuffer->GetFormat(),
94 source,
95 aFilter);
96 if (!effect) {
97 return;
98 }
99
100 aEffectChain.mPrimaryEffect = effect;
101 IntSize textureSize = source->GetSize();
102 gfx::Rect gfxPictureRect
103 = mHasPictureRect ? gfx::Rect(0, 0, mPictureRect.width, mPictureRect.height)
104 : gfx::Rect(0, 0, textureSize.width, textureSize.height);
105
106 gfx::Rect pictureRect(0, 0,
107 mPictureRect.width,
108 mPictureRect.height);
109 //XXX: We might have multiple texture sources here (e.g. 3 YCbCr textures), and we're
110 // only iterating over the tiles of the first one. Are we assuming that the tiling
111 // will be identical? Can we ensure that somehow?
112 TileIterator* it = source->AsTileIterator();
113 if (it) {
114 it->BeginTileIteration();
115 do {
116 nsIntRect tileRect = it->GetTileRect();
117 gfx::Rect rect(tileRect.x, tileRect.y, tileRect.width, tileRect.height);
118 if (mHasPictureRect) {
119 rect = rect.Intersect(pictureRect);
120 effect->mTextureCoords = Rect(Float(rect.x - tileRect.x)/ tileRect.width,
121 Float(rect.y - tileRect.y) / tileRect.height,
122 Float(rect.width) / tileRect.width,
123 Float(rect.height) / tileRect.height);
124 } else {
125 effect->mTextureCoords = Rect(0, 0, 1, 1);
126 }
127 GetCompositor()->DrawQuad(rect, aClipRect, aEffectChain,
128 aOpacity, aTransform);
129 GetCompositor()->DrawDiagnostics(DIAGNOSTIC_IMAGE|DIAGNOSTIC_BIGIMAGE,
130 rect, aClipRect, aTransform, mFlashCounter);
131 } while (it->NextTile());
132 it->EndTileIteration();
133 // layer border
134 GetCompositor()->DrawDiagnostics(DIAGNOSTIC_IMAGE,
135 gfxPictureRect, aClipRect,
136 aTransform, mFlashCounter);
137 } else {
138 IntSize textureSize = source->GetSize();
139 gfx::Rect rect;
140 if (mHasPictureRect) {
141 effect->mTextureCoords = Rect(Float(mPictureRect.x) / textureSize.width,
142 Float(mPictureRect.y) / textureSize.height,
143 Float(mPictureRect.width) / textureSize.width,
144 Float(mPictureRect.height) / textureSize.height);
145 rect = pictureRect;
146 } else {
147 effect->mTextureCoords = Rect(0, 0, 1, 1);
148 rect = gfx::Rect(0, 0, textureSize.width, textureSize.height);
149 }
150
151 if (mFrontBuffer->GetFlags() & TEXTURE_NEEDS_Y_FLIP) {
152 effect->mTextureCoords.y = effect->mTextureCoords.YMost();
153 effect->mTextureCoords.height = -effect->mTextureCoords.height;
154 }
155
156 GetCompositor()->DrawQuad(rect, aClipRect, aEffectChain,
157 aOpacity, aTransform);
158 GetCompositor()->DrawDiagnostics(DIAGNOSTIC_IMAGE,
159 rect, aClipRect,
160 aTransform, mFlashCounter);
161 }
162 }
163
164 void
165 ImageHost::SetCompositor(Compositor* aCompositor)
166 {
167 if (mFrontBuffer && mCompositor != aCompositor) {
168 mFrontBuffer->SetCompositor(aCompositor);
169 }
170 CompositableHost::SetCompositor(aCompositor);
171 }
172
173 void
174 ImageHost::PrintInfo(nsACString& aTo, const char* aPrefix)
175 {
176 aTo += aPrefix;
177 aTo += nsPrintfCString("ImageHost (0x%p)", this);
178
179 AppendToString(aTo, mPictureRect, " [picture-rect=", "]");
180
181 if (mFrontBuffer) {
182 nsAutoCString pfx(aPrefix);
183 pfx += " ";
184 aTo += "\n";
185 mFrontBuffer->PrintInfo(aTo, pfx.get());
186 }
187 }
188
189 #ifdef MOZ_DUMP_PAINTING
190 void
191 ImageHost::Dump(FILE* aFile,
192 const char* aPrefix,
193 bool aDumpHtml)
194 {
195 if (!aFile) {
196 aFile = stderr;
197 }
198 if (mFrontBuffer) {
199 fprintf_stderr(aFile, "%s", aPrefix);
200 fprintf_stderr(aFile, aDumpHtml ? "<ul><li>TextureHost: "
201 : "TextureHost: ");
202 DumpTextureHost(aFile, mFrontBuffer);
203 fprintf_stderr(aFile, aDumpHtml ? " </li></ul> " : " ");
204 }
205 }
206 #endif
207
208 LayerRenderState
209 ImageHost::GetRenderState()
210 {
211 if (mFrontBuffer) {
212 return mFrontBuffer->GetRenderState();
213 }
214 return LayerRenderState();
215 }
216
217 #ifdef MOZ_DUMP_PAINTING
218 TemporaryRef<gfx::DataSourceSurface>
219 ImageHost::GetAsSurface()
220 {
221 return mFrontBuffer->GetAsSurface();
222 }
223 #endif
224
225 }
226 }

mercurial