2017-10-28 02:10:06 +03:00
|
|
|
/* -*- 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
|
2017-10-28 01:55:37 +03:00
|
|
|
* 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/. */
|
2017-06-24 00:23:12 +03:00
|
|
|
|
|
|
|
#include "PaintedLayerMLGPU.h"
|
|
|
|
#include "LayerManagerMLGPU.h"
|
|
|
|
#include "mozilla/layers/LayersHelpers.h"
|
2017-11-30 08:12:26 +03:00
|
|
|
#include "mozilla/layers/TiledContentHost.h"
|
2017-10-21 01:09:12 +03:00
|
|
|
#include "UnitTransforms.h"
|
2017-06-24 00:23:12 +03:00
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2017-11-30 08:12:25 +03:00
|
|
|
// Reset our cached texture pointers. The next call to AssignToView will
|
|
|
|
// populate them again.
|
|
|
|
mTexture = nullptr;
|
|
|
|
mTextureOnWhite = nullptr;
|
|
|
|
return !!mHost;
|
2017-08-02 01:40:32 +03:00
|
|
|
}
|
|
|
|
|
2017-10-21 01:09:12 +03:00
|
|
|
void
|
|
|
|
PaintedLayerMLGPU::SetRenderRegion(LayerIntRegion&& aRegion)
|
2017-08-02 01:40:32 +03:00
|
|
|
{
|
2017-10-21 01:09:12 +03:00
|
|
|
mRenderRegion = Move(aRegion);
|
2017-06-24 00:23:12 +03:00
|
|
|
|
2017-11-06 23:18:01 +03:00
|
|
|
LayerIntRect bounds(mRenderRegion.GetBounds().TopLeft(),
|
|
|
|
ViewAs<LayerPixel>(mTexture->GetSize()));
|
|
|
|
mRenderRegion.AndWith(bounds);
|
|
|
|
}
|
|
|
|
|
|
|
|
const LayerIntRegion&
|
|
|
|
PaintedLayerMLGPU::GetDrawRects()
|
|
|
|
{
|
2017-06-24 00:23:12 +03:00
|
|
|
#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()) {
|
2017-11-06 23:18:01 +03:00
|
|
|
mDrawRects = mRenderRegion.GetBounds();
|
|
|
|
return mDrawRects;
|
2017-10-20 21:52:56 +03:00
|
|
|
}
|
2017-10-21 01:09:12 +03:00
|
|
|
#endif
|
2017-11-06 23:18:01 +03:00
|
|
|
return mRenderRegion;
|
2017-06-24 00:23:12 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
PaintedLayerMLGPU::SetCompositableHost(CompositableHost* aHost)
|
|
|
|
{
|
|
|
|
switch (aHost->GetType()) {
|
2017-11-30 08:12:24 +03:00
|
|
|
case CompositableType::CONTENT_TILED:
|
2017-06-24 00:23:12 +03:00
|
|
|
case CompositableType::CONTENT_SINGLE:
|
|
|
|
case CompositableType::CONTENT_DOUBLE:
|
2017-11-30 08:12:24 +03:00
|
|
|
mHost = aHost->AsContentHost();
|
2017-06-24 00:23:12 +03:00
|
|
|
if (!mHost) {
|
|
|
|
gfxWarning() << "ContentHostBase is not a ContentHostTexture";
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
CompositableHost*
|
|
|
|
PaintedLayerMLGPU::GetCompositableHost()
|
|
|
|
{
|
|
|
|
return mHost;
|
|
|
|
}
|
|
|
|
|
2017-11-30 08:12:24 +03:00
|
|
|
gfx::Point
|
|
|
|
PaintedLayerMLGPU::GetDestOrigin() const
|
|
|
|
{
|
|
|
|
return mDestOrigin;
|
|
|
|
}
|
|
|
|
|
2017-11-30 08:12:25 +03:00
|
|
|
void
|
|
|
|
PaintedLayerMLGPU::AssignToView(FrameBuilder* aBuilder,
|
|
|
|
RenderViewMLGPU* aView,
|
|
|
|
Maybe<Polygon>&& aGeometry)
|
|
|
|
{
|
|
|
|
if (TiledContentHost* tiles = mHost->AsTiledContentHost()) {
|
2017-11-30 08:12:26 +03:00
|
|
|
// Note: we do not support the low-res buffer yet.
|
|
|
|
MOZ_ASSERT(tiles->GetLowResBuffer().GetTileCount() == 0);
|
|
|
|
AssignHighResTilesToView(aBuilder, aView, tiles, aGeometry);
|
2017-11-30 08:12:25 +03:00
|
|
|
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, Move(aGeometry));
|
|
|
|
}
|
|
|
|
|
2017-11-30 08:12:26 +03:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
TileIntPoint pos = aTiles.GetPlacement().TilePosition(i);
|
|
|
|
// A sanity check that catches a lot of mistakes.
|
|
|
|
MOZ_ASSERT(pos.x == tile.mTilePosition.x && pos.y == tile.mTilePosition.y);
|
|
|
|
|
|
|
|
IntPoint offset = aTiles.GetTileOffset(pos);
|
|
|
|
|
|
|
|
// 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, Move(geometry));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Restore the computed opacity and visible region.
|
|
|
|
mComputedOpacity = baseOpacity;
|
|
|
|
SetShadowVisibleRegion(Move(visible));
|
|
|
|
}
|
|
|
|
|
2017-06-24 00:23:12 +03:00
|
|
|
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
|