Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- |
michael@0 | 2 | * vim: sw=2 ts=8 et : |
michael@0 | 3 | */ |
michael@0 | 4 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 7 | |
michael@0 | 8 | #include "ShadowLayers.h" |
michael@0 | 9 | #include <set> // for _Rb_tree_const_iterator, etc |
michael@0 | 10 | #include <vector> // for vector |
michael@0 | 11 | #include "GeckoProfiler.h" // for PROFILER_LABEL |
michael@0 | 12 | #include "ISurfaceAllocator.h" // for IsSurfaceDescriptorValid |
michael@0 | 13 | #include "Layers.h" // for Layer |
michael@0 | 14 | #include "RenderTrace.h" // for RenderTraceScope |
michael@0 | 15 | #include "ShadowLayerChild.h" // for ShadowLayerChild |
michael@0 | 16 | #include "gfx2DGlue.h" // for Moz2D transition helpers |
michael@0 | 17 | #include "gfxPlatform.h" // for gfxImageFormat, gfxPlatform |
michael@0 | 18 | #include "gfxSharedImageSurface.h" // for gfxSharedImageSurface |
michael@0 | 19 | #include "ipc/IPCMessageUtils.h" // for gfxContentType, null_t |
michael@0 | 20 | #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc |
michael@0 | 21 | #include "mozilla/gfx/Point.h" // for IntSize |
michael@0 | 22 | #include "mozilla/layers/CompositableClient.h" // for CompositableClient, etc |
michael@0 | 23 | #include "mozilla/layers/LayersMessages.h" // for Edit, etc |
michael@0 | 24 | #include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor, etc |
michael@0 | 25 | #include "mozilla/layers/LayersTypes.h" // for MOZ_LAYERS_LOG |
michael@0 | 26 | #include "mozilla/layers/LayerTransactionChild.h" |
michael@0 | 27 | #include "ShadowLayerUtils.h" |
michael@0 | 28 | #include "mozilla/layers/TextureClient.h" // for TextureClient |
michael@0 | 29 | #include "mozilla/mozalloc.h" // for operator new, etc |
michael@0 | 30 | #include "nsAutoPtr.h" // for nsRefPtr, getter_AddRefs, etc |
michael@0 | 31 | #include "nsDebug.h" // for NS_ABORT_IF_FALSE, etc |
michael@0 | 32 | #include "nsRect.h" // for nsIntRect |
michael@0 | 33 | #include "nsSize.h" // for nsIntSize |
michael@0 | 34 | #include "nsTArray.h" // for nsAutoTArray, nsTArray, etc |
michael@0 | 35 | #include "nsXULAppAPI.h" // for XRE_GetProcessType, etc |
michael@0 | 36 | |
michael@0 | 37 | struct nsIntPoint; |
michael@0 | 38 | |
michael@0 | 39 | using namespace mozilla::ipc; |
michael@0 | 40 | using namespace mozilla::gl; |
michael@0 | 41 | using namespace mozilla::dom; |
michael@0 | 42 | |
michael@0 | 43 | namespace mozilla { |
michael@0 | 44 | namespace ipc { |
michael@0 | 45 | class Shmem; |
michael@0 | 46 | } |
michael@0 | 47 | |
michael@0 | 48 | namespace layers { |
michael@0 | 49 | |
michael@0 | 50 | class ClientTiledLayerBuffer; |
michael@0 | 51 | |
michael@0 | 52 | typedef nsTArray<SurfaceDescriptor> BufferArray; |
michael@0 | 53 | typedef std::vector<Edit> EditVector; |
michael@0 | 54 | typedef std::set<ShadowableLayer*> ShadowableLayerSet; |
michael@0 | 55 | |
michael@0 | 56 | class Transaction |
michael@0 | 57 | { |
michael@0 | 58 | public: |
michael@0 | 59 | Transaction() |
michael@0 | 60 | : mTargetRotation(ROTATION_0) |
michael@0 | 61 | , mSwapRequired(false) |
michael@0 | 62 | , mOpen(false) |
michael@0 | 63 | , mRotationChanged(false) |
michael@0 | 64 | {} |
michael@0 | 65 | |
michael@0 | 66 | void Begin(const nsIntRect& aTargetBounds, ScreenRotation aRotation, |
michael@0 | 67 | const nsIntRect& aClientBounds, ScreenOrientation aOrientation) |
michael@0 | 68 | { |
michael@0 | 69 | mOpen = true; |
michael@0 | 70 | mTargetBounds = aTargetBounds; |
michael@0 | 71 | if (aRotation != mTargetRotation) { |
michael@0 | 72 | // the first time this is called, mRotationChanged will be false if |
michael@0 | 73 | // aRotation is 0, but we should be OK because for the first transaction |
michael@0 | 74 | // we should only compose if it is non-empty. See the caller(s) of |
michael@0 | 75 | // RotationChanged. |
michael@0 | 76 | mRotationChanged = true; |
michael@0 | 77 | } |
michael@0 | 78 | mTargetRotation = aRotation; |
michael@0 | 79 | mClientBounds = aClientBounds; |
michael@0 | 80 | mTargetOrientation = aOrientation; |
michael@0 | 81 | } |
michael@0 | 82 | void MarkSyncTransaction() |
michael@0 | 83 | { |
michael@0 | 84 | mSwapRequired = true; |
michael@0 | 85 | } |
michael@0 | 86 | void AddEdit(const Edit& aEdit) |
michael@0 | 87 | { |
michael@0 | 88 | NS_ABORT_IF_FALSE(!Finished(), "forgot BeginTransaction?"); |
michael@0 | 89 | mCset.push_back(aEdit); |
michael@0 | 90 | } |
michael@0 | 91 | void AddEdit(const CompositableOperation& aEdit) |
michael@0 | 92 | { |
michael@0 | 93 | AddEdit(Edit(aEdit)); |
michael@0 | 94 | } |
michael@0 | 95 | void AddPaint(const Edit& aPaint) |
michael@0 | 96 | { |
michael@0 | 97 | AddNoSwapPaint(aPaint); |
michael@0 | 98 | mSwapRequired = true; |
michael@0 | 99 | } |
michael@0 | 100 | void AddPaint(const CompositableOperation& aPaint) |
michael@0 | 101 | { |
michael@0 | 102 | AddNoSwapPaint(Edit(aPaint)); |
michael@0 | 103 | mSwapRequired = true; |
michael@0 | 104 | } |
michael@0 | 105 | |
michael@0 | 106 | void AddNoSwapPaint(const Edit& aPaint) |
michael@0 | 107 | { |
michael@0 | 108 | NS_ABORT_IF_FALSE(!Finished(), "forgot BeginTransaction?"); |
michael@0 | 109 | mPaints.push_back(aPaint); |
michael@0 | 110 | } |
michael@0 | 111 | void AddNoSwapPaint(const CompositableOperation& aPaint) |
michael@0 | 112 | { |
michael@0 | 113 | NS_ABORT_IF_FALSE(!Finished(), "forgot BeginTransaction?"); |
michael@0 | 114 | mPaints.push_back(Edit(aPaint)); |
michael@0 | 115 | } |
michael@0 | 116 | void AddMutant(ShadowableLayer* aLayer) |
michael@0 | 117 | { |
michael@0 | 118 | NS_ABORT_IF_FALSE(!Finished(), "forgot BeginTransaction?"); |
michael@0 | 119 | mMutants.insert(aLayer); |
michael@0 | 120 | } |
michael@0 | 121 | void End() |
michael@0 | 122 | { |
michael@0 | 123 | mCset.clear(); |
michael@0 | 124 | mPaints.clear(); |
michael@0 | 125 | mMutants.clear(); |
michael@0 | 126 | mOpen = false; |
michael@0 | 127 | mSwapRequired = false; |
michael@0 | 128 | mRotationChanged = false; |
michael@0 | 129 | } |
michael@0 | 130 | |
michael@0 | 131 | bool Empty() const { |
michael@0 | 132 | return mCset.empty() && mPaints.empty() && mMutants.empty(); |
michael@0 | 133 | } |
michael@0 | 134 | bool RotationChanged() const { |
michael@0 | 135 | return mRotationChanged; |
michael@0 | 136 | } |
michael@0 | 137 | bool Finished() const { return !mOpen && Empty(); } |
michael@0 | 138 | |
michael@0 | 139 | EditVector mCset; |
michael@0 | 140 | EditVector mPaints; |
michael@0 | 141 | ShadowableLayerSet mMutants; |
michael@0 | 142 | nsIntRect mTargetBounds; |
michael@0 | 143 | ScreenRotation mTargetRotation; |
michael@0 | 144 | nsIntRect mClientBounds; |
michael@0 | 145 | ScreenOrientation mTargetOrientation; |
michael@0 | 146 | bool mSwapRequired; |
michael@0 | 147 | |
michael@0 | 148 | private: |
michael@0 | 149 | bool mOpen; |
michael@0 | 150 | bool mRotationChanged; |
michael@0 | 151 | |
michael@0 | 152 | // disabled |
michael@0 | 153 | Transaction(const Transaction&); |
michael@0 | 154 | Transaction& operator=(const Transaction&); |
michael@0 | 155 | }; |
michael@0 | 156 | struct AutoTxnEnd { |
michael@0 | 157 | AutoTxnEnd(Transaction* aTxn) : mTxn(aTxn) {} |
michael@0 | 158 | ~AutoTxnEnd() { mTxn->End(); } |
michael@0 | 159 | Transaction* mTxn; |
michael@0 | 160 | }; |
michael@0 | 161 | |
michael@0 | 162 | void |
michael@0 | 163 | CompositableForwarder::IdentifyTextureHost(const TextureFactoryIdentifier& aIdentifier) |
michael@0 | 164 | { |
michael@0 | 165 | mTextureFactoryIdentifier = aIdentifier; |
michael@0 | 166 | } |
michael@0 | 167 | |
michael@0 | 168 | ShadowLayerForwarder::ShadowLayerForwarder() |
michael@0 | 169 | : mDiagnosticTypes(DIAGNOSTIC_NONE) |
michael@0 | 170 | , mIsFirstPaint(false) |
michael@0 | 171 | , mWindowOverlayChanged(false) |
michael@0 | 172 | { |
michael@0 | 173 | mTxn = new Transaction(); |
michael@0 | 174 | } |
michael@0 | 175 | |
michael@0 | 176 | ShadowLayerForwarder::~ShadowLayerForwarder() |
michael@0 | 177 | { |
michael@0 | 178 | NS_ABORT_IF_FALSE(mTxn->Finished(), "unfinished transaction?"); |
michael@0 | 179 | delete mTxn; |
michael@0 | 180 | } |
michael@0 | 181 | |
michael@0 | 182 | void |
michael@0 | 183 | ShadowLayerForwarder::BeginTransaction(const nsIntRect& aTargetBounds, |
michael@0 | 184 | ScreenRotation aRotation, |
michael@0 | 185 | const nsIntRect& aClientBounds, |
michael@0 | 186 | ScreenOrientation aOrientation) |
michael@0 | 187 | { |
michael@0 | 188 | NS_ABORT_IF_FALSE(HasShadowManager(), "no manager to forward to"); |
michael@0 | 189 | NS_ABORT_IF_FALSE(mTxn->Finished(), "uncommitted txn?"); |
michael@0 | 190 | mTxn->Begin(aTargetBounds, aRotation, aClientBounds, aOrientation); |
michael@0 | 191 | } |
michael@0 | 192 | |
michael@0 | 193 | static PLayerChild* |
michael@0 | 194 | Shadow(ShadowableLayer* aLayer) |
michael@0 | 195 | { |
michael@0 | 196 | return aLayer->GetShadow(); |
michael@0 | 197 | } |
michael@0 | 198 | |
michael@0 | 199 | template<typename OpCreateT> |
michael@0 | 200 | static void |
michael@0 | 201 | CreatedLayer(Transaction* aTxn, ShadowableLayer* aLayer) |
michael@0 | 202 | { |
michael@0 | 203 | aTxn->AddEdit(OpCreateT(nullptr, Shadow(aLayer))); |
michael@0 | 204 | } |
michael@0 | 205 | |
michael@0 | 206 | void |
michael@0 | 207 | ShadowLayerForwarder::CreatedThebesLayer(ShadowableLayer* aThebes) |
michael@0 | 208 | { |
michael@0 | 209 | CreatedLayer<OpCreateThebesLayer>(mTxn, aThebes); |
michael@0 | 210 | } |
michael@0 | 211 | void |
michael@0 | 212 | ShadowLayerForwarder::CreatedContainerLayer(ShadowableLayer* aContainer) |
michael@0 | 213 | { |
michael@0 | 214 | CreatedLayer<OpCreateContainerLayer>(mTxn, aContainer); |
michael@0 | 215 | } |
michael@0 | 216 | void |
michael@0 | 217 | ShadowLayerForwarder::CreatedImageLayer(ShadowableLayer* aImage) |
michael@0 | 218 | { |
michael@0 | 219 | CreatedLayer<OpCreateImageLayer>(mTxn, aImage); |
michael@0 | 220 | } |
michael@0 | 221 | void |
michael@0 | 222 | ShadowLayerForwarder::CreatedColorLayer(ShadowableLayer* aColor) |
michael@0 | 223 | { |
michael@0 | 224 | CreatedLayer<OpCreateColorLayer>(mTxn, aColor); |
michael@0 | 225 | } |
michael@0 | 226 | void |
michael@0 | 227 | ShadowLayerForwarder::CreatedCanvasLayer(ShadowableLayer* aCanvas) |
michael@0 | 228 | { |
michael@0 | 229 | CreatedLayer<OpCreateCanvasLayer>(mTxn, aCanvas); |
michael@0 | 230 | } |
michael@0 | 231 | void |
michael@0 | 232 | ShadowLayerForwarder::CreatedRefLayer(ShadowableLayer* aRef) |
michael@0 | 233 | { |
michael@0 | 234 | CreatedLayer<OpCreateRefLayer>(mTxn, aRef); |
michael@0 | 235 | } |
michael@0 | 236 | |
michael@0 | 237 | void |
michael@0 | 238 | ShadowLayerForwarder::Mutated(ShadowableLayer* aMutant) |
michael@0 | 239 | { |
michael@0 | 240 | mTxn->AddMutant(aMutant); |
michael@0 | 241 | } |
michael@0 | 242 | |
michael@0 | 243 | void |
michael@0 | 244 | ShadowLayerForwarder::SetRoot(ShadowableLayer* aRoot) |
michael@0 | 245 | { |
michael@0 | 246 | mTxn->AddEdit(OpSetRoot(nullptr, Shadow(aRoot))); |
michael@0 | 247 | } |
michael@0 | 248 | void |
michael@0 | 249 | ShadowLayerForwarder::InsertAfter(ShadowableLayer* aContainer, |
michael@0 | 250 | ShadowableLayer* aChild, |
michael@0 | 251 | ShadowableLayer* aAfter) |
michael@0 | 252 | { |
michael@0 | 253 | if (aAfter) |
michael@0 | 254 | mTxn->AddEdit(OpInsertAfter(nullptr, Shadow(aContainer), |
michael@0 | 255 | nullptr, Shadow(aChild), |
michael@0 | 256 | nullptr, Shadow(aAfter))); |
michael@0 | 257 | else |
michael@0 | 258 | mTxn->AddEdit(OpPrependChild(nullptr, Shadow(aContainer), |
michael@0 | 259 | nullptr, Shadow(aChild))); |
michael@0 | 260 | } |
michael@0 | 261 | void |
michael@0 | 262 | ShadowLayerForwarder::RemoveChild(ShadowableLayer* aContainer, |
michael@0 | 263 | ShadowableLayer* aChild) |
michael@0 | 264 | { |
michael@0 | 265 | MOZ_LAYERS_LOG(("[LayersForwarder] OpRemoveChild container=%p child=%p\n", |
michael@0 | 266 | aContainer->AsLayer(), aChild->AsLayer())); |
michael@0 | 267 | |
michael@0 | 268 | mTxn->AddEdit(OpRemoveChild(nullptr, Shadow(aContainer), |
michael@0 | 269 | nullptr, Shadow(aChild))); |
michael@0 | 270 | } |
michael@0 | 271 | void |
michael@0 | 272 | ShadowLayerForwarder::RepositionChild(ShadowableLayer* aContainer, |
michael@0 | 273 | ShadowableLayer* aChild, |
michael@0 | 274 | ShadowableLayer* aAfter) |
michael@0 | 275 | { |
michael@0 | 276 | if (aAfter) { |
michael@0 | 277 | MOZ_LAYERS_LOG(("[LayersForwarder] OpRepositionChild container=%p child=%p after=%p", |
michael@0 | 278 | aContainer->AsLayer(), aChild->AsLayer(), aAfter->AsLayer())); |
michael@0 | 279 | mTxn->AddEdit(OpRepositionChild(nullptr, Shadow(aContainer), |
michael@0 | 280 | nullptr, Shadow(aChild), |
michael@0 | 281 | nullptr, Shadow(aAfter))); |
michael@0 | 282 | } else { |
michael@0 | 283 | MOZ_LAYERS_LOG(("[LayersForwarder] OpRaiseToTopChild container=%p child=%p", |
michael@0 | 284 | aContainer->AsLayer(), aChild->AsLayer())); |
michael@0 | 285 | mTxn->AddEdit(OpRaiseToTopChild(nullptr, Shadow(aContainer), |
michael@0 | 286 | nullptr, Shadow(aChild))); |
michael@0 | 287 | } |
michael@0 | 288 | } |
michael@0 | 289 | |
michael@0 | 290 | |
michael@0 | 291 | #ifdef DEBUG |
michael@0 | 292 | void |
michael@0 | 293 | ShadowLayerForwarder::CheckSurfaceDescriptor(const SurfaceDescriptor* aDescriptor) const |
michael@0 | 294 | { |
michael@0 | 295 | if (!aDescriptor) { |
michael@0 | 296 | return; |
michael@0 | 297 | } |
michael@0 | 298 | |
michael@0 | 299 | if (aDescriptor->type() == SurfaceDescriptor::TSurfaceDescriptorShmem) { |
michael@0 | 300 | const SurfaceDescriptorShmem& shmem = aDescriptor->get_SurfaceDescriptorShmem(); |
michael@0 | 301 | shmem.data().AssertInvariants(); |
michael@0 | 302 | MOZ_ASSERT(mShadowManager && |
michael@0 | 303 | mShadowManager->IsTrackingSharedMemory(shmem.data().mSegment)); |
michael@0 | 304 | } |
michael@0 | 305 | } |
michael@0 | 306 | #endif |
michael@0 | 307 | |
michael@0 | 308 | void |
michael@0 | 309 | ShadowLayerForwarder::UseTiledLayerBuffer(CompositableClient* aCompositable, |
michael@0 | 310 | const SurfaceDescriptorTiles& aTileLayerDescriptor) |
michael@0 | 311 | { |
michael@0 | 312 | MOZ_ASSERT(aCompositable); |
michael@0 | 313 | MOZ_ASSERT(aCompositable->GetIPDLActor()); |
michael@0 | 314 | mTxn->AddNoSwapPaint(OpUseTiledLayerBuffer(nullptr, aCompositable->GetIPDLActor(), |
michael@0 | 315 | aTileLayerDescriptor)); |
michael@0 | 316 | } |
michael@0 | 317 | |
michael@0 | 318 | void |
michael@0 | 319 | ShadowLayerForwarder::UpdateTextureRegion(CompositableClient* aCompositable, |
michael@0 | 320 | const ThebesBufferData& aThebesBufferData, |
michael@0 | 321 | const nsIntRegion& aUpdatedRegion) |
michael@0 | 322 | { |
michael@0 | 323 | MOZ_ASSERT(aCompositable); |
michael@0 | 324 | MOZ_ASSERT(aCompositable->GetIPDLActor()); |
michael@0 | 325 | mTxn->AddPaint(OpPaintTextureRegion(nullptr, aCompositable->GetIPDLActor(), |
michael@0 | 326 | aThebesBufferData, |
michael@0 | 327 | aUpdatedRegion)); |
michael@0 | 328 | } |
michael@0 | 329 | |
michael@0 | 330 | void |
michael@0 | 331 | ShadowLayerForwarder::UpdateTextureIncremental(CompositableClient* aCompositable, |
michael@0 | 332 | TextureIdentifier aTextureId, |
michael@0 | 333 | SurfaceDescriptor& aDescriptor, |
michael@0 | 334 | const nsIntRegion& aUpdatedRegion, |
michael@0 | 335 | const nsIntRect& aBufferRect, |
michael@0 | 336 | const nsIntPoint& aBufferRotation) |
michael@0 | 337 | { |
michael@0 | 338 | CheckSurfaceDescriptor(&aDescriptor); |
michael@0 | 339 | MOZ_ASSERT(aCompositable); |
michael@0 | 340 | MOZ_ASSERT(aCompositable->GetIPDLActor()); |
michael@0 | 341 | mTxn->AddNoSwapPaint(OpPaintTextureIncremental(nullptr, aCompositable->GetIPDLActor(), |
michael@0 | 342 | aTextureId, |
michael@0 | 343 | aDescriptor, |
michael@0 | 344 | aUpdatedRegion, |
michael@0 | 345 | aBufferRect, |
michael@0 | 346 | aBufferRotation)); |
michael@0 | 347 | } |
michael@0 | 348 | |
michael@0 | 349 | |
michael@0 | 350 | void |
michael@0 | 351 | ShadowLayerForwarder::UpdatePictureRect(CompositableClient* aCompositable, |
michael@0 | 352 | const nsIntRect& aRect) |
michael@0 | 353 | { |
michael@0 | 354 | MOZ_ASSERT(aCompositable); |
michael@0 | 355 | MOZ_ASSERT(aCompositable->GetIPDLActor()); |
michael@0 | 356 | mTxn->AddNoSwapPaint(OpUpdatePictureRect(nullptr, aCompositable->GetIPDLActor(), aRect)); |
michael@0 | 357 | } |
michael@0 | 358 | |
michael@0 | 359 | void |
michael@0 | 360 | ShadowLayerForwarder::UpdatedTexture(CompositableClient* aCompositable, |
michael@0 | 361 | TextureClient* aTexture, |
michael@0 | 362 | nsIntRegion* aRegion) |
michael@0 | 363 | { |
michael@0 | 364 | MOZ_ASSERT(aCompositable); |
michael@0 | 365 | MOZ_ASSERT(aTexture); |
michael@0 | 366 | MOZ_ASSERT(aCompositable->GetIPDLActor()); |
michael@0 | 367 | MOZ_ASSERT(aTexture->GetIPDLActor()); |
michael@0 | 368 | MaybeRegion region = aRegion ? MaybeRegion(*aRegion) |
michael@0 | 369 | : MaybeRegion(null_t()); |
michael@0 | 370 | if (aTexture->GetFlags() & TEXTURE_IMMEDIATE_UPLOAD) { |
michael@0 | 371 | mTxn->AddPaint(OpUpdateTexture(nullptr, aCompositable->GetIPDLActor(), |
michael@0 | 372 | nullptr, aTexture->GetIPDLActor(), |
michael@0 | 373 | region)); |
michael@0 | 374 | } else { |
michael@0 | 375 | mTxn->AddNoSwapPaint(OpUpdateTexture(nullptr, aCompositable->GetIPDLActor(), |
michael@0 | 376 | nullptr, aTexture->GetIPDLActor(), |
michael@0 | 377 | region)); |
michael@0 | 378 | } |
michael@0 | 379 | } |
michael@0 | 380 | |
michael@0 | 381 | void |
michael@0 | 382 | ShadowLayerForwarder::UseTexture(CompositableClient* aCompositable, |
michael@0 | 383 | TextureClient* aTexture) |
michael@0 | 384 | { |
michael@0 | 385 | MOZ_ASSERT(aCompositable); |
michael@0 | 386 | MOZ_ASSERT(aTexture); |
michael@0 | 387 | MOZ_ASSERT(aCompositable->GetIPDLActor()); |
michael@0 | 388 | MOZ_ASSERT(aTexture->GetIPDLActor()); |
michael@0 | 389 | mTxn->AddEdit(OpUseTexture(nullptr, aCompositable->GetIPDLActor(), |
michael@0 | 390 | nullptr, aTexture->GetIPDLActor())); |
michael@0 | 391 | } |
michael@0 | 392 | |
michael@0 | 393 | void |
michael@0 | 394 | ShadowLayerForwarder::UseComponentAlphaTextures(CompositableClient* aCompositable, |
michael@0 | 395 | TextureClient* aTextureOnBlack, |
michael@0 | 396 | TextureClient* aTextureOnWhite) |
michael@0 | 397 | { |
michael@0 | 398 | MOZ_ASSERT(aCompositable); |
michael@0 | 399 | MOZ_ASSERT(aTextureOnWhite); |
michael@0 | 400 | MOZ_ASSERT(aTextureOnBlack); |
michael@0 | 401 | MOZ_ASSERT(aCompositable->GetIPDLActor()); |
michael@0 | 402 | MOZ_ASSERT(aTextureOnBlack->GetIPDLActor()); |
michael@0 | 403 | MOZ_ASSERT(aTextureOnWhite->GetIPDLActor()); |
michael@0 | 404 | MOZ_ASSERT(aTextureOnBlack->GetSize() == aTextureOnWhite->GetSize()); |
michael@0 | 405 | mTxn->AddEdit(OpUseComponentAlphaTextures(nullptr, aCompositable->GetIPDLActor(), |
michael@0 | 406 | nullptr, aTextureOnBlack->GetIPDLActor(), |
michael@0 | 407 | nullptr, aTextureOnWhite->GetIPDLActor())); |
michael@0 | 408 | } |
michael@0 | 409 | |
michael@0 | 410 | void |
michael@0 | 411 | ShadowLayerForwarder::RemoveTextureFromCompositable(CompositableClient* aCompositable, |
michael@0 | 412 | TextureClient* aTexture) |
michael@0 | 413 | { |
michael@0 | 414 | MOZ_ASSERT(aCompositable); |
michael@0 | 415 | MOZ_ASSERT(aTexture); |
michael@0 | 416 | MOZ_ASSERT(aCompositable->GetIPDLActor()); |
michael@0 | 417 | MOZ_ASSERT(aTexture->GetIPDLActor()); |
michael@0 | 418 | mTxn->AddEdit(OpRemoveTexture(nullptr, aCompositable->GetIPDLActor(), |
michael@0 | 419 | nullptr, aTexture->GetIPDLActor())); |
michael@0 | 420 | if (aTexture->GetFlags() & TEXTURE_DEALLOCATE_CLIENT) { |
michael@0 | 421 | mTxn->MarkSyncTransaction(); |
michael@0 | 422 | } |
michael@0 | 423 | // Hold texture until transaction complete. |
michael@0 | 424 | HoldUntilTransaction(aTexture); |
michael@0 | 425 | } |
michael@0 | 426 | |
michael@0 | 427 | void |
michael@0 | 428 | ShadowLayerForwarder::RemoveTexture(TextureClient* aTexture) |
michael@0 | 429 | { |
michael@0 | 430 | MOZ_ASSERT(aTexture); |
michael@0 | 431 | aTexture->ForceRemove(); |
michael@0 | 432 | } |
michael@0 | 433 | |
michael@0 | 434 | bool |
michael@0 | 435 | ShadowLayerForwarder::EndTransaction(InfallibleTArray<EditReply>* aReplies, |
michael@0 | 436 | const nsIntRegion& aRegionToClear, |
michael@0 | 437 | bool aScheduleComposite, |
michael@0 | 438 | bool* aSent) |
michael@0 | 439 | { |
michael@0 | 440 | *aSent = false; |
michael@0 | 441 | |
michael@0 | 442 | PROFILER_LABEL("ShadowLayerForwarder", "EndTranscation"); |
michael@0 | 443 | RenderTraceScope rendertrace("Foward Transaction", "000091"); |
michael@0 | 444 | NS_ABORT_IF_FALSE(HasShadowManager(), "no manager to forward to"); |
michael@0 | 445 | NS_ABORT_IF_FALSE(!mTxn->Finished(), "forgot BeginTransaction?"); |
michael@0 | 446 | |
michael@0 | 447 | DiagnosticTypes diagnostics = gfxPlatform::GetPlatform()->GetLayerDiagnosticTypes(); |
michael@0 | 448 | if (mDiagnosticTypes != diagnostics) { |
michael@0 | 449 | mDiagnosticTypes = diagnostics; |
michael@0 | 450 | mTxn->AddEdit(OpSetDiagnosticTypes(diagnostics)); |
michael@0 | 451 | } |
michael@0 | 452 | |
michael@0 | 453 | AutoTxnEnd _(mTxn); |
michael@0 | 454 | |
michael@0 | 455 | if (mTxn->Empty() && !mTxn->RotationChanged() && !mWindowOverlayChanged) { |
michael@0 | 456 | MOZ_LAYERS_LOG(("[LayersForwarder] 0-length cset (?) and no rotation event, skipping Update()")); |
michael@0 | 457 | return true; |
michael@0 | 458 | } |
michael@0 | 459 | |
michael@0 | 460 | MOZ_LAYERS_LOG(("[LayersForwarder] destroying buffers...")); |
michael@0 | 461 | |
michael@0 | 462 | MOZ_LAYERS_LOG(("[LayersForwarder] building transaction...")); |
michael@0 | 463 | |
michael@0 | 464 | // We purposely add attribute-change ops to the final changeset |
michael@0 | 465 | // before we add paint ops. This allows layers to record the |
michael@0 | 466 | // attribute changes before new pixels arrive, which can be useful |
michael@0 | 467 | // for setting up back/front buffers. |
michael@0 | 468 | RenderTraceScope rendertrace2("Foward Transaction", "000092"); |
michael@0 | 469 | for (ShadowableLayerSet::const_iterator it = mTxn->mMutants.begin(); |
michael@0 | 470 | it != mTxn->mMutants.end(); ++it) { |
michael@0 | 471 | ShadowableLayer* shadow = *it; |
michael@0 | 472 | Layer* mutant = shadow->AsLayer(); |
michael@0 | 473 | NS_ABORT_IF_FALSE(!!mutant, "unshadowable layer?"); |
michael@0 | 474 | |
michael@0 | 475 | LayerAttributes attrs; |
michael@0 | 476 | CommonLayerAttributes& common = attrs.common(); |
michael@0 | 477 | common.visibleRegion() = mutant->GetVisibleRegion(); |
michael@0 | 478 | common.eventRegions() = mutant->GetEventRegions(); |
michael@0 | 479 | common.postXScale() = mutant->GetPostXScale(); |
michael@0 | 480 | common.postYScale() = mutant->GetPostYScale(); |
michael@0 | 481 | common.transform() = mutant->GetBaseTransform(); |
michael@0 | 482 | common.contentFlags() = mutant->GetContentFlags(); |
michael@0 | 483 | common.opacity() = mutant->GetOpacity(); |
michael@0 | 484 | common.useClipRect() = !!mutant->GetClipRect(); |
michael@0 | 485 | common.clipRect() = (common.useClipRect() ? |
michael@0 | 486 | *mutant->GetClipRect() : nsIntRect()); |
michael@0 | 487 | common.isFixedPosition() = mutant->GetIsFixedPosition(); |
michael@0 | 488 | common.fixedPositionAnchor() = mutant->GetFixedPositionAnchor(); |
michael@0 | 489 | common.fixedPositionMargin() = mutant->GetFixedPositionMargins(); |
michael@0 | 490 | common.isStickyPosition() = mutant->GetIsStickyPosition(); |
michael@0 | 491 | if (mutant->GetIsStickyPosition()) { |
michael@0 | 492 | common.stickyScrollContainerId() = mutant->GetStickyScrollContainerId(); |
michael@0 | 493 | common.stickyScrollRangeOuter() = mutant->GetStickyScrollRangeOuter(); |
michael@0 | 494 | common.stickyScrollRangeInner() = mutant->GetStickyScrollRangeInner(); |
michael@0 | 495 | } |
michael@0 | 496 | common.scrollbarTargetContainerId() = mutant->GetScrollbarTargetContainerId(); |
michael@0 | 497 | common.scrollbarDirection() = mutant->GetScrollbarDirection(); |
michael@0 | 498 | if (Layer* maskLayer = mutant->GetMaskLayer()) { |
michael@0 | 499 | common.maskLayerChild() = Shadow(maskLayer->AsShadowableLayer()); |
michael@0 | 500 | } else { |
michael@0 | 501 | common.maskLayerChild() = nullptr; |
michael@0 | 502 | } |
michael@0 | 503 | common.maskLayerParent() = nullptr; |
michael@0 | 504 | common.animations() = mutant->GetAnimations(); |
michael@0 | 505 | common.invalidRegion() = mutant->GetInvalidRegion(); |
michael@0 | 506 | attrs.specific() = null_t(); |
michael@0 | 507 | mutant->FillSpecificAttributes(attrs.specific()); |
michael@0 | 508 | |
michael@0 | 509 | MOZ_LAYERS_LOG(("[LayersForwarder] OpSetLayerAttributes(%p)\n", mutant)); |
michael@0 | 510 | |
michael@0 | 511 | mTxn->AddEdit(OpSetLayerAttributes(nullptr, Shadow(shadow), attrs)); |
michael@0 | 512 | } |
michael@0 | 513 | |
michael@0 | 514 | AutoInfallibleTArray<Edit, 10> cset; |
michael@0 | 515 | size_t nCsets = mTxn->mCset.size() + mTxn->mPaints.size(); |
michael@0 | 516 | NS_ABORT_IF_FALSE(nCsets > 0 || mWindowOverlayChanged, "should have bailed by now"); |
michael@0 | 517 | |
michael@0 | 518 | cset.SetCapacity(nCsets); |
michael@0 | 519 | if (!mTxn->mCset.empty()) { |
michael@0 | 520 | cset.AppendElements(&mTxn->mCset.front(), mTxn->mCset.size()); |
michael@0 | 521 | } |
michael@0 | 522 | // Paints after non-paint ops, including attribute changes. See |
michael@0 | 523 | // above. |
michael@0 | 524 | if (!mTxn->mPaints.empty()) { |
michael@0 | 525 | cset.AppendElements(&mTxn->mPaints.front(), mTxn->mPaints.size()); |
michael@0 | 526 | } |
michael@0 | 527 | |
michael@0 | 528 | mWindowOverlayChanged = false; |
michael@0 | 529 | |
michael@0 | 530 | TargetConfig targetConfig(mTxn->mTargetBounds, |
michael@0 | 531 | mTxn->mTargetRotation, |
michael@0 | 532 | mTxn->mClientBounds, |
michael@0 | 533 | mTxn->mTargetOrientation, |
michael@0 | 534 | aRegionToClear); |
michael@0 | 535 | |
michael@0 | 536 | MOZ_LAYERS_LOG(("[LayersForwarder] syncing before send...")); |
michael@0 | 537 | PlatformSyncBeforeUpdate(); |
michael@0 | 538 | |
michael@0 | 539 | profiler_tracing("Paint", "Rasterize", TRACING_INTERVAL_END); |
michael@0 | 540 | if (mTxn->mSwapRequired) { |
michael@0 | 541 | MOZ_LAYERS_LOG(("[LayersForwarder] sending transaction...")); |
michael@0 | 542 | RenderTraceScope rendertrace3("Forward Transaction", "000093"); |
michael@0 | 543 | if (!HasShadowManager() || |
michael@0 | 544 | !mShadowManager->IPCOpen() || |
michael@0 | 545 | !mShadowManager->SendUpdate(cset, targetConfig, mIsFirstPaint, |
michael@0 | 546 | aScheduleComposite, aReplies)) { |
michael@0 | 547 | MOZ_LAYERS_LOG(("[LayersForwarder] WARNING: sending transaction failed!")); |
michael@0 | 548 | return false; |
michael@0 | 549 | } |
michael@0 | 550 | } else { |
michael@0 | 551 | // If we don't require a swap we can call SendUpdateNoSwap which |
michael@0 | 552 | // assumes that aReplies is empty (DEBUG assertion) |
michael@0 | 553 | MOZ_LAYERS_LOG(("[LayersForwarder] sending no swap transaction...")); |
michael@0 | 554 | RenderTraceScope rendertrace3("Forward NoSwap Transaction", "000093"); |
michael@0 | 555 | if (!HasShadowManager() || |
michael@0 | 556 | !mShadowManager->IPCOpen() || |
michael@0 | 557 | !mShadowManager->SendUpdateNoSwap(cset, targetConfig, mIsFirstPaint, aScheduleComposite)) { |
michael@0 | 558 | MOZ_LAYERS_LOG(("[LayersForwarder] WARNING: sending transaction failed!")); |
michael@0 | 559 | return false; |
michael@0 | 560 | } |
michael@0 | 561 | } |
michael@0 | 562 | |
michael@0 | 563 | *aSent = true; |
michael@0 | 564 | mIsFirstPaint = false; |
michael@0 | 565 | MOZ_LAYERS_LOG(("[LayersForwarder] ... done")); |
michael@0 | 566 | return true; |
michael@0 | 567 | } |
michael@0 | 568 | |
michael@0 | 569 | bool |
michael@0 | 570 | ShadowLayerForwarder::AllocShmem(size_t aSize, |
michael@0 | 571 | ipc::SharedMemory::SharedMemoryType aType, |
michael@0 | 572 | ipc::Shmem* aShmem) |
michael@0 | 573 | { |
michael@0 | 574 | NS_ABORT_IF_FALSE(HasShadowManager(), "no shadow manager"); |
michael@0 | 575 | if (!mShadowManager->IPCOpen()) { |
michael@0 | 576 | return false; |
michael@0 | 577 | } |
michael@0 | 578 | return mShadowManager->AllocShmem(aSize, aType, aShmem); |
michael@0 | 579 | } |
michael@0 | 580 | bool |
michael@0 | 581 | ShadowLayerForwarder::AllocUnsafeShmem(size_t aSize, |
michael@0 | 582 | ipc::SharedMemory::SharedMemoryType aType, |
michael@0 | 583 | ipc::Shmem* aShmem) |
michael@0 | 584 | { |
michael@0 | 585 | NS_ABORT_IF_FALSE(HasShadowManager(), "no shadow manager"); |
michael@0 | 586 | if (!mShadowManager->IPCOpen()) { |
michael@0 | 587 | return false; |
michael@0 | 588 | } |
michael@0 | 589 | return mShadowManager->AllocUnsafeShmem(aSize, aType, aShmem); |
michael@0 | 590 | } |
michael@0 | 591 | void |
michael@0 | 592 | ShadowLayerForwarder::DeallocShmem(ipc::Shmem& aShmem) |
michael@0 | 593 | { |
michael@0 | 594 | NS_ABORT_IF_FALSE(HasShadowManager(), "no shadow manager"); |
michael@0 | 595 | if (!mShadowManager->IPCOpen()) { |
michael@0 | 596 | return; |
michael@0 | 597 | } |
michael@0 | 598 | mShadowManager->DeallocShmem(aShmem); |
michael@0 | 599 | } |
michael@0 | 600 | |
michael@0 | 601 | bool |
michael@0 | 602 | ShadowLayerForwarder::IPCOpen() const |
michael@0 | 603 | { |
michael@0 | 604 | return mShadowManager->IPCOpen(); |
michael@0 | 605 | } |
michael@0 | 606 | |
michael@0 | 607 | bool |
michael@0 | 608 | ShadowLayerForwarder::IsSameProcess() const |
michael@0 | 609 | { |
michael@0 | 610 | if (!mShadowManager->IPCOpen()) { |
michael@0 | 611 | return false; |
michael@0 | 612 | } |
michael@0 | 613 | return mShadowManager->OtherProcess() == kInvalidProcessHandle; |
michael@0 | 614 | } |
michael@0 | 615 | |
michael@0 | 616 | /** |
michael@0 | 617 | * We bail out when we have no shadow manager. That can happen when the |
michael@0 | 618 | * layer manager is created by the preallocated process. |
michael@0 | 619 | * See bug 914843 for details. |
michael@0 | 620 | */ |
michael@0 | 621 | PLayerChild* |
michael@0 | 622 | ShadowLayerForwarder::ConstructShadowFor(ShadowableLayer* aLayer) |
michael@0 | 623 | { |
michael@0 | 624 | NS_ABORT_IF_FALSE(HasShadowManager(), "no manager to forward to"); |
michael@0 | 625 | if (!mShadowManager->IPCOpen()) { |
michael@0 | 626 | return nullptr; |
michael@0 | 627 | } |
michael@0 | 628 | return mShadowManager->SendPLayerConstructor(new ShadowLayerChild(aLayer)); |
michael@0 | 629 | } |
michael@0 | 630 | |
michael@0 | 631 | #if !defined(MOZ_HAVE_PLATFORM_SPECIFIC_LAYER_BUFFERS) |
michael@0 | 632 | |
michael@0 | 633 | /*static*/ void |
michael@0 | 634 | ShadowLayerForwarder::PlatformSyncBeforeUpdate() |
michael@0 | 635 | { |
michael@0 | 636 | } |
michael@0 | 637 | |
michael@0 | 638 | #endif // !defined(MOZ_HAVE_PLATFORM_SPECIFIC_LAYER_BUFFERS) |
michael@0 | 639 | |
michael@0 | 640 | void |
michael@0 | 641 | ShadowLayerForwarder::Connect(CompositableClient* aCompositable) |
michael@0 | 642 | { |
michael@0 | 643 | #ifdef GFX_COMPOSITOR_LOGGING |
michael@0 | 644 | printf("ShadowLayerForwarder::Connect(Compositable)\n"); |
michael@0 | 645 | #endif |
michael@0 | 646 | MOZ_ASSERT(aCompositable); |
michael@0 | 647 | MOZ_ASSERT(mShadowManager); |
michael@0 | 648 | if (!mShadowManager->IPCOpen()) { |
michael@0 | 649 | return; |
michael@0 | 650 | } |
michael@0 | 651 | PCompositableChild* actor = |
michael@0 | 652 | mShadowManager->SendPCompositableConstructor(aCompositable->GetTextureInfo()); |
michael@0 | 653 | MOZ_ASSERT(actor); |
michael@0 | 654 | aCompositable->InitIPDLActor(actor); |
michael@0 | 655 | } |
michael@0 | 656 | |
michael@0 | 657 | void |
michael@0 | 658 | ShadowLayerForwarder::CreatedIncrementalBuffer(CompositableClient* aCompositable, |
michael@0 | 659 | const TextureInfo& aTextureInfo, |
michael@0 | 660 | const nsIntRect& aBufferRect) |
michael@0 | 661 | { |
michael@0 | 662 | MOZ_ASSERT(aCompositable); |
michael@0 | 663 | mTxn->AddNoSwapPaint(OpCreatedIncrementalTexture(nullptr, aCompositable->GetIPDLActor(), |
michael@0 | 664 | aTextureInfo, aBufferRect)); |
michael@0 | 665 | } |
michael@0 | 666 | |
michael@0 | 667 | void ShadowLayerForwarder::Attach(CompositableClient* aCompositable, |
michael@0 | 668 | ShadowableLayer* aLayer) |
michael@0 | 669 | { |
michael@0 | 670 | MOZ_ASSERT(aLayer); |
michael@0 | 671 | MOZ_ASSERT(aCompositable); |
michael@0 | 672 | MOZ_ASSERT(aCompositable->GetIPDLActor()); |
michael@0 | 673 | mTxn->AddEdit(OpAttachCompositable(nullptr, Shadow(aLayer), |
michael@0 | 674 | nullptr, aCompositable->GetIPDLActor())); |
michael@0 | 675 | } |
michael@0 | 676 | |
michael@0 | 677 | void ShadowLayerForwarder::AttachAsyncCompositable(uint64_t aCompositableID, |
michael@0 | 678 | ShadowableLayer* aLayer) |
michael@0 | 679 | { |
michael@0 | 680 | MOZ_ASSERT(aLayer); |
michael@0 | 681 | MOZ_ASSERT(aCompositableID != 0); // zero is always an invalid compositable id. |
michael@0 | 682 | mTxn->AddEdit(OpAttachAsyncCompositable(nullptr, Shadow(aLayer), |
michael@0 | 683 | aCompositableID)); |
michael@0 | 684 | } |
michael@0 | 685 | |
michael@0 | 686 | PTextureChild* |
michael@0 | 687 | ShadowLayerForwarder::CreateTexture(const SurfaceDescriptor& aSharedData, |
michael@0 | 688 | TextureFlags aFlags) |
michael@0 | 689 | { |
michael@0 | 690 | if (!mShadowManager->IPCOpen()) { |
michael@0 | 691 | return nullptr; |
michael@0 | 692 | } |
michael@0 | 693 | return mShadowManager->SendPTextureConstructor(aSharedData, aFlags); |
michael@0 | 694 | } |
michael@0 | 695 | |
michael@0 | 696 | |
michael@0 | 697 | void ShadowLayerForwarder::SetShadowManager(PLayerTransactionChild* aShadowManager) |
michael@0 | 698 | { |
michael@0 | 699 | mShadowManager = static_cast<LayerTransactionChild*>(aShadowManager); |
michael@0 | 700 | } |
michael@0 | 701 | |
michael@0 | 702 | |
michael@0 | 703 | } // namespace layers |
michael@0 | 704 | } // namespace mozilla |