1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/layers/composite/TiledContentHost.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,518 @@ 1.4 +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "TiledContentHost.h" 1.10 +#include "ThebesLayerComposite.h" // for ThebesLayerComposite 1.11 +#include "mozilla/gfx/BaseSize.h" // for BaseSize 1.12 +#include "mozilla/gfx/Matrix.h" // for Matrix4x4 1.13 +#include "mozilla/layers/Compositor.h" // for Compositor 1.14 +#include "mozilla/layers/Effects.h" // for TexturedEffect, Effect, etc 1.15 +#include "mozilla/layers/TextureHostOGL.h" // for TextureHostOGL 1.16 +#include "nsAString.h" 1.17 +#include "nsDebug.h" // for NS_WARNING 1.18 +#include "nsPoint.h" // for nsIntPoint 1.19 +#include "nsPrintfCString.h" // for nsPrintfCString 1.20 +#include "nsRect.h" // for nsIntRect 1.21 +#include "nsSize.h" // for nsIntSize 1.22 +#include "mozilla/layers/TiledContentClient.h" 1.23 + 1.24 +class gfxReusableSurfaceWrapper; 1.25 + 1.26 +namespace mozilla { 1.27 +using namespace gfx; 1.28 +namespace layers { 1.29 + 1.30 +class Layer; 1.31 + 1.32 +TiledLayerBufferComposite::TiledLayerBufferComposite() 1.33 + : mFrameResolution(1.0) 1.34 + , mHasDoubleBufferedTiles(false) 1.35 + , mUninitialized(true) 1.36 +{} 1.37 + 1.38 +/* static */ void 1.39 +TiledLayerBufferComposite::RecycleCallback(TextureHost* textureHost, void* aClosure) 1.40 +{ 1.41 + textureHost->CompositorRecycle(); 1.42 +} 1.43 + 1.44 +TiledLayerBufferComposite::TiledLayerBufferComposite(ISurfaceAllocator* aAllocator, 1.45 + const SurfaceDescriptorTiles& aDescriptor, 1.46 + const nsIntRegion& aOldPaintedRegion) 1.47 +{ 1.48 + mUninitialized = false; 1.49 + mHasDoubleBufferedTiles = false; 1.50 + mValidRegion = aDescriptor.validRegion(); 1.51 + mPaintedRegion = aDescriptor.paintedRegion(); 1.52 + mRetainedWidth = aDescriptor.retainedWidth(); 1.53 + mRetainedHeight = aDescriptor.retainedHeight(); 1.54 + mResolution = aDescriptor.resolution(); 1.55 + mFrameResolution = CSSToParentLayerScale(aDescriptor.frameResolution()); 1.56 + 1.57 + // Combine any valid content that wasn't already uploaded 1.58 + nsIntRegion oldPaintedRegion(aOldPaintedRegion); 1.59 + oldPaintedRegion.And(oldPaintedRegion, mValidRegion); 1.60 + mPaintedRegion.Or(mPaintedRegion, oldPaintedRegion); 1.61 + 1.62 + const InfallibleTArray<TileDescriptor>& tiles = aDescriptor.tiles(); 1.63 + for(size_t i = 0; i < tiles.Length(); i++) { 1.64 + RefPtr<TextureHost> texture; 1.65 + const TileDescriptor& tileDesc = tiles[i]; 1.66 + switch (tileDesc.type()) { 1.67 + case TileDescriptor::TTexturedTileDescriptor : { 1.68 + texture = TextureHost::AsTextureHost(tileDesc.get_TexturedTileDescriptor().textureParent()); 1.69 +#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17 1.70 + if (!gfxPrefs::LayersUseSimpleTiles()) { 1.71 + texture->SetRecycleCallback(RecycleCallback, nullptr); 1.72 + } 1.73 +#endif 1.74 + const TileLock& ipcLock = tileDesc.get_TexturedTileDescriptor().sharedLock(); 1.75 + nsRefPtr<gfxSharedReadLock> sharedLock; 1.76 + if (ipcLock.type() == TileLock::TShmemSection) { 1.77 + sharedLock = gfxShmSharedReadLock::Open(aAllocator, ipcLock.get_ShmemSection()); 1.78 + } else { 1.79 + sharedLock = reinterpret_cast<gfxMemorySharedReadLock*>(ipcLock.get_uintptr_t()); 1.80 + if (sharedLock) { 1.81 + // The corresponding AddRef is in TiledClient::GetTileDescriptor 1.82 + sharedLock->Release(); 1.83 + } 1.84 + } 1.85 + 1.86 + mRetainedTiles.AppendElement(TileHost(sharedLock, texture)); 1.87 + break; 1.88 + } 1.89 + default: 1.90 + NS_WARNING("Unrecognised tile descriptor type"); 1.91 + // Fall through 1.92 + case TileDescriptor::TPlaceholderTileDescriptor : 1.93 + mRetainedTiles.AppendElement(GetPlaceholderTile()); 1.94 + break; 1.95 + } 1.96 + if (texture && !texture->HasInternalBuffer()) { 1.97 + mHasDoubleBufferedTiles = true; 1.98 + } 1.99 + } 1.100 +} 1.101 + 1.102 +void 1.103 +TiledLayerBufferComposite::ReadUnlock() 1.104 +{ 1.105 + if (!IsValid()) { 1.106 + return; 1.107 + } 1.108 + for (size_t i = 0; i < mRetainedTiles.Length(); i++) { 1.109 + mRetainedTiles[i].ReadUnlock(); 1.110 + } 1.111 +} 1.112 + 1.113 +void 1.114 +TiledLayerBufferComposite::ReleaseTextureHosts() 1.115 +{ 1.116 + if (!IsValid()) { 1.117 + return; 1.118 + } 1.119 + for (size_t i = 0; i < mRetainedTiles.Length(); i++) { 1.120 + mRetainedTiles[i].mTextureHost = nullptr; 1.121 + } 1.122 +} 1.123 + 1.124 +void 1.125 +TiledLayerBufferComposite::Upload() 1.126 +{ 1.127 + if(!IsValid()) { 1.128 + return; 1.129 + } 1.130 + // The TextureClients were created with the TEXTURE_IMMEDIATE_UPLOAD flag, 1.131 + // so calling Update on all the texture hosts will perform the texture upload. 1.132 + Update(mValidRegion, mPaintedRegion); 1.133 + ClearPaintedRegion(); 1.134 +} 1.135 + 1.136 +TileHost 1.137 +TiledLayerBufferComposite::ValidateTile(TileHost aTile, 1.138 + const nsIntPoint& aTileOrigin, 1.139 + const nsIntRegion& aDirtyRect) 1.140 +{ 1.141 + if (aTile.IsPlaceholderTile()) { 1.142 + NS_WARNING("Placeholder tile encountered in painted region"); 1.143 + return aTile; 1.144 + } 1.145 + 1.146 +#ifdef GFX_TILEDLAYER_PREF_WARNINGS 1.147 + printf_stderr("Upload tile %i, %i\n", aTileOrigin.x, aTileOrigin.y); 1.148 + long start = PR_IntervalNow(); 1.149 +#endif 1.150 + 1.151 + MOZ_ASSERT(aTile.mTextureHost->GetFlags() & TEXTURE_IMMEDIATE_UPLOAD); 1.152 + // We possibly upload the entire texture contents here. This is a purposeful 1.153 + // decision, as sub-image upload can often be slow and/or unreliable, but 1.154 + // we may want to reevaluate this in the future. 1.155 + // For !HasInternalBuffer() textures, this is likely a no-op. 1.156 + aTile.mTextureHost->Updated(nullptr); 1.157 + 1.158 +#ifdef GFX_TILEDLAYER_PREF_WARNINGS 1.159 + if (PR_IntervalNow() - start > 1) { 1.160 + printf_stderr("Tile Time to upload %i\n", PR_IntervalNow() - start); 1.161 + } 1.162 +#endif 1.163 + return aTile; 1.164 +} 1.165 + 1.166 +void 1.167 +TiledLayerBufferComposite::SetCompositor(Compositor* aCompositor) 1.168 +{ 1.169 + if (!IsValid()) { 1.170 + return; 1.171 + } 1.172 + for (size_t i = 0; i < mRetainedTiles.Length(); i++) { 1.173 + if (mRetainedTiles[i].IsPlaceholderTile()) continue; 1.174 + mRetainedTiles[i].mTextureHost->SetCompositor(aCompositor); 1.175 + } 1.176 +} 1.177 + 1.178 +#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17 1.179 +void 1.180 +TiledLayerBufferComposite::SetReleaseFence(const android::sp<android::Fence>& aReleaseFence) 1.181 +{ 1.182 + for (size_t i = 0; i < mRetainedTiles.Length(); i++) { 1.183 + if (!mRetainedTiles[i].mTextureHost) { 1.184 + continue; 1.185 + } 1.186 + TextureHostOGL* texture = mRetainedTiles[i].mTextureHost->AsHostOGL(); 1.187 + if (!texture) { 1.188 + continue; 1.189 + } 1.190 + texture->SetReleaseFence(new android::Fence(aReleaseFence->dup())); 1.191 + } 1.192 +} 1.193 +#endif 1.194 + 1.195 +TiledContentHost::TiledContentHost(const TextureInfo& aTextureInfo) 1.196 + : ContentHost(aTextureInfo) 1.197 + , mTiledBuffer(TiledLayerBufferComposite()) 1.198 + , mLowPrecisionTiledBuffer(TiledLayerBufferComposite()) 1.199 + , mOldTiledBuffer(TiledLayerBufferComposite()) 1.200 + , mOldLowPrecisionTiledBuffer(TiledLayerBufferComposite()) 1.201 + , mPendingUpload(false) 1.202 + , mPendingLowPrecisionUpload(false) 1.203 +{ 1.204 + MOZ_COUNT_CTOR(TiledContentHost); 1.205 +} 1.206 + 1.207 +TiledContentHost::~TiledContentHost() 1.208 +{ 1.209 + MOZ_COUNT_DTOR(TiledContentHost); 1.210 + 1.211 + // Unlock any buffers that may still be locked. If we have a pending upload, 1.212 + // we will need to unlock the buffer that was about to be uploaded. 1.213 + // If a buffer that was being composited had double-buffered tiles, we will 1.214 + // need to unlock that buffer too. 1.215 + if (mPendingUpload) { 1.216 + mTiledBuffer.ReadUnlock(); 1.217 + if (mOldTiledBuffer.HasDoubleBufferedTiles()) { 1.218 + mOldTiledBuffer.ReadUnlock(); 1.219 + } 1.220 + } else if (mTiledBuffer.HasDoubleBufferedTiles()) { 1.221 + mTiledBuffer.ReadUnlock(); 1.222 + } 1.223 + 1.224 + if (mPendingLowPrecisionUpload) { 1.225 + mLowPrecisionTiledBuffer.ReadUnlock(); 1.226 + if (mOldLowPrecisionTiledBuffer.HasDoubleBufferedTiles()) { 1.227 + mOldLowPrecisionTiledBuffer.ReadUnlock(); 1.228 + } 1.229 + } else if (mLowPrecisionTiledBuffer.HasDoubleBufferedTiles()) { 1.230 + mLowPrecisionTiledBuffer.ReadUnlock(); 1.231 + } 1.232 +} 1.233 + 1.234 +void 1.235 +TiledContentHost::Attach(Layer* aLayer, 1.236 + Compositor* aCompositor, 1.237 + AttachFlags aFlags /* = NO_FLAGS */) 1.238 +{ 1.239 + CompositableHost::Attach(aLayer, aCompositor, aFlags); 1.240 + static_cast<ThebesLayerComposite*>(aLayer)->EnsureTiled(); 1.241 +} 1.242 + 1.243 +void 1.244 +TiledContentHost::UseTiledLayerBuffer(ISurfaceAllocator* aAllocator, 1.245 + const SurfaceDescriptorTiles& aTiledDescriptor) 1.246 +{ 1.247 + if (aTiledDescriptor.resolution() < 1) { 1.248 + if (mPendingLowPrecisionUpload) { 1.249 + mLowPrecisionTiledBuffer.ReadUnlock(); 1.250 + } else { 1.251 + mPendingLowPrecisionUpload = true; 1.252 + // If the old buffer has double-buffered tiles, hang onto it so we can 1.253 + // unlock it after we've composited the new buffer. 1.254 + // We only need to hang onto the locks, but not the textures. 1.255 + // Releasing the textures here can help prevent a memory spike in the 1.256 + // situation that the client starts rendering new content before we get 1.257 + // to composite the new buffer. 1.258 + if (mLowPrecisionTiledBuffer.HasDoubleBufferedTiles()) { 1.259 + mOldLowPrecisionTiledBuffer = mLowPrecisionTiledBuffer; 1.260 + mOldLowPrecisionTiledBuffer.ReleaseTextureHosts(); 1.261 + } 1.262 + } 1.263 + mLowPrecisionTiledBuffer = 1.264 + TiledLayerBufferComposite(aAllocator, aTiledDescriptor, 1.265 + mLowPrecisionTiledBuffer.GetPaintedRegion()); 1.266 + } else { 1.267 + if (mPendingUpload) { 1.268 + mTiledBuffer.ReadUnlock(); 1.269 + } else { 1.270 + mPendingUpload = true; 1.271 + if (mTiledBuffer.HasDoubleBufferedTiles()) { 1.272 + mOldTiledBuffer = mTiledBuffer; 1.273 + mOldTiledBuffer.ReleaseTextureHosts(); 1.274 + } 1.275 + } 1.276 + mTiledBuffer = TiledLayerBufferComposite(aAllocator, aTiledDescriptor, 1.277 + mTiledBuffer.GetPaintedRegion()); 1.278 + } 1.279 +} 1.280 + 1.281 +void 1.282 +TiledContentHost::Composite(EffectChain& aEffectChain, 1.283 + float aOpacity, 1.284 + const gfx::Matrix4x4& aTransform, 1.285 + const gfx::Filter& aFilter, 1.286 + const gfx::Rect& aClipRect, 1.287 + const nsIntRegion* aVisibleRegion /* = nullptr */, 1.288 + TiledLayerProperties* aLayerProperties /* = nullptr */) 1.289 +{ 1.290 + MOZ_ASSERT(aLayerProperties, "aLayerProperties required for TiledContentHost"); 1.291 + 1.292 + if (mPendingUpload) { 1.293 + mTiledBuffer.SetCompositor(mCompositor); 1.294 + mTiledBuffer.Upload(); 1.295 + 1.296 + // For a single-buffered tiled buffer, Upload will upload the shared memory 1.297 + // surface to texture memory and we no longer need to read from them. 1.298 + if (!mTiledBuffer.HasDoubleBufferedTiles()) { 1.299 + mTiledBuffer.ReadUnlock(); 1.300 + } 1.301 + } 1.302 + if (mPendingLowPrecisionUpload) { 1.303 + mLowPrecisionTiledBuffer.SetCompositor(mCompositor); 1.304 + mLowPrecisionTiledBuffer.Upload(); 1.305 + 1.306 + if (!mLowPrecisionTiledBuffer.HasDoubleBufferedTiles()) { 1.307 + mLowPrecisionTiledBuffer.ReadUnlock(); 1.308 + } 1.309 + } 1.310 + 1.311 + RenderLayerBuffer(mLowPrecisionTiledBuffer, aEffectChain, aOpacity, aFilter, 1.312 + aClipRect, aLayerProperties->mVisibleRegion, aTransform); 1.313 + RenderLayerBuffer(mTiledBuffer, aEffectChain, aOpacity, aFilter, 1.314 + aClipRect, aLayerProperties->mVisibleRegion, aTransform); 1.315 + 1.316 + // Now release the old buffer if it had double-buffered tiles, as we can 1.317 + // guarantee that they're no longer on the screen (and so any locks that may 1.318 + // have been held have been released). 1.319 + if (mPendingUpload && mOldTiledBuffer.HasDoubleBufferedTiles()) { 1.320 + mOldTiledBuffer.ReadUnlock(); 1.321 + mOldTiledBuffer = TiledLayerBufferComposite(); 1.322 + } 1.323 + if (mPendingLowPrecisionUpload && mOldLowPrecisionTiledBuffer.HasDoubleBufferedTiles()) { 1.324 + mOldLowPrecisionTiledBuffer.ReadUnlock(); 1.325 + mOldLowPrecisionTiledBuffer = TiledLayerBufferComposite(); 1.326 + } 1.327 + mPendingUpload = mPendingLowPrecisionUpload = false; 1.328 +} 1.329 + 1.330 + 1.331 +void 1.332 +TiledContentHost::RenderTile(const TileHost& aTile, 1.333 + EffectChain& aEffectChain, 1.334 + float aOpacity, 1.335 + const gfx::Matrix4x4& aTransform, 1.336 + const gfx::Filter& aFilter, 1.337 + const gfx::Rect& aClipRect, 1.338 + const nsIntRegion& aScreenRegion, 1.339 + const nsIntPoint& aTextureOffset, 1.340 + const nsIntSize& aTextureBounds) 1.341 +{ 1.342 + if (aTile.IsPlaceholderTile()) { 1.343 + // This shouldn't ever happen, but let's fail semi-gracefully. No need 1.344 + // to warn, the texture update would have already caught this. 1.345 + return; 1.346 + } 1.347 + 1.348 + nsIntRect screenBounds = aScreenRegion.GetBounds(); 1.349 + Rect quad(screenBounds.x, screenBounds.y, screenBounds.width, screenBounds.height); 1.350 + quad = aTransform.TransformBounds(quad); 1.351 + 1.352 + if (!quad.Intersects(mCompositor->ClipRectInLayersCoordinates(aClipRect))) { 1.353 + return; 1.354 + } 1.355 + 1.356 + AutoLockTextureHost autoLock(aTile.mTextureHost); 1.357 + if (autoLock.Failed()) { 1.358 + NS_WARNING("Failed to lock tile"); 1.359 + return; 1.360 + } 1.361 + RefPtr<NewTextureSource> source = aTile.mTextureHost->GetTextureSources(); 1.362 + if (!source) { 1.363 + return; 1.364 + } 1.365 + 1.366 + RefPtr<TexturedEffect> effect = 1.367 + CreateTexturedEffect(aTile.mTextureHost->GetFormat(), source, aFilter); 1.368 + if (!effect) { 1.369 + return; 1.370 + } 1.371 + 1.372 + aEffectChain.mPrimaryEffect = effect; 1.373 + 1.374 + nsIntRegionRectIterator it(aScreenRegion); 1.375 + for (const nsIntRect* rect = it.Next(); rect != nullptr; rect = it.Next()) { 1.376 + Rect graphicsRect(rect->x, rect->y, rect->width, rect->height); 1.377 + Rect textureRect(rect->x - aTextureOffset.x, rect->y - aTextureOffset.y, 1.378 + rect->width, rect->height); 1.379 + 1.380 + effect->mTextureCoords = Rect(textureRect.x / aTextureBounds.width, 1.381 + textureRect.y / aTextureBounds.height, 1.382 + textureRect.width / aTextureBounds.width, 1.383 + textureRect.height / aTextureBounds.height); 1.384 + mCompositor->DrawQuad(graphicsRect, aClipRect, aEffectChain, aOpacity, aTransform); 1.385 + } 1.386 + mCompositor->DrawDiagnostics(DIAGNOSTIC_CONTENT|DIAGNOSTIC_TILE, 1.387 + aScreenRegion, aClipRect, aTransform, mFlashCounter); 1.388 +} 1.389 + 1.390 +void 1.391 +TiledContentHost::RenderLayerBuffer(TiledLayerBufferComposite& aLayerBuffer, 1.392 + EffectChain& aEffectChain, 1.393 + float aOpacity, 1.394 + const gfx::Filter& aFilter, 1.395 + const gfx::Rect& aClipRect, 1.396 + nsIntRegion aVisibleRegion, 1.397 + gfx::Matrix4x4 aTransform) 1.398 +{ 1.399 + if (!mCompositor) { 1.400 + NS_WARNING("Can't render tiled content host - no compositor"); 1.401 + return; 1.402 + } 1.403 + float resolution = aLayerBuffer.GetResolution(); 1.404 + gfx::Size layerScale(1, 1); 1.405 + 1.406 + // We assume that the current frame resolution is the one used in our high 1.407 + // precision layer buffer. Compensate for a changing frame resolution when 1.408 + // rendering the low precision buffer. 1.409 + if (aLayerBuffer.GetFrameResolution() != mTiledBuffer.GetFrameResolution()) { 1.410 + const CSSToParentLayerScale& layerResolution = aLayerBuffer.GetFrameResolution(); 1.411 + const CSSToParentLayerScale& localResolution = mTiledBuffer.GetFrameResolution(); 1.412 + layerScale.width = layerScale.height = layerResolution.scale / localResolution.scale; 1.413 + aVisibleRegion.ScaleRoundOut(layerScale.width, layerScale.height); 1.414 + } 1.415 + 1.416 + // If we're drawing the low precision buffer, make sure the high precision 1.417 + // buffer is masked out to avoid overdraw and rendering artifacts with 1.418 + // non-opaque layers. 1.419 + nsIntRegion maskRegion; 1.420 + if (resolution != mTiledBuffer.GetResolution()) { 1.421 + maskRegion = mTiledBuffer.GetValidRegion(); 1.422 + // XXX This should be ScaleRoundIn, but there is no such function on 1.423 + // nsIntRegion. 1.424 + maskRegion.ScaleRoundOut(layerScale.width, layerScale.height); 1.425 + } 1.426 + 1.427 + // Make sure the resolution and difference in frame resolution are accounted 1.428 + // for in the layer transform. 1.429 + aTransform.Scale(1/(resolution * layerScale.width), 1.430 + 1/(resolution * layerScale.height), 1); 1.431 + 1.432 + uint32_t rowCount = 0; 1.433 + uint32_t tileX = 0; 1.434 + nsIntRect visibleRect = aVisibleRegion.GetBounds(); 1.435 + gfx::IntSize scaledTileSize = aLayerBuffer.GetScaledTileSize(); 1.436 + for (int32_t x = visibleRect.x; x < visibleRect.x + visibleRect.width;) { 1.437 + rowCount++; 1.438 + int32_t tileStartX = aLayerBuffer.GetTileStart(x, scaledTileSize.width); 1.439 + int32_t w = scaledTileSize.width - tileStartX; 1.440 + if (x + w > visibleRect.x + visibleRect.width) { 1.441 + w = visibleRect.x + visibleRect.width - x; 1.442 + } 1.443 + int tileY = 0; 1.444 + for (int32_t y = visibleRect.y; y < visibleRect.y + visibleRect.height;) { 1.445 + int32_t tileStartY = aLayerBuffer.GetTileStart(y, scaledTileSize.height); 1.446 + int32_t h = scaledTileSize.height - tileStartY; 1.447 + if (y + h > visibleRect.y + visibleRect.height) { 1.448 + h = visibleRect.y + visibleRect.height - y; 1.449 + } 1.450 + 1.451 + TileHost tileTexture = aLayerBuffer. 1.452 + GetTile(nsIntPoint(aLayerBuffer.RoundDownToTileEdge(x, scaledTileSize.width), 1.453 + aLayerBuffer.RoundDownToTileEdge(y, scaledTileSize.height))); 1.454 + if (tileTexture != aLayerBuffer.GetPlaceholderTile()) { 1.455 + nsIntRegion tileDrawRegion; 1.456 + tileDrawRegion.And(nsIntRect(x, y, w, h), aLayerBuffer.GetValidRegion()); 1.457 + tileDrawRegion.And(tileDrawRegion, aVisibleRegion); 1.458 + tileDrawRegion.Sub(tileDrawRegion, maskRegion); 1.459 + 1.460 + if (!tileDrawRegion.IsEmpty()) { 1.461 + tileDrawRegion.ScaleRoundOut(resolution, resolution); 1.462 + nsIntPoint tileOffset((x - tileStartX) * resolution, 1.463 + (y - tileStartY) * resolution); 1.464 + gfx::IntSize tileSize = aLayerBuffer.GetTileSize(); 1.465 + RenderTile(tileTexture, aEffectChain, aOpacity, aTransform, aFilter, aClipRect, tileDrawRegion, 1.466 + tileOffset, nsIntSize(tileSize.width, tileSize.height)); 1.467 + } 1.468 + } 1.469 + tileY++; 1.470 + y += h; 1.471 + } 1.472 + tileX++; 1.473 + x += w; 1.474 + } 1.475 + gfx::Rect rect(visibleRect.x, visibleRect.y, 1.476 + visibleRect.width, visibleRect.height); 1.477 + GetCompositor()->DrawDiagnostics(DIAGNOSTIC_CONTENT, 1.478 + rect, aClipRect, aTransform, mFlashCounter); 1.479 +} 1.480 + 1.481 +void 1.482 +TiledContentHost::PrintInfo(nsACString& aTo, const char* aPrefix) 1.483 +{ 1.484 + aTo += aPrefix; 1.485 + aTo += nsPrintfCString("TiledContentHost (0x%p)", this); 1.486 + 1.487 +} 1.488 + 1.489 +#ifdef MOZ_DUMP_PAINTING 1.490 +void 1.491 +TiledContentHost::Dump(FILE* aFile, 1.492 + const char* aPrefix, 1.493 + bool aDumpHtml) 1.494 +{ 1.495 + if (!aFile) { 1.496 + aFile = stderr; 1.497 + } 1.498 + 1.499 + TiledLayerBufferComposite::Iterator it = mTiledBuffer.TilesBegin(); 1.500 + TiledLayerBufferComposite::Iterator stop = mTiledBuffer.TilesEnd(); 1.501 + if (aDumpHtml) { 1.502 + fprintf_stderr(aFile, "<ul>"); 1.503 + } 1.504 + for (;it != stop; ++it) { 1.505 + fprintf_stderr(aFile, "%s", aPrefix); 1.506 + fprintf_stderr(aFile, aDumpHtml ? "<li> <a href=" : "Tile "); 1.507 + if (it->IsPlaceholderTile()) { 1.508 + fprintf_stderr(aFile, "empty tile"); 1.509 + } else { 1.510 + DumpTextureHost(aFile, it->mTextureHost); 1.511 + } 1.512 + fprintf_stderr(aFile, aDumpHtml ? " >Tile</a></li>" : " "); 1.513 + } 1.514 + if (aDumpHtml) { 1.515 + fprintf_stderr(aFile, "</ul>"); 1.516 + } 1.517 +} 1.518 +#endif 1.519 + 1.520 +} // namespace 1.521 +} // namespace