DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Header

Mercurial (d5efb485c09c)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "PaintedLayerMLGPU.h"
#include "LayerManagerMLGPU.h"
#include "mozilla/layers/LayersHelpers.h"
#include "mozilla/layers/TiledContentHost.h"
#include "UnitTransforms.h"

namespace mozilla {

using namespace gfx;

namespace layers {

PaintedLayerMLGPU::PaintedLayerMLGPU(LayerManagerMLGPU* aManager)
    : PaintedLayer(aManager, static_cast<HostLayer*>(this)),
      LayerMLGPU(aManager) {
  MOZ_COUNT_CTOR(PaintedLayerMLGPU);
}

PaintedLayerMLGPU::~PaintedLayerMLGPU() {
  MOZ_COUNT_DTOR(PaintedLayerMLGPU);

  CleanupResources();
}

bool PaintedLayerMLGPU::OnPrepareToRender(FrameBuilder* aBuilder) {
  // Reset our cached texture pointers. The next call to AssignToView will
  // populate them again.
  mTexture = nullptr;
  mTextureOnWhite = nullptr;
  return !!mHost;
}

void PaintedLayerMLGPU::SetRenderRegion(LayerIntRegion&& aRegion) {
  mRenderRegion = std::move(aRegion);

  LayerIntRect bounds(mRenderRegion.GetBounds().TopLeft(),
                      ViewAs<LayerPixel>(mTexture->GetSize()));
  mRenderRegion.AndWith(bounds);
}

const LayerIntRegion& PaintedLayerMLGPU::GetDrawRects() {
#ifndef MOZ_IGNORE_PAINT_WILL_RESAMPLE
  // Note: we don't set PaintWillResample on our ContentTextureHost. The old
  // compositor must do this since ContentHost is responsible for issuing
  // draw calls, but in AL we can handle it directly here.
  //
  // Note that when AL performs CPU-based occlusion culling (the default
  // behavior), we might break up the visible region again. If that turns
  // out to be a problem, we can factor this into ForEachDrawRect instead.
  if (MayResample()) {
    mDrawRects = mRenderRegion.GetBounds();
    return mDrawRects;
  }
#endif
  return mRenderRegion;
}

bool PaintedLayerMLGPU::SetCompositableHost(CompositableHost* aHost) {
  switch (aHost->GetType()) {
    case CompositableType::CONTENT_TILED:
    case CompositableType::CONTENT_SINGLE:
    case CompositableType::CONTENT_DOUBLE: {
      if (mHost && mHost != aHost->AsContentHost()) {
        mHost->Detach(this);
      }
      mHost = aHost->AsContentHost();
      if (!mHost) {
        gfxWarning() << "ContentHostBase is not a ContentHostTexture";
      }
      return true;
    }
    default:
      return false;
  }
}

CompositableHost* PaintedLayerMLGPU::GetCompositableHost() { return mHost; }

gfx::Point PaintedLayerMLGPU::GetDestOrigin() const { return mDestOrigin; }

void PaintedLayerMLGPU::AssignToView(FrameBuilder* aBuilder,
                                     RenderViewMLGPU* aView,
                                     Maybe<Polygon>&& aGeometry) {
  if (TiledContentHost* tiles = mHost->AsTiledContentHost()) {
    // Note: we do not support the low-res buffer yet.
    MOZ_ASSERT(tiles->GetLowResBuffer().GetTileCount() == 0);
    AssignHighResTilesToView(aBuilder, aView, tiles, aGeometry);
    return;
  }

  // If we don't have a texture yet, acquire one from the ContentHost now.
  if (!mTexture) {
    ContentHostTexture* single = mHost->AsContentHostTexture();
    if (!single) {
      return;
    }

    mTexture = single->AcquireTextureSource();
    if (!mTexture) {
      return;
    }
    mTextureOnWhite = single->AcquireTextureSourceOnWhite();
    mDestOrigin = single->GetOriginOffset();
  }

  // Fall through to the single texture case.
  LayerMLGPU::AssignToView(aBuilder, aView, std::move(aGeometry));
}

void PaintedLayerMLGPU::AssignHighResTilesToView(
    FrameBuilder* aBuilder, RenderViewMLGPU* aView, TiledContentHost* aTileHost,
    const Maybe<Polygon>& aGeometry) {
  TiledLayerBufferComposite& tiles = aTileHost->GetHighResBuffer();

  LayerIntRegion compositeRegion = ViewAs<LayerPixel>(tiles.GetValidRegion());
  compositeRegion.AndWith(GetShadowVisibleRegion());
  if (compositeRegion.IsEmpty()) {
    return;
  }

  AssignTileBufferToView(aBuilder, aView, tiles, compositeRegion, aGeometry);
}

void PaintedLayerMLGPU::AssignTileBufferToView(
    FrameBuilder* aBuilder, RenderViewMLGPU* aView,
    TiledLayerBufferComposite& aTiles, const LayerIntRegion& aCompositeRegion,
    const Maybe<Polygon>& aGeometry) {
  float resolution = aTiles.GetResolution();

  // Save these so they can be restored at the end.
  float baseOpacity = mComputedOpacity;
  LayerIntRegion visible = GetShadowVisibleRegion();

  for (size_t i = 0; i < aTiles.GetTileCount(); i++) {
    TileHost& tile = aTiles.GetTile(i);
    if (tile.IsPlaceholderTile()) {
      continue;
    }

    TileCoordIntPoint coord = aTiles.GetPlacement().TileCoord(i);
    // A sanity check that catches a lot of mistakes.
    MOZ_ASSERT(coord.x == tile.mTileCoord.x && coord.y == tile.mTileCoord.y);

    IntPoint offset = aTiles.GetTileOffset(coord);

    // Use LayerIntRect here so we don't have to keep re-allocating the region
    // to change the unit type.
    LayerIntRect tileRect(ViewAs<LayerPixel>(offset),
                          ViewAs<LayerPixel>(aTiles.GetScaledTileSize()));
    LayerIntRegion tileDrawRegion = tileRect;
    tileDrawRegion.AndWith(aCompositeRegion);
    if (tileDrawRegion.IsEmpty()) {
      continue;
    }
    tileDrawRegion.ScaleRoundOut(resolution, resolution);

    // Update layer state for this tile - that includes the texture, visible
    // region, and opacity.
    mTexture = tile.AcquireTextureSource();
    if (!mTexture) {
      continue;
    }

    mTextureOnWhite = tile.AcquireTextureSourceOnWhite();

    SetShadowVisibleRegion(tileDrawRegion);
    mComputedOpacity = tile.GetFadeInOpacity(baseOpacity);
    mDestOrigin = offset;

    // Yes, it's a bit weird that we're assigning the same layer to the same
    // view multiple times. Note that each time, the texture, computed
    // opacity, origin, and visible region are updated to match the current
    // tile, and we restore these properties after we've finished processing
    // all tiles.
    Maybe<Polygon> geometry = aGeometry;
    LayerMLGPU::AssignToView(aBuilder, aView, std::move(geometry));
  }

  // Restore the computed opacity and visible region.
  mComputedOpacity = baseOpacity;
  SetShadowVisibleRegion(std::move(visible));
}

void PaintedLayerMLGPU::CleanupResources() {
  if (mHost) {
    mHost->Detach(this);
  }
  mTexture = nullptr;
  mTextureOnWhite = nullptr;
  mHost = nullptr;
}

void PaintedLayerMLGPU::PrintInfo(std::stringstream& aStream,
                                  const char* aPrefix) {
  PaintedLayer::PrintInfo(aStream, aPrefix);
  if (mHost && mHost->IsAttached()) {
    aStream << "\n";
    nsAutoCString pfx(aPrefix);
    pfx += "  ";
    mHost->PrintInfo(aStream, pfx.get());
  }
}

void PaintedLayerMLGPU::Disconnect() { CleanupResources(); }

bool PaintedLayerMLGPU::IsContentOpaque() {
  return !!(GetContentFlags() & CONTENT_OPAQUE);
}

void PaintedLayerMLGPU::CleanupCachedResources() { CleanupResources(); }

}  // namespace layers
}  // namespace mozilla