gecko-dev/gfx/layers/mlgpu/TexturedLayerMLGPU.cpp

212 строки
5.7 KiB
C++

/* -*- 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 "TexturedLayerMLGPU.h"
#include "LayerManagerMLGPU.h"
#include "RenderViewMLGPU.h"
#include "FrameBuilder.h"
#include "mozilla/gfx/Types.h"
#include "mozilla/layers/ImageHost.h"
#include "UnitTransforms.h"
namespace mozilla {
namespace layers {
using namespace gfx;
TexturedLayerMLGPU::TexturedLayerMLGPU(LayerManagerMLGPU* aManager)
: LayerMLGPU(aManager)
{
}
TexturedLayerMLGPU::~TexturedLayerMLGPU()
{
// Note: we have to cleanup resources in derived classes, since we can't
// easily tell in our destructor if we have a TempImageLayerMLGPU, which
// should not have its compositable detached, and we can't call GetLayer
// here.
}
bool
TexturedLayerMLGPU::SetCompositableHost(CompositableHost* aHost)
{
switch (aHost->GetType()) {
case CompositableType::IMAGE:
mHost = aHost->AsImageHost();
return true;
default:
return false;
}
}
CompositableHost*
TexturedLayerMLGPU::GetCompositableHost()
{
if (mHost && mHost->IsAttached()) {
return mHost.get();
}
return nullptr;
}
RefPtr<TextureSource>
TexturedLayerMLGPU::BindAndGetTexture()
{
if (!mHost) {
return nullptr;
}
LayerManagerMLGPU* lm = GetLayerManager()->AsLayerManagerMLGPU();
// Note: we don't call FinishRendering since mask layers do not need
// composite notifications or bias updates. (This function should
// not be called for non-mask-layers).
ImageHost::RenderInfo info;
if (!mHost->PrepareToRender(lm->GetTextureSourceProvider(), &info)) {
return nullptr;
}
RefPtr<TextureSource> source = mHost->AcquireTextureSource(info);
if (!source) {
return nullptr;
}
mTexture = source;
return source;
}
bool
TexturedLayerMLGPU::OnPrepareToRender(FrameBuilder* aBuilder)
{
if (!mHost) {
return false;
}
LayerManagerMLGPU* lm = GetLayerManager()->AsLayerManagerMLGPU();
ImageHost::RenderInfo info;
if (!mHost->PrepareToRender(lm->GetTextureSourceProvider(), &info)) {
return false;
}
RefPtr<TextureSource> source = mHost->AcquireTextureSource(info);
if (!source) {
return false;
}
if (source->AsBigImageIterator()) {
mBigImageTexture = source;
mTexture = nullptr;
} else {
mTexture = source;
}
mPictureRect = IntRect(0, 0, info.img->mPictureRect.Width(), info.img->mPictureRect.Height());
mHost->FinishRendering(info);
return true;
}
void
TexturedLayerMLGPU::AssignToView(FrameBuilder* aBuilder,
RenderViewMLGPU* aView,
Maybe<Polygon>&& aGeometry)
{
if (mBigImageTexture) {
BigImageIterator* iter = mBigImageTexture->AsBigImageIterator();
iter->BeginBigImageIteration();
AssignBigImage(aBuilder, aView, iter, aGeometry);
iter->EndBigImageIteration();
} else {
LayerMLGPU::AssignToView(aBuilder, aView, Move(aGeometry));
}
}
void
TexturedLayerMLGPU::AssignBigImage(FrameBuilder* aBuilder,
RenderViewMLGPU* aView,
BigImageIterator* aIter,
const Maybe<Polygon>& aGeometry)
{
const Matrix4x4& transform = GetLayer()->GetEffectiveTransformForBuffer();
// Note that we don't need to assign these in any particular order, since
// they do not overlap.
do {
IntRect tileRect = aIter->GetTileRect();
IntRect rect = tileRect.Intersect(mPictureRect);
if (rect.IsEmpty()) {
continue;
}
{
Rect screenRect = transform.TransformBounds(Rect(rect));
screenRect.MoveBy(-aView->GetTargetOffset());
screenRect = screenRect.Intersect(Rect(mComputedClipRect.ToUnknownRect()));
if (screenRect.IsEmpty()) {
// This tile is not in the clip region, so skip it.
continue;
}
}
RefPtr<TextureSource> tile = mBigImageTexture->ExtractCurrentTile();
if (!tile) {
continue;
}
// Create a temporary item.
RefPtr<TempImageLayerMLGPU> item = new TempImageLayerMLGPU(aBuilder->GetManager());
item->Init(this, tile, rect);
Maybe<Polygon> geometry = aGeometry;
item->AddBoundsToView(aBuilder, aView, Move(geometry));
// Since the layer tree is not holding this alive, we have to ask the
// FrameBuilder to do it for us.
aBuilder->RetainTemporaryLayer(item);
} while (aIter->NextTile());
}
TempImageLayerMLGPU::TempImageLayerMLGPU(LayerManagerMLGPU* aManager)
: ImageLayer(aManager, static_cast<HostLayer*>(this)),
TexturedLayerMLGPU(aManager)
{
}
TempImageLayerMLGPU::~TempImageLayerMLGPU()
{
}
void
TempImageLayerMLGPU::Init(TexturedLayerMLGPU* aSource,
const RefPtr<TextureSource>& aTexture,
const gfx::IntRect& aPictureRect)
{
// ImageLayer properties.
mEffectiveTransform = aSource->GetLayer()->GetEffectiveTransform();
mEffectiveTransformForBuffer = aSource->GetLayer()->GetEffectiveTransformForBuffer();
// Base LayerMLGPU properties.
mComputedClipRect = aSource->GetComputedClipRect();
mMask = aSource->GetMask();
mComputedOpacity = aSource->GetComputedOpacity();
// TexturedLayerMLGPU properties.
mHost = aSource->GetImageHost();
mTexture = aTexture;
mPictureRect = aPictureRect;
// Local properties.
mFilter = aSource->GetSamplingFilter();
mShadowVisibleRegion = aSource->GetShadowVisibleRegion();
mIsOpaque = aSource->IsContentOpaque();
// Set this layer to prepared so IsPrepared() assertions don't fire.
MarkPrepared();
}
} // namespace layers
} // namespace mozilla