gfx/layers/client/ClientLayerManager.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
michael@0 2 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #include "ClientLayerManager.h"
michael@0 7 #include "CompositorChild.h" // for CompositorChild
michael@0 8 #include "GeckoProfiler.h" // for PROFILER_LABEL
michael@0 9 #include "gfxPrefs.h" // for gfxPrefs::LayersTileWidth/Height
michael@0 10 #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
michael@0 11 #include "mozilla/Hal.h"
michael@0 12 #include "mozilla/dom/ScreenOrientation.h" // for ScreenOrientation
michael@0 13 #include "mozilla/dom/TabChild.h" // for TabChild
michael@0 14 #include "mozilla/hal_sandbox/PHal.h" // for ScreenConfiguration
michael@0 15 #include "mozilla/layers/CompositableClient.h"
michael@0 16 #include "mozilla/layers/ContentClient.h"
michael@0 17 #include "mozilla/layers/ISurfaceAllocator.h"
michael@0 18 #include "mozilla/layers/LayersMessages.h" // for EditReply, etc
michael@0 19 #include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor
michael@0 20 #include "mozilla/layers/PLayerChild.h" // for PLayerChild
michael@0 21 #include "mozilla/layers/LayerTransactionChild.h"
michael@0 22 #include "mozilla/layers/TextureClientPool.h" // for TextureClientPool
michael@0 23 #include "mozilla/layers/SimpleTextureClientPool.h" // for SimpleTextureClientPool
michael@0 24 #include "nsAString.h"
michael@0 25 #include "nsIWidget.h" // for nsIWidget
michael@0 26 #include "nsIWidgetListener.h"
michael@0 27 #include "nsTArray.h" // for AutoInfallibleTArray
michael@0 28 #include "nsXULAppAPI.h" // for XRE_GetProcessType, etc
michael@0 29 #include "TiledLayerBuffer.h"
michael@0 30 #ifdef MOZ_WIDGET_ANDROID
michael@0 31 #include "AndroidBridge.h"
michael@0 32 #endif
michael@0 33
michael@0 34 using namespace mozilla::dom;
michael@0 35 using namespace mozilla::gfx;
michael@0 36
michael@0 37 namespace mozilla {
michael@0 38 namespace layers {
michael@0 39
michael@0 40 ClientLayerManager::ClientLayerManager(nsIWidget* aWidget)
michael@0 41 : mPhase(PHASE_NONE)
michael@0 42 , mWidget(aWidget)
michael@0 43 , mTargetRotation(ROTATION_0)
michael@0 44 , mRepeatTransaction(false)
michael@0 45 , mIsRepeatTransaction(false)
michael@0 46 , mTransactionIncomplete(false)
michael@0 47 , mCompositorMightResample(false)
michael@0 48 , mNeedsComposite(false)
michael@0 49 , mForwarder(new ShadowLayerForwarder)
michael@0 50 {
michael@0 51 MOZ_COUNT_CTOR(ClientLayerManager);
michael@0 52 }
michael@0 53
michael@0 54 ClientLayerManager::~ClientLayerManager()
michael@0 55 {
michael@0 56 mRoot = nullptr;
michael@0 57
michael@0 58 MOZ_COUNT_DTOR(ClientLayerManager);
michael@0 59 }
michael@0 60
michael@0 61 int32_t
michael@0 62 ClientLayerManager::GetMaxTextureSize() const
michael@0 63 {
michael@0 64 return mForwarder->GetMaxTextureSize();
michael@0 65 }
michael@0 66
michael@0 67 void
michael@0 68 ClientLayerManager::SetDefaultTargetConfiguration(BufferMode aDoubleBuffering,
michael@0 69 ScreenRotation aRotation)
michael@0 70 {
michael@0 71 mTargetRotation = aRotation;
michael@0 72 if (mWidget) {
michael@0 73 mTargetBounds = mWidget->GetNaturalBounds();
michael@0 74 }
michael@0 75 }
michael@0 76
michael@0 77 void
michael@0 78 ClientLayerManager::SetRoot(Layer* aLayer)
michael@0 79 {
michael@0 80 if (mRoot != aLayer) {
michael@0 81 // Have to hold the old root and its children in order to
michael@0 82 // maintain the same view of the layer tree in this process as
michael@0 83 // the parent sees. Otherwise layers can be destroyed
michael@0 84 // mid-transaction and bad things can happen (v. bug 612573)
michael@0 85 if (mRoot) {
michael@0 86 Hold(mRoot);
michael@0 87 }
michael@0 88 mForwarder->SetRoot(Hold(aLayer));
michael@0 89 NS_ASSERTION(aLayer, "Root can't be null");
michael@0 90 NS_ASSERTION(aLayer->Manager() == this, "Wrong manager");
michael@0 91 NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
michael@0 92 mRoot = aLayer;
michael@0 93 }
michael@0 94 }
michael@0 95
michael@0 96 void
michael@0 97 ClientLayerManager::Mutated(Layer* aLayer)
michael@0 98 {
michael@0 99 LayerManager::Mutated(aLayer);
michael@0 100
michael@0 101 NS_ASSERTION(InConstruction() || InDrawing(), "wrong phase");
michael@0 102 mForwarder->Mutated(Hold(aLayer));
michael@0 103 }
michael@0 104
michael@0 105 void
michael@0 106 ClientLayerManager::BeginTransactionWithTarget(gfxContext* aTarget)
michael@0 107 {
michael@0 108 mInTransaction = true;
michael@0 109
michael@0 110 #ifdef MOZ_LAYERS_HAVE_LOG
michael@0 111 MOZ_LAYERS_LOG(("[----- BeginTransaction"));
michael@0 112 Log();
michael@0 113 #endif
michael@0 114
michael@0 115 NS_ASSERTION(!InTransaction(), "Nested transactions not allowed");
michael@0 116 mPhase = PHASE_CONSTRUCTION;
michael@0 117
michael@0 118 NS_ABORT_IF_FALSE(mKeepAlive.IsEmpty(), "uncommitted txn?");
michael@0 119 nsRefPtr<gfxContext> targetContext = aTarget;
michael@0 120
michael@0 121 // If the last transaction was incomplete (a failed DoEmptyTransaction),
michael@0 122 // don't signal a new transaction to ShadowLayerForwarder. Carry on adding
michael@0 123 // to the previous transaction.
michael@0 124 ScreenOrientation orientation;
michael@0 125 if (TabChild* window = mWidget->GetOwningTabChild()) {
michael@0 126 orientation = window->GetOrientation();
michael@0 127 } else {
michael@0 128 hal::ScreenConfiguration currentConfig;
michael@0 129 hal::GetCurrentScreenConfiguration(&currentConfig);
michael@0 130 orientation = currentConfig.orientation();
michael@0 131 }
michael@0 132 nsIntRect clientBounds;
michael@0 133 mWidget->GetClientBounds(clientBounds);
michael@0 134 clientBounds.x = clientBounds.y = 0;
michael@0 135 mForwarder->BeginTransaction(mTargetBounds, mTargetRotation, clientBounds, orientation);
michael@0 136
michael@0 137 // If we're drawing on behalf of a context with async pan/zoom
michael@0 138 // enabled, then the entire buffer of thebes layers might be
michael@0 139 // composited (including resampling) asynchronously before we get
michael@0 140 // a chance to repaint, so we have to ensure that it's all valid
michael@0 141 // and not rotated.
michael@0 142 if (mWidget) {
michael@0 143 if (TabChild* window = mWidget->GetOwningTabChild()) {
michael@0 144 mCompositorMightResample = window->IsAsyncPanZoomEnabled();
michael@0 145 }
michael@0 146 }
michael@0 147
michael@0 148 // If we have a non-default target, we need to let our shadow manager draw
michael@0 149 // to it. This will happen at the end of the transaction.
michael@0 150 if (aTarget && XRE_GetProcessType() == GeckoProcessType_Default) {
michael@0 151 mShadowTarget = aTarget;
michael@0 152 }
michael@0 153 }
michael@0 154
michael@0 155 void
michael@0 156 ClientLayerManager::BeginTransaction()
michael@0 157 {
michael@0 158 mInTransaction = true;
michael@0 159 BeginTransactionWithTarget(nullptr);
michael@0 160 }
michael@0 161
michael@0 162 bool
michael@0 163 ClientLayerManager::EndTransactionInternal(DrawThebesLayerCallback aCallback,
michael@0 164 void* aCallbackData,
michael@0 165 EndTransactionFlags)
michael@0 166 {
michael@0 167 PROFILER_LABEL("ClientLayerManager", "EndTransactionInternal");
michael@0 168 #ifdef MOZ_LAYERS_HAVE_LOG
michael@0 169 MOZ_LAYERS_LOG((" ----- (beginning paint)"));
michael@0 170 Log();
michael@0 171 #endif
michael@0 172 profiler_tracing("Paint", "Rasterize", TRACING_INTERVAL_START);
michael@0 173
michael@0 174 NS_ASSERTION(InConstruction(), "Should be in construction phase");
michael@0 175 mPhase = PHASE_DRAWING;
michael@0 176
michael@0 177 ClientLayer* root = ClientLayer::ToClientLayer(GetRoot());
michael@0 178
michael@0 179 mTransactionIncomplete = false;
michael@0 180
michael@0 181 // Apply pending tree updates before recomputing effective
michael@0 182 // properties.
michael@0 183 GetRoot()->ApplyPendingUpdatesToSubtree();
michael@0 184
michael@0 185 mThebesLayerCallback = aCallback;
michael@0 186 mThebesLayerCallbackData = aCallbackData;
michael@0 187
michael@0 188 GetRoot()->ComputeEffectiveTransforms(Matrix4x4());
michael@0 189
michael@0 190 root->RenderLayer();
michael@0 191 if (!mRepeatTransaction && !GetRoot()->GetInvalidRegion().IsEmpty()) {
michael@0 192 GetRoot()->Mutated();
michael@0 193 }
michael@0 194
michael@0 195 mThebesLayerCallback = nullptr;
michael@0 196 mThebesLayerCallbackData = nullptr;
michael@0 197
michael@0 198 // Go back to the construction phase if the transaction isn't complete.
michael@0 199 // Layout will update the layer tree and call EndTransaction().
michael@0 200 mPhase = mTransactionIncomplete ? PHASE_CONSTRUCTION : PHASE_NONE;
michael@0 201
michael@0 202 NS_ASSERTION(!aCallback || !mTransactionIncomplete,
michael@0 203 "If callback is not null, transaction must be complete");
michael@0 204
michael@0 205 return !mTransactionIncomplete;
michael@0 206 }
michael@0 207
michael@0 208 void
michael@0 209 ClientLayerManager::EndTransaction(DrawThebesLayerCallback aCallback,
michael@0 210 void* aCallbackData,
michael@0 211 EndTransactionFlags aFlags)
michael@0 212 {
michael@0 213 if (mWidget) {
michael@0 214 mWidget->PrepareWindowEffects();
michael@0 215 }
michael@0 216 EndTransactionInternal(aCallback, aCallbackData, aFlags);
michael@0 217 ForwardTransaction(!(aFlags & END_NO_REMOTE_COMPOSITE));
michael@0 218
michael@0 219 if (mRepeatTransaction) {
michael@0 220 mRepeatTransaction = false;
michael@0 221 mIsRepeatTransaction = true;
michael@0 222 BeginTransaction();
michael@0 223 ClientLayerManager::EndTransaction(aCallback, aCallbackData, aFlags);
michael@0 224 mIsRepeatTransaction = false;
michael@0 225 } else {
michael@0 226 MakeSnapshotIfRequired();
michael@0 227 }
michael@0 228
michael@0 229 for (size_t i = 0; i < mTexturePools.Length(); i++) {
michael@0 230 mTexturePools[i]->ReturnDeferredClients();
michael@0 231 }
michael@0 232 }
michael@0 233
michael@0 234 bool
michael@0 235 ClientLayerManager::EndEmptyTransaction(EndTransactionFlags aFlags)
michael@0 236 {
michael@0 237 mInTransaction = false;
michael@0 238
michael@0 239 if (!mRoot) {
michael@0 240 return false;
michael@0 241 }
michael@0 242 if (!EndTransactionInternal(nullptr, nullptr, aFlags)) {
michael@0 243 // Return without calling ForwardTransaction. This leaves the
michael@0 244 // ShadowLayerForwarder transaction open; the following
michael@0 245 // EndTransaction will complete it.
michael@0 246 return false;
michael@0 247 }
michael@0 248 if (mWidget) {
michael@0 249 mWidget->PrepareWindowEffects();
michael@0 250 }
michael@0 251 ForwardTransaction(!(aFlags & END_NO_REMOTE_COMPOSITE));
michael@0 252 MakeSnapshotIfRequired();
michael@0 253 return true;
michael@0 254 }
michael@0 255
michael@0 256 CompositorChild *
michael@0 257 ClientLayerManager::GetRemoteRenderer()
michael@0 258 {
michael@0 259 if (!mWidget) {
michael@0 260 return nullptr;
michael@0 261 }
michael@0 262
michael@0 263 return mWidget->GetRemoteRenderer();
michael@0 264 }
michael@0 265
michael@0 266 void
michael@0 267 ClientLayerManager::Composite()
michael@0 268 {
michael@0 269 if (LayerTransactionChild* manager = mForwarder->GetShadowManager()) {
michael@0 270 manager->SendForceComposite();
michael@0 271 }
michael@0 272 }
michael@0 273
michael@0 274 void
michael@0 275 ClientLayerManager::DidComposite()
michael@0 276 {
michael@0 277 MOZ_ASSERT(mWidget);
michael@0 278 nsIWidgetListener *listener = mWidget->GetWidgetListener();
michael@0 279 if (listener) {
michael@0 280 listener->DidCompositeWindow();
michael@0 281 }
michael@0 282 listener = mWidget->GetAttachedWidgetListener();
michael@0 283 if (listener) {
michael@0 284 listener->DidCompositeWindow();
michael@0 285 }
michael@0 286 }
michael@0 287
michael@0 288 void
michael@0 289 ClientLayerManager::MakeSnapshotIfRequired()
michael@0 290 {
michael@0 291 if (!mShadowTarget) {
michael@0 292 return;
michael@0 293 }
michael@0 294 if (mWidget) {
michael@0 295 if (CompositorChild* remoteRenderer = GetRemoteRenderer()) {
michael@0 296 nsIntRect bounds;
michael@0 297 mWidget->GetBounds(bounds);
michael@0 298 IntSize widgetSize = bounds.Size().ToIntSize();
michael@0 299 SurfaceDescriptor inSnapshot, snapshot;
michael@0 300 if (mForwarder->AllocSurfaceDescriptor(widgetSize,
michael@0 301 gfxContentType::COLOR_ALPHA,
michael@0 302 &inSnapshot) &&
michael@0 303 // The compositor will usually reuse |snapshot| and return
michael@0 304 // it through |outSnapshot|, but if it doesn't, it's
michael@0 305 // responsible for freeing |snapshot|.
michael@0 306 remoteRenderer->SendMakeSnapshot(inSnapshot, &snapshot)) {
michael@0 307 RefPtr<DataSourceSurface> surf = GetSurfaceForDescriptor(snapshot);
michael@0 308 DrawTarget* dt = mShadowTarget->GetDrawTarget();
michael@0 309 Rect widgetRect(Point(0, 0), Size(widgetSize.width, widgetSize.height));
michael@0 310 dt->DrawSurface(surf, widgetRect, widgetRect,
michael@0 311 DrawSurfaceOptions(),
michael@0 312 DrawOptions(1.0f, CompositionOp::OP_OVER));
michael@0 313 }
michael@0 314 if (IsSurfaceDescriptorValid(snapshot)) {
michael@0 315 mForwarder->DestroySharedSurface(&snapshot);
michael@0 316 }
michael@0 317 }
michael@0 318 }
michael@0 319 mShadowTarget = nullptr;
michael@0 320 }
michael@0 321
michael@0 322 void
michael@0 323 ClientLayerManager::FlushRendering()
michael@0 324 {
michael@0 325 if (mWidget) {
michael@0 326 if (CompositorChild* remoteRenderer = mWidget->GetRemoteRenderer()) {
michael@0 327 remoteRenderer->SendFlushRendering();
michael@0 328 }
michael@0 329 }
michael@0 330 }
michael@0 331
michael@0 332 void
michael@0 333 ClientLayerManager::SendInvalidRegion(const nsIntRegion& aRegion)
michael@0 334 {
michael@0 335 if (mWidget) {
michael@0 336 if (CompositorChild* remoteRenderer = mWidget->GetRemoteRenderer()) {
michael@0 337 remoteRenderer->SendNotifyRegionInvalidated(aRegion);
michael@0 338 }
michael@0 339 }
michael@0 340 }
michael@0 341
michael@0 342 uint32_t
michael@0 343 ClientLayerManager::StartFrameTimeRecording(int32_t aBufferSize)
michael@0 344 {
michael@0 345 CompositorChild* renderer = GetRemoteRenderer();
michael@0 346 if (renderer) {
michael@0 347 uint32_t startIndex;
michael@0 348 renderer->SendStartFrameTimeRecording(aBufferSize, &startIndex);
michael@0 349 return startIndex;
michael@0 350 }
michael@0 351 return -1;
michael@0 352 }
michael@0 353
michael@0 354 void
michael@0 355 ClientLayerManager::StopFrameTimeRecording(uint32_t aStartIndex,
michael@0 356 nsTArray<float>& aFrameIntervals)
michael@0 357 {
michael@0 358 CompositorChild* renderer = GetRemoteRenderer();
michael@0 359 if (renderer) {
michael@0 360 renderer->SendStopFrameTimeRecording(aStartIndex, &aFrameIntervals);
michael@0 361 }
michael@0 362 }
michael@0 363
michael@0 364 void
michael@0 365 ClientLayerManager::ForwardTransaction(bool aScheduleComposite)
michael@0 366 {
michael@0 367 mPhase = PHASE_FORWARD;
michael@0 368
michael@0 369 // forward this transaction's changeset to our LayerManagerComposite
michael@0 370 bool sent;
michael@0 371 AutoInfallibleTArray<EditReply, 10> replies;
michael@0 372 if (HasShadowManager() && mForwarder->EndTransaction(&replies, mRegionToClear, aScheduleComposite, &sent)) {
michael@0 373 for (nsTArray<EditReply>::size_type i = 0; i < replies.Length(); ++i) {
michael@0 374 const EditReply& reply = replies[i];
michael@0 375
michael@0 376 switch (reply.type()) {
michael@0 377 case EditReply::TOpContentBufferSwap: {
michael@0 378 MOZ_LAYERS_LOG(("[LayersForwarder] DoubleBufferSwap"));
michael@0 379
michael@0 380 const OpContentBufferSwap& obs = reply.get_OpContentBufferSwap();
michael@0 381
michael@0 382 CompositableClient* compositable =
michael@0 383 CompositableClient::FromIPDLActor(obs.compositableChild());
michael@0 384 ContentClientRemote* contentClient =
michael@0 385 static_cast<ContentClientRemote*>(compositable);
michael@0 386 MOZ_ASSERT(contentClient);
michael@0 387
michael@0 388 contentClient->SwapBuffers(obs.frontUpdatedRegion());
michael@0 389
michael@0 390 break;
michael@0 391 }
michael@0 392 case EditReply::TOpTextureSwap: {
michael@0 393 MOZ_LAYERS_LOG(("[LayersForwarder] TextureSwap"));
michael@0 394
michael@0 395 const OpTextureSwap& ots = reply.get_OpTextureSwap();
michael@0 396
michael@0 397 CompositableClient* compositable =
michael@0 398 CompositableClient::FromIPDLActor(ots.compositableChild());
michael@0 399 MOZ_ASSERT(compositable);
michael@0 400 compositable->SetDescriptorFromReply(ots.textureId(), ots.image());
michael@0 401 break;
michael@0 402 }
michael@0 403 case EditReply::TReturnReleaseFence: {
michael@0 404 const ReturnReleaseFence& rep = reply.get_ReturnReleaseFence();
michael@0 405 FenceHandle fence = rep.fence();
michael@0 406 PTextureChild* child = rep.textureChild();
michael@0 407
michael@0 408 if (!fence.IsValid() || !child) {
michael@0 409 break;
michael@0 410 }
michael@0 411 RefPtr<TextureClient> texture = TextureClient::AsTextureClient(child);
michael@0 412 if (texture) {
michael@0 413 texture->SetReleaseFenceHandle(fence);
michael@0 414 }
michael@0 415 break;
michael@0 416 }
michael@0 417
michael@0 418 default:
michael@0 419 NS_RUNTIMEABORT("not reached");
michael@0 420 }
michael@0 421 }
michael@0 422
michael@0 423 if (sent) {
michael@0 424 mNeedsComposite = false;
michael@0 425 }
michael@0 426 } else if (HasShadowManager()) {
michael@0 427 NS_WARNING("failed to forward Layers transaction");
michael@0 428 }
michael@0 429
michael@0 430 mForwarder->RemoveTexturesIfNecessary();
michael@0 431 mPhase = PHASE_NONE;
michael@0 432
michael@0 433 // this may result in Layers being deleted, which results in
michael@0 434 // PLayer::Send__delete__() and DeallocShmem()
michael@0 435 mKeepAlive.Clear();
michael@0 436 }
michael@0 437
michael@0 438 ShadowableLayer*
michael@0 439 ClientLayerManager::Hold(Layer* aLayer)
michael@0 440 {
michael@0 441 NS_ABORT_IF_FALSE(HasShadowManager(),
michael@0 442 "top-level tree, no shadow tree to remote to");
michael@0 443
michael@0 444 ShadowableLayer* shadowable = ClientLayer::ToClientLayer(aLayer);
michael@0 445 NS_ABORT_IF_FALSE(shadowable, "trying to remote an unshadowable layer");
michael@0 446
michael@0 447 mKeepAlive.AppendElement(aLayer);
michael@0 448 return shadowable;
michael@0 449 }
michael@0 450
michael@0 451 bool
michael@0 452 ClientLayerManager::IsCompositingCheap()
michael@0 453 {
michael@0 454 // Whether compositing is cheap depends on the parent backend.
michael@0 455 return mForwarder->mShadowManager &&
michael@0 456 LayerManager::IsCompositingCheap(mForwarder->GetCompositorBackendType());
michael@0 457 }
michael@0 458
michael@0 459 void
michael@0 460 ClientLayerManager::SetIsFirstPaint()
michael@0 461 {
michael@0 462 mForwarder->SetIsFirstPaint();
michael@0 463 }
michael@0 464
michael@0 465 TextureClientPool*
michael@0 466 ClientLayerManager::GetTexturePool(SurfaceFormat aFormat)
michael@0 467 {
michael@0 468 for (size_t i = 0; i < mTexturePools.Length(); i++) {
michael@0 469 if (mTexturePools[i]->GetFormat() == aFormat) {
michael@0 470 return mTexturePools[i];
michael@0 471 }
michael@0 472 }
michael@0 473
michael@0 474 mTexturePools.AppendElement(
michael@0 475 new TextureClientPool(aFormat, IntSize(gfxPrefs::LayersTileWidth(),
michael@0 476 gfxPrefs::LayersTileHeight()),
michael@0 477 mForwarder));
michael@0 478
michael@0 479 return mTexturePools.LastElement();
michael@0 480 }
michael@0 481
michael@0 482 SimpleTextureClientPool*
michael@0 483 ClientLayerManager::GetSimpleTileTexturePool(SurfaceFormat aFormat)
michael@0 484 {
michael@0 485 int index = (int) aFormat;
michael@0 486 mSimpleTilePools.EnsureLengthAtLeast(index+1);
michael@0 487
michael@0 488 if (mSimpleTilePools[index].get() == nullptr) {
michael@0 489 mSimpleTilePools[index] = new SimpleTextureClientPool(aFormat, IntSize(gfxPrefs::LayersTileWidth(),
michael@0 490 gfxPrefs::LayersTileHeight()),
michael@0 491 mForwarder);
michael@0 492 }
michael@0 493
michael@0 494 return mSimpleTilePools[index];
michael@0 495 }
michael@0 496
michael@0 497 void
michael@0 498 ClientLayerManager::ClearCachedResources(Layer* aSubtree)
michael@0 499 {
michael@0 500 MOZ_ASSERT(!HasShadowManager() || !aSubtree);
michael@0 501 if (LayerTransactionChild* manager = mForwarder->GetShadowManager()) {
michael@0 502 manager->SendClearCachedResources();
michael@0 503 }
michael@0 504 if (aSubtree) {
michael@0 505 ClearLayer(aSubtree);
michael@0 506 } else if (mRoot) {
michael@0 507 ClearLayer(mRoot);
michael@0 508 }
michael@0 509 for (size_t i = 0; i < mTexturePools.Length(); i++) {
michael@0 510 mTexturePools[i]->Clear();
michael@0 511 }
michael@0 512 }
michael@0 513
michael@0 514 void
michael@0 515 ClientLayerManager::ClearLayer(Layer* aLayer)
michael@0 516 {
michael@0 517 ClientLayer::ToClientLayer(aLayer)->ClearCachedResources();
michael@0 518 for (Layer* child = aLayer->GetFirstChild(); child;
michael@0 519 child = child->GetNextSibling()) {
michael@0 520 ClearLayer(child);
michael@0 521 }
michael@0 522 }
michael@0 523
michael@0 524 void
michael@0 525 ClientLayerManager::GetBackendName(nsAString& aName)
michael@0 526 {
michael@0 527 switch (mForwarder->GetCompositorBackendType()) {
michael@0 528 case LayersBackend::LAYERS_BASIC: aName.AssignLiteral("Basic"); return;
michael@0 529 case LayersBackend::LAYERS_OPENGL: aName.AssignLiteral("OpenGL"); return;
michael@0 530 case LayersBackend::LAYERS_D3D9: aName.AssignLiteral("Direct3D 9"); return;
michael@0 531 case LayersBackend::LAYERS_D3D10: aName.AssignLiteral("Direct3D 10"); return;
michael@0 532 case LayersBackend::LAYERS_D3D11: aName.AssignLiteral("Direct3D 11"); return;
michael@0 533 default: NS_RUNTIMEABORT("Invalid backend");
michael@0 534 }
michael@0 535 }
michael@0 536
michael@0 537 bool
michael@0 538 ClientLayerManager::ProgressiveUpdateCallback(bool aHasPendingNewThebesContent,
michael@0 539 ParentLayerRect& aCompositionBounds,
michael@0 540 CSSToParentLayerScale& aZoom,
michael@0 541 bool aDrawingCritical)
michael@0 542 {
michael@0 543 aZoom.scale = 1.0;
michael@0 544 #ifdef MOZ_WIDGET_ANDROID
michael@0 545 Layer* primaryScrollable = GetPrimaryScrollableLayer();
michael@0 546 if (primaryScrollable) {
michael@0 547 const FrameMetrics& metrics = primaryScrollable->AsContainerLayer()->GetFrameMetrics();
michael@0 548
michael@0 549 // This is derived from the code in
michael@0 550 // gfx/layers/ipc/CompositorParent.cpp::TransformShadowTree.
michael@0 551 CSSToLayerScale paintScale = metrics.LayersPixelsPerCSSPixel();
michael@0 552 const CSSRect& metricsDisplayPort =
michael@0 553 (aDrawingCritical && !metrics.mCriticalDisplayPort.IsEmpty()) ?
michael@0 554 metrics.mCriticalDisplayPort : metrics.mDisplayPort;
michael@0 555 LayerRect displayPort = (metricsDisplayPort + metrics.GetScrollOffset()) * paintScale;
michael@0 556
michael@0 557 return AndroidBridge::Bridge()->ProgressiveUpdateCallback(
michael@0 558 aHasPendingNewThebesContent, displayPort, paintScale.scale, aDrawingCritical,
michael@0 559 aCompositionBounds, aZoom);
michael@0 560 }
michael@0 561 #endif
michael@0 562
michael@0 563 return false;
michael@0 564 }
michael@0 565
michael@0 566 ClientLayer::~ClientLayer()
michael@0 567 {
michael@0 568 if (HasShadow()) {
michael@0 569 PLayerChild::Send__delete__(GetShadow());
michael@0 570 }
michael@0 571 MOZ_COUNT_DTOR(ClientLayer);
michael@0 572 }
michael@0 573
michael@0 574 }
michael@0 575 }

mercurial