gfx/layers/composite/TiledContentHost.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /* -*- Mode: C++; tab-width: 20; 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 "TiledContentHost.h"
michael@0 7 #include "ThebesLayerComposite.h" // for ThebesLayerComposite
michael@0 8 #include "mozilla/gfx/BaseSize.h" // for BaseSize
michael@0 9 #include "mozilla/gfx/Matrix.h" // for Matrix4x4
michael@0 10 #include "mozilla/layers/Compositor.h" // for Compositor
michael@0 11 #include "mozilla/layers/Effects.h" // for TexturedEffect, Effect, etc
michael@0 12 #include "mozilla/layers/TextureHostOGL.h" // for TextureHostOGL
michael@0 13 #include "nsAString.h"
michael@0 14 #include "nsDebug.h" // for NS_WARNING
michael@0 15 #include "nsPoint.h" // for nsIntPoint
michael@0 16 #include "nsPrintfCString.h" // for nsPrintfCString
michael@0 17 #include "nsRect.h" // for nsIntRect
michael@0 18 #include "nsSize.h" // for nsIntSize
michael@0 19 #include "mozilla/layers/TiledContentClient.h"
michael@0 20
michael@0 21 class gfxReusableSurfaceWrapper;
michael@0 22
michael@0 23 namespace mozilla {
michael@0 24 using namespace gfx;
michael@0 25 namespace layers {
michael@0 26
michael@0 27 class Layer;
michael@0 28
michael@0 29 TiledLayerBufferComposite::TiledLayerBufferComposite()
michael@0 30 : mFrameResolution(1.0)
michael@0 31 , mHasDoubleBufferedTiles(false)
michael@0 32 , mUninitialized(true)
michael@0 33 {}
michael@0 34
michael@0 35 /* static */ void
michael@0 36 TiledLayerBufferComposite::RecycleCallback(TextureHost* textureHost, void* aClosure)
michael@0 37 {
michael@0 38 textureHost->CompositorRecycle();
michael@0 39 }
michael@0 40
michael@0 41 TiledLayerBufferComposite::TiledLayerBufferComposite(ISurfaceAllocator* aAllocator,
michael@0 42 const SurfaceDescriptorTiles& aDescriptor,
michael@0 43 const nsIntRegion& aOldPaintedRegion)
michael@0 44 {
michael@0 45 mUninitialized = false;
michael@0 46 mHasDoubleBufferedTiles = false;
michael@0 47 mValidRegion = aDescriptor.validRegion();
michael@0 48 mPaintedRegion = aDescriptor.paintedRegion();
michael@0 49 mRetainedWidth = aDescriptor.retainedWidth();
michael@0 50 mRetainedHeight = aDescriptor.retainedHeight();
michael@0 51 mResolution = aDescriptor.resolution();
michael@0 52 mFrameResolution = CSSToParentLayerScale(aDescriptor.frameResolution());
michael@0 53
michael@0 54 // Combine any valid content that wasn't already uploaded
michael@0 55 nsIntRegion oldPaintedRegion(aOldPaintedRegion);
michael@0 56 oldPaintedRegion.And(oldPaintedRegion, mValidRegion);
michael@0 57 mPaintedRegion.Or(mPaintedRegion, oldPaintedRegion);
michael@0 58
michael@0 59 const InfallibleTArray<TileDescriptor>& tiles = aDescriptor.tiles();
michael@0 60 for(size_t i = 0; i < tiles.Length(); i++) {
michael@0 61 RefPtr<TextureHost> texture;
michael@0 62 const TileDescriptor& tileDesc = tiles[i];
michael@0 63 switch (tileDesc.type()) {
michael@0 64 case TileDescriptor::TTexturedTileDescriptor : {
michael@0 65 texture = TextureHost::AsTextureHost(tileDesc.get_TexturedTileDescriptor().textureParent());
michael@0 66 #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
michael@0 67 if (!gfxPrefs::LayersUseSimpleTiles()) {
michael@0 68 texture->SetRecycleCallback(RecycleCallback, nullptr);
michael@0 69 }
michael@0 70 #endif
michael@0 71 const TileLock& ipcLock = tileDesc.get_TexturedTileDescriptor().sharedLock();
michael@0 72 nsRefPtr<gfxSharedReadLock> sharedLock;
michael@0 73 if (ipcLock.type() == TileLock::TShmemSection) {
michael@0 74 sharedLock = gfxShmSharedReadLock::Open(aAllocator, ipcLock.get_ShmemSection());
michael@0 75 } else {
michael@0 76 sharedLock = reinterpret_cast<gfxMemorySharedReadLock*>(ipcLock.get_uintptr_t());
michael@0 77 if (sharedLock) {
michael@0 78 // The corresponding AddRef is in TiledClient::GetTileDescriptor
michael@0 79 sharedLock->Release();
michael@0 80 }
michael@0 81 }
michael@0 82
michael@0 83 mRetainedTiles.AppendElement(TileHost(sharedLock, texture));
michael@0 84 break;
michael@0 85 }
michael@0 86 default:
michael@0 87 NS_WARNING("Unrecognised tile descriptor type");
michael@0 88 // Fall through
michael@0 89 case TileDescriptor::TPlaceholderTileDescriptor :
michael@0 90 mRetainedTiles.AppendElement(GetPlaceholderTile());
michael@0 91 break;
michael@0 92 }
michael@0 93 if (texture && !texture->HasInternalBuffer()) {
michael@0 94 mHasDoubleBufferedTiles = true;
michael@0 95 }
michael@0 96 }
michael@0 97 }
michael@0 98
michael@0 99 void
michael@0 100 TiledLayerBufferComposite::ReadUnlock()
michael@0 101 {
michael@0 102 if (!IsValid()) {
michael@0 103 return;
michael@0 104 }
michael@0 105 for (size_t i = 0; i < mRetainedTiles.Length(); i++) {
michael@0 106 mRetainedTiles[i].ReadUnlock();
michael@0 107 }
michael@0 108 }
michael@0 109
michael@0 110 void
michael@0 111 TiledLayerBufferComposite::ReleaseTextureHosts()
michael@0 112 {
michael@0 113 if (!IsValid()) {
michael@0 114 return;
michael@0 115 }
michael@0 116 for (size_t i = 0; i < mRetainedTiles.Length(); i++) {
michael@0 117 mRetainedTiles[i].mTextureHost = nullptr;
michael@0 118 }
michael@0 119 }
michael@0 120
michael@0 121 void
michael@0 122 TiledLayerBufferComposite::Upload()
michael@0 123 {
michael@0 124 if(!IsValid()) {
michael@0 125 return;
michael@0 126 }
michael@0 127 // The TextureClients were created with the TEXTURE_IMMEDIATE_UPLOAD flag,
michael@0 128 // so calling Update on all the texture hosts will perform the texture upload.
michael@0 129 Update(mValidRegion, mPaintedRegion);
michael@0 130 ClearPaintedRegion();
michael@0 131 }
michael@0 132
michael@0 133 TileHost
michael@0 134 TiledLayerBufferComposite::ValidateTile(TileHost aTile,
michael@0 135 const nsIntPoint& aTileOrigin,
michael@0 136 const nsIntRegion& aDirtyRect)
michael@0 137 {
michael@0 138 if (aTile.IsPlaceholderTile()) {
michael@0 139 NS_WARNING("Placeholder tile encountered in painted region");
michael@0 140 return aTile;
michael@0 141 }
michael@0 142
michael@0 143 #ifdef GFX_TILEDLAYER_PREF_WARNINGS
michael@0 144 printf_stderr("Upload tile %i, %i\n", aTileOrigin.x, aTileOrigin.y);
michael@0 145 long start = PR_IntervalNow();
michael@0 146 #endif
michael@0 147
michael@0 148 MOZ_ASSERT(aTile.mTextureHost->GetFlags() & TEXTURE_IMMEDIATE_UPLOAD);
michael@0 149 // We possibly upload the entire texture contents here. This is a purposeful
michael@0 150 // decision, as sub-image upload can often be slow and/or unreliable, but
michael@0 151 // we may want to reevaluate this in the future.
michael@0 152 // For !HasInternalBuffer() textures, this is likely a no-op.
michael@0 153 aTile.mTextureHost->Updated(nullptr);
michael@0 154
michael@0 155 #ifdef GFX_TILEDLAYER_PREF_WARNINGS
michael@0 156 if (PR_IntervalNow() - start > 1) {
michael@0 157 printf_stderr("Tile Time to upload %i\n", PR_IntervalNow() - start);
michael@0 158 }
michael@0 159 #endif
michael@0 160 return aTile;
michael@0 161 }
michael@0 162
michael@0 163 void
michael@0 164 TiledLayerBufferComposite::SetCompositor(Compositor* aCompositor)
michael@0 165 {
michael@0 166 if (!IsValid()) {
michael@0 167 return;
michael@0 168 }
michael@0 169 for (size_t i = 0; i < mRetainedTiles.Length(); i++) {
michael@0 170 if (mRetainedTiles[i].IsPlaceholderTile()) continue;
michael@0 171 mRetainedTiles[i].mTextureHost->SetCompositor(aCompositor);
michael@0 172 }
michael@0 173 }
michael@0 174
michael@0 175 #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
michael@0 176 void
michael@0 177 TiledLayerBufferComposite::SetReleaseFence(const android::sp<android::Fence>& aReleaseFence)
michael@0 178 {
michael@0 179 for (size_t i = 0; i < mRetainedTiles.Length(); i++) {
michael@0 180 if (!mRetainedTiles[i].mTextureHost) {
michael@0 181 continue;
michael@0 182 }
michael@0 183 TextureHostOGL* texture = mRetainedTiles[i].mTextureHost->AsHostOGL();
michael@0 184 if (!texture) {
michael@0 185 continue;
michael@0 186 }
michael@0 187 texture->SetReleaseFence(new android::Fence(aReleaseFence->dup()));
michael@0 188 }
michael@0 189 }
michael@0 190 #endif
michael@0 191
michael@0 192 TiledContentHost::TiledContentHost(const TextureInfo& aTextureInfo)
michael@0 193 : ContentHost(aTextureInfo)
michael@0 194 , mTiledBuffer(TiledLayerBufferComposite())
michael@0 195 , mLowPrecisionTiledBuffer(TiledLayerBufferComposite())
michael@0 196 , mOldTiledBuffer(TiledLayerBufferComposite())
michael@0 197 , mOldLowPrecisionTiledBuffer(TiledLayerBufferComposite())
michael@0 198 , mPendingUpload(false)
michael@0 199 , mPendingLowPrecisionUpload(false)
michael@0 200 {
michael@0 201 MOZ_COUNT_CTOR(TiledContentHost);
michael@0 202 }
michael@0 203
michael@0 204 TiledContentHost::~TiledContentHost()
michael@0 205 {
michael@0 206 MOZ_COUNT_DTOR(TiledContentHost);
michael@0 207
michael@0 208 // Unlock any buffers that may still be locked. If we have a pending upload,
michael@0 209 // we will need to unlock the buffer that was about to be uploaded.
michael@0 210 // If a buffer that was being composited had double-buffered tiles, we will
michael@0 211 // need to unlock that buffer too.
michael@0 212 if (mPendingUpload) {
michael@0 213 mTiledBuffer.ReadUnlock();
michael@0 214 if (mOldTiledBuffer.HasDoubleBufferedTiles()) {
michael@0 215 mOldTiledBuffer.ReadUnlock();
michael@0 216 }
michael@0 217 } else if (mTiledBuffer.HasDoubleBufferedTiles()) {
michael@0 218 mTiledBuffer.ReadUnlock();
michael@0 219 }
michael@0 220
michael@0 221 if (mPendingLowPrecisionUpload) {
michael@0 222 mLowPrecisionTiledBuffer.ReadUnlock();
michael@0 223 if (mOldLowPrecisionTiledBuffer.HasDoubleBufferedTiles()) {
michael@0 224 mOldLowPrecisionTiledBuffer.ReadUnlock();
michael@0 225 }
michael@0 226 } else if (mLowPrecisionTiledBuffer.HasDoubleBufferedTiles()) {
michael@0 227 mLowPrecisionTiledBuffer.ReadUnlock();
michael@0 228 }
michael@0 229 }
michael@0 230
michael@0 231 void
michael@0 232 TiledContentHost::Attach(Layer* aLayer,
michael@0 233 Compositor* aCompositor,
michael@0 234 AttachFlags aFlags /* = NO_FLAGS */)
michael@0 235 {
michael@0 236 CompositableHost::Attach(aLayer, aCompositor, aFlags);
michael@0 237 static_cast<ThebesLayerComposite*>(aLayer)->EnsureTiled();
michael@0 238 }
michael@0 239
michael@0 240 void
michael@0 241 TiledContentHost::UseTiledLayerBuffer(ISurfaceAllocator* aAllocator,
michael@0 242 const SurfaceDescriptorTiles& aTiledDescriptor)
michael@0 243 {
michael@0 244 if (aTiledDescriptor.resolution() < 1) {
michael@0 245 if (mPendingLowPrecisionUpload) {
michael@0 246 mLowPrecisionTiledBuffer.ReadUnlock();
michael@0 247 } else {
michael@0 248 mPendingLowPrecisionUpload = true;
michael@0 249 // If the old buffer has double-buffered tiles, hang onto it so we can
michael@0 250 // unlock it after we've composited the new buffer.
michael@0 251 // We only need to hang onto the locks, but not the textures.
michael@0 252 // Releasing the textures here can help prevent a memory spike in the
michael@0 253 // situation that the client starts rendering new content before we get
michael@0 254 // to composite the new buffer.
michael@0 255 if (mLowPrecisionTiledBuffer.HasDoubleBufferedTiles()) {
michael@0 256 mOldLowPrecisionTiledBuffer = mLowPrecisionTiledBuffer;
michael@0 257 mOldLowPrecisionTiledBuffer.ReleaseTextureHosts();
michael@0 258 }
michael@0 259 }
michael@0 260 mLowPrecisionTiledBuffer =
michael@0 261 TiledLayerBufferComposite(aAllocator, aTiledDescriptor,
michael@0 262 mLowPrecisionTiledBuffer.GetPaintedRegion());
michael@0 263 } else {
michael@0 264 if (mPendingUpload) {
michael@0 265 mTiledBuffer.ReadUnlock();
michael@0 266 } else {
michael@0 267 mPendingUpload = true;
michael@0 268 if (mTiledBuffer.HasDoubleBufferedTiles()) {
michael@0 269 mOldTiledBuffer = mTiledBuffer;
michael@0 270 mOldTiledBuffer.ReleaseTextureHosts();
michael@0 271 }
michael@0 272 }
michael@0 273 mTiledBuffer = TiledLayerBufferComposite(aAllocator, aTiledDescriptor,
michael@0 274 mTiledBuffer.GetPaintedRegion());
michael@0 275 }
michael@0 276 }
michael@0 277
michael@0 278 void
michael@0 279 TiledContentHost::Composite(EffectChain& aEffectChain,
michael@0 280 float aOpacity,
michael@0 281 const gfx::Matrix4x4& aTransform,
michael@0 282 const gfx::Filter& aFilter,
michael@0 283 const gfx::Rect& aClipRect,
michael@0 284 const nsIntRegion* aVisibleRegion /* = nullptr */,
michael@0 285 TiledLayerProperties* aLayerProperties /* = nullptr */)
michael@0 286 {
michael@0 287 MOZ_ASSERT(aLayerProperties, "aLayerProperties required for TiledContentHost");
michael@0 288
michael@0 289 if (mPendingUpload) {
michael@0 290 mTiledBuffer.SetCompositor(mCompositor);
michael@0 291 mTiledBuffer.Upload();
michael@0 292
michael@0 293 // For a single-buffered tiled buffer, Upload will upload the shared memory
michael@0 294 // surface to texture memory and we no longer need to read from them.
michael@0 295 if (!mTiledBuffer.HasDoubleBufferedTiles()) {
michael@0 296 mTiledBuffer.ReadUnlock();
michael@0 297 }
michael@0 298 }
michael@0 299 if (mPendingLowPrecisionUpload) {
michael@0 300 mLowPrecisionTiledBuffer.SetCompositor(mCompositor);
michael@0 301 mLowPrecisionTiledBuffer.Upload();
michael@0 302
michael@0 303 if (!mLowPrecisionTiledBuffer.HasDoubleBufferedTiles()) {
michael@0 304 mLowPrecisionTiledBuffer.ReadUnlock();
michael@0 305 }
michael@0 306 }
michael@0 307
michael@0 308 RenderLayerBuffer(mLowPrecisionTiledBuffer, aEffectChain, aOpacity, aFilter,
michael@0 309 aClipRect, aLayerProperties->mVisibleRegion, aTransform);
michael@0 310 RenderLayerBuffer(mTiledBuffer, aEffectChain, aOpacity, aFilter,
michael@0 311 aClipRect, aLayerProperties->mVisibleRegion, aTransform);
michael@0 312
michael@0 313 // Now release the old buffer if it had double-buffered tiles, as we can
michael@0 314 // guarantee that they're no longer on the screen (and so any locks that may
michael@0 315 // have been held have been released).
michael@0 316 if (mPendingUpload && mOldTiledBuffer.HasDoubleBufferedTiles()) {
michael@0 317 mOldTiledBuffer.ReadUnlock();
michael@0 318 mOldTiledBuffer = TiledLayerBufferComposite();
michael@0 319 }
michael@0 320 if (mPendingLowPrecisionUpload && mOldLowPrecisionTiledBuffer.HasDoubleBufferedTiles()) {
michael@0 321 mOldLowPrecisionTiledBuffer.ReadUnlock();
michael@0 322 mOldLowPrecisionTiledBuffer = TiledLayerBufferComposite();
michael@0 323 }
michael@0 324 mPendingUpload = mPendingLowPrecisionUpload = false;
michael@0 325 }
michael@0 326
michael@0 327
michael@0 328 void
michael@0 329 TiledContentHost::RenderTile(const TileHost& aTile,
michael@0 330 EffectChain& aEffectChain,
michael@0 331 float aOpacity,
michael@0 332 const gfx::Matrix4x4& aTransform,
michael@0 333 const gfx::Filter& aFilter,
michael@0 334 const gfx::Rect& aClipRect,
michael@0 335 const nsIntRegion& aScreenRegion,
michael@0 336 const nsIntPoint& aTextureOffset,
michael@0 337 const nsIntSize& aTextureBounds)
michael@0 338 {
michael@0 339 if (aTile.IsPlaceholderTile()) {
michael@0 340 // This shouldn't ever happen, but let's fail semi-gracefully. No need
michael@0 341 // to warn, the texture update would have already caught this.
michael@0 342 return;
michael@0 343 }
michael@0 344
michael@0 345 nsIntRect screenBounds = aScreenRegion.GetBounds();
michael@0 346 Rect quad(screenBounds.x, screenBounds.y, screenBounds.width, screenBounds.height);
michael@0 347 quad = aTransform.TransformBounds(quad);
michael@0 348
michael@0 349 if (!quad.Intersects(mCompositor->ClipRectInLayersCoordinates(aClipRect))) {
michael@0 350 return;
michael@0 351 }
michael@0 352
michael@0 353 AutoLockTextureHost autoLock(aTile.mTextureHost);
michael@0 354 if (autoLock.Failed()) {
michael@0 355 NS_WARNING("Failed to lock tile");
michael@0 356 return;
michael@0 357 }
michael@0 358 RefPtr<NewTextureSource> source = aTile.mTextureHost->GetTextureSources();
michael@0 359 if (!source) {
michael@0 360 return;
michael@0 361 }
michael@0 362
michael@0 363 RefPtr<TexturedEffect> effect =
michael@0 364 CreateTexturedEffect(aTile.mTextureHost->GetFormat(), source, aFilter);
michael@0 365 if (!effect) {
michael@0 366 return;
michael@0 367 }
michael@0 368
michael@0 369 aEffectChain.mPrimaryEffect = effect;
michael@0 370
michael@0 371 nsIntRegionRectIterator it(aScreenRegion);
michael@0 372 for (const nsIntRect* rect = it.Next(); rect != nullptr; rect = it.Next()) {
michael@0 373 Rect graphicsRect(rect->x, rect->y, rect->width, rect->height);
michael@0 374 Rect textureRect(rect->x - aTextureOffset.x, rect->y - aTextureOffset.y,
michael@0 375 rect->width, rect->height);
michael@0 376
michael@0 377 effect->mTextureCoords = Rect(textureRect.x / aTextureBounds.width,
michael@0 378 textureRect.y / aTextureBounds.height,
michael@0 379 textureRect.width / aTextureBounds.width,
michael@0 380 textureRect.height / aTextureBounds.height);
michael@0 381 mCompositor->DrawQuad(graphicsRect, aClipRect, aEffectChain, aOpacity, aTransform);
michael@0 382 }
michael@0 383 mCompositor->DrawDiagnostics(DIAGNOSTIC_CONTENT|DIAGNOSTIC_TILE,
michael@0 384 aScreenRegion, aClipRect, aTransform, mFlashCounter);
michael@0 385 }
michael@0 386
michael@0 387 void
michael@0 388 TiledContentHost::RenderLayerBuffer(TiledLayerBufferComposite& aLayerBuffer,
michael@0 389 EffectChain& aEffectChain,
michael@0 390 float aOpacity,
michael@0 391 const gfx::Filter& aFilter,
michael@0 392 const gfx::Rect& aClipRect,
michael@0 393 nsIntRegion aVisibleRegion,
michael@0 394 gfx::Matrix4x4 aTransform)
michael@0 395 {
michael@0 396 if (!mCompositor) {
michael@0 397 NS_WARNING("Can't render tiled content host - no compositor");
michael@0 398 return;
michael@0 399 }
michael@0 400 float resolution = aLayerBuffer.GetResolution();
michael@0 401 gfx::Size layerScale(1, 1);
michael@0 402
michael@0 403 // We assume that the current frame resolution is the one used in our high
michael@0 404 // precision layer buffer. Compensate for a changing frame resolution when
michael@0 405 // rendering the low precision buffer.
michael@0 406 if (aLayerBuffer.GetFrameResolution() != mTiledBuffer.GetFrameResolution()) {
michael@0 407 const CSSToParentLayerScale& layerResolution = aLayerBuffer.GetFrameResolution();
michael@0 408 const CSSToParentLayerScale& localResolution = mTiledBuffer.GetFrameResolution();
michael@0 409 layerScale.width = layerScale.height = layerResolution.scale / localResolution.scale;
michael@0 410 aVisibleRegion.ScaleRoundOut(layerScale.width, layerScale.height);
michael@0 411 }
michael@0 412
michael@0 413 // If we're drawing the low precision buffer, make sure the high precision
michael@0 414 // buffer is masked out to avoid overdraw and rendering artifacts with
michael@0 415 // non-opaque layers.
michael@0 416 nsIntRegion maskRegion;
michael@0 417 if (resolution != mTiledBuffer.GetResolution()) {
michael@0 418 maskRegion = mTiledBuffer.GetValidRegion();
michael@0 419 // XXX This should be ScaleRoundIn, but there is no such function on
michael@0 420 // nsIntRegion.
michael@0 421 maskRegion.ScaleRoundOut(layerScale.width, layerScale.height);
michael@0 422 }
michael@0 423
michael@0 424 // Make sure the resolution and difference in frame resolution are accounted
michael@0 425 // for in the layer transform.
michael@0 426 aTransform.Scale(1/(resolution * layerScale.width),
michael@0 427 1/(resolution * layerScale.height), 1);
michael@0 428
michael@0 429 uint32_t rowCount = 0;
michael@0 430 uint32_t tileX = 0;
michael@0 431 nsIntRect visibleRect = aVisibleRegion.GetBounds();
michael@0 432 gfx::IntSize scaledTileSize = aLayerBuffer.GetScaledTileSize();
michael@0 433 for (int32_t x = visibleRect.x; x < visibleRect.x + visibleRect.width;) {
michael@0 434 rowCount++;
michael@0 435 int32_t tileStartX = aLayerBuffer.GetTileStart(x, scaledTileSize.width);
michael@0 436 int32_t w = scaledTileSize.width - tileStartX;
michael@0 437 if (x + w > visibleRect.x + visibleRect.width) {
michael@0 438 w = visibleRect.x + visibleRect.width - x;
michael@0 439 }
michael@0 440 int tileY = 0;
michael@0 441 for (int32_t y = visibleRect.y; y < visibleRect.y + visibleRect.height;) {
michael@0 442 int32_t tileStartY = aLayerBuffer.GetTileStart(y, scaledTileSize.height);
michael@0 443 int32_t h = scaledTileSize.height - tileStartY;
michael@0 444 if (y + h > visibleRect.y + visibleRect.height) {
michael@0 445 h = visibleRect.y + visibleRect.height - y;
michael@0 446 }
michael@0 447
michael@0 448 TileHost tileTexture = aLayerBuffer.
michael@0 449 GetTile(nsIntPoint(aLayerBuffer.RoundDownToTileEdge(x, scaledTileSize.width),
michael@0 450 aLayerBuffer.RoundDownToTileEdge(y, scaledTileSize.height)));
michael@0 451 if (tileTexture != aLayerBuffer.GetPlaceholderTile()) {
michael@0 452 nsIntRegion tileDrawRegion;
michael@0 453 tileDrawRegion.And(nsIntRect(x, y, w, h), aLayerBuffer.GetValidRegion());
michael@0 454 tileDrawRegion.And(tileDrawRegion, aVisibleRegion);
michael@0 455 tileDrawRegion.Sub(tileDrawRegion, maskRegion);
michael@0 456
michael@0 457 if (!tileDrawRegion.IsEmpty()) {
michael@0 458 tileDrawRegion.ScaleRoundOut(resolution, resolution);
michael@0 459 nsIntPoint tileOffset((x - tileStartX) * resolution,
michael@0 460 (y - tileStartY) * resolution);
michael@0 461 gfx::IntSize tileSize = aLayerBuffer.GetTileSize();
michael@0 462 RenderTile(tileTexture, aEffectChain, aOpacity, aTransform, aFilter, aClipRect, tileDrawRegion,
michael@0 463 tileOffset, nsIntSize(tileSize.width, tileSize.height));
michael@0 464 }
michael@0 465 }
michael@0 466 tileY++;
michael@0 467 y += h;
michael@0 468 }
michael@0 469 tileX++;
michael@0 470 x += w;
michael@0 471 }
michael@0 472 gfx::Rect rect(visibleRect.x, visibleRect.y,
michael@0 473 visibleRect.width, visibleRect.height);
michael@0 474 GetCompositor()->DrawDiagnostics(DIAGNOSTIC_CONTENT,
michael@0 475 rect, aClipRect, aTransform, mFlashCounter);
michael@0 476 }
michael@0 477
michael@0 478 void
michael@0 479 TiledContentHost::PrintInfo(nsACString& aTo, const char* aPrefix)
michael@0 480 {
michael@0 481 aTo += aPrefix;
michael@0 482 aTo += nsPrintfCString("TiledContentHost (0x%p)", this);
michael@0 483
michael@0 484 }
michael@0 485
michael@0 486 #ifdef MOZ_DUMP_PAINTING
michael@0 487 void
michael@0 488 TiledContentHost::Dump(FILE* aFile,
michael@0 489 const char* aPrefix,
michael@0 490 bool aDumpHtml)
michael@0 491 {
michael@0 492 if (!aFile) {
michael@0 493 aFile = stderr;
michael@0 494 }
michael@0 495
michael@0 496 TiledLayerBufferComposite::Iterator it = mTiledBuffer.TilesBegin();
michael@0 497 TiledLayerBufferComposite::Iterator stop = mTiledBuffer.TilesEnd();
michael@0 498 if (aDumpHtml) {
michael@0 499 fprintf_stderr(aFile, "<ul>");
michael@0 500 }
michael@0 501 for (;it != stop; ++it) {
michael@0 502 fprintf_stderr(aFile, "%s", aPrefix);
michael@0 503 fprintf_stderr(aFile, aDumpHtml ? "<li> <a href=" : "Tile ");
michael@0 504 if (it->IsPlaceholderTile()) {
michael@0 505 fprintf_stderr(aFile, "empty tile");
michael@0 506 } else {
michael@0 507 DumpTextureHost(aFile, it->mTextureHost);
michael@0 508 }
michael@0 509 fprintf_stderr(aFile, aDumpHtml ? " >Tile</a></li>" : " ");
michael@0 510 }
michael@0 511 if (aDumpHtml) {
michael@0 512 fprintf_stderr(aFile, "</ul>");
michael@0 513 }
michael@0 514 }
michael@0 515 #endif
michael@0 516
michael@0 517 } // namespace
michael@0 518 } // namespace

mercurial