mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-07 12:15:51 +00:00
80b67114ce
1. Support GenEffectChain() for LayerComposite. Each layer can use this API to gen the EffectChain (only primary effect now) 2. Support GenEffect() for CompositableHost. 3. Move AutoLock to compositeHost.
191 lines
5.5 KiB
C++
191 lines
5.5 KiB
C++
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
* 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 "ImageLayerComposite.h"
|
|
#include "CompositableHost.h" // for CompositableHost
|
|
#include "Layers.h" // for WriteSnapshotToDumpFile, etc
|
|
#include "gfx2DGlue.h" // for ToFilter, ToMatrix4x4
|
|
#include "gfxRect.h" // for gfxRect
|
|
#include "gfxUtils.h" // for gfxUtils, etc
|
|
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
|
|
#include "mozilla/gfx/Matrix.h" // for Matrix4x4
|
|
#include "mozilla/gfx/Point.h" // for IntSize, Point
|
|
#include "mozilla/gfx/Rect.h" // for Rect
|
|
#include "mozilla/layers/Compositor.h" // for Compositor
|
|
#include "mozilla/layers/Effects.h" // for EffectChain
|
|
#include "mozilla/layers/TextureHost.h" // for TextureHost, etc
|
|
#include "mozilla/mozalloc.h" // for operator delete
|
|
#include "nsAString.h"
|
|
#include "nsAutoPtr.h" // for nsRefPtr
|
|
#include "nsDebug.h" // for NS_ASSERTION
|
|
#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
|
|
#include "nsPoint.h" // for nsIntPoint
|
|
#include "nsRect.h" // for nsIntRect
|
|
#include "nsString.h" // for nsAutoCString
|
|
|
|
namespace mozilla {
|
|
namespace layers {
|
|
|
|
using namespace mozilla::gfx;
|
|
|
|
ImageLayerComposite::ImageLayerComposite(LayerManagerComposite* aManager)
|
|
: ImageLayer(aManager, nullptr)
|
|
, LayerComposite(aManager)
|
|
, mImageHost(nullptr)
|
|
{
|
|
MOZ_COUNT_CTOR(ImageLayerComposite);
|
|
mImplData = static_cast<LayerComposite*>(this);
|
|
}
|
|
|
|
ImageLayerComposite::~ImageLayerComposite()
|
|
{
|
|
MOZ_COUNT_DTOR(ImageLayerComposite);
|
|
MOZ_ASSERT(mDestroyed);
|
|
|
|
CleanupResources();
|
|
}
|
|
|
|
bool
|
|
ImageLayerComposite::SetCompositableHost(CompositableHost* aHost)
|
|
{
|
|
switch (aHost->GetType()) {
|
|
case CompositableType::BUFFER_IMAGE_SINGLE:
|
|
case CompositableType::BUFFER_IMAGE_BUFFERED:
|
|
case CompositableType::IMAGE:
|
|
mImageHost = aHost;
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
void
|
|
ImageLayerComposite::Disconnect()
|
|
{
|
|
Destroy();
|
|
}
|
|
|
|
LayerRenderState
|
|
ImageLayerComposite::GetRenderState()
|
|
{
|
|
if (mImageHost && mImageHost->IsAttached()) {
|
|
return mImageHost->GetRenderState();
|
|
}
|
|
return LayerRenderState();
|
|
}
|
|
|
|
Layer*
|
|
ImageLayerComposite::GetLayer()
|
|
{
|
|
return this;
|
|
}
|
|
|
|
void
|
|
ImageLayerComposite::RenderLayer(const nsIntRect& aClipRect)
|
|
{
|
|
if (!mImageHost || !mImageHost->IsAttached()) {
|
|
return;
|
|
}
|
|
|
|
#ifdef MOZ_DUMP_PAINTING
|
|
if (gfxUtils::sDumpPainting) {
|
|
RefPtr<gfx::DataSourceSurface> surf = mImageHost->GetAsSurface();
|
|
WriteSnapshotToDumpFile(this, surf);
|
|
}
|
|
#endif
|
|
|
|
mCompositor->MakeCurrent();
|
|
|
|
EffectChain effectChain(this);
|
|
LayerManagerComposite::AutoAddMaskEffect autoMaskEffect(mMaskLayer, effectChain);
|
|
AddBlendModeEffect(effectChain);
|
|
|
|
gfx::Rect clipRect(aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height);
|
|
mImageHost->SetCompositor(mCompositor);
|
|
mImageHost->Composite(effectChain,
|
|
GetEffectiveOpacity(),
|
|
GetEffectiveTransform(),
|
|
GetEffectFilter(),
|
|
clipRect);
|
|
mImageHost->BumpFlashCounter();
|
|
}
|
|
|
|
void
|
|
ImageLayerComposite::ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface)
|
|
{
|
|
gfx::Matrix4x4 local = GetLocalTransform();
|
|
|
|
// Snap image edges to pixel boundaries
|
|
gfxRect sourceRect(0, 0, 0, 0);
|
|
if (mImageHost &&
|
|
mImageHost->IsAttached() &&
|
|
mImageHost->GetAsTextureHost()) {
|
|
IntSize size = mImageHost->GetAsTextureHost()->GetSize();
|
|
sourceRect.SizeTo(size.width, size.height);
|
|
if (mScaleMode != ScaleMode::SCALE_NONE &&
|
|
sourceRect.width != 0.0 && sourceRect.height != 0.0) {
|
|
NS_ASSERTION(mScaleMode == ScaleMode::STRETCH,
|
|
"No other scalemodes than stretch and none supported yet.");
|
|
local.Scale(mScaleToSize.width / sourceRect.width,
|
|
mScaleToSize.height / sourceRect.height, 1.0);
|
|
}
|
|
}
|
|
// Snap our local transform first, and snap the inherited transform as well.
|
|
// This makes our snapping equivalent to what would happen if our content
|
|
// was drawn into a ThebesLayer (gfxContext would snap using the local
|
|
// transform, then we'd snap again when compositing the ThebesLayer).
|
|
mEffectiveTransform =
|
|
SnapTransform(local, sourceRect, nullptr) *
|
|
SnapTransformTranslation(aTransformToSurface, nullptr);
|
|
ComputeEffectiveTransformForMaskLayer(aTransformToSurface);
|
|
}
|
|
|
|
CompositableHost*
|
|
ImageLayerComposite::GetCompositableHost()
|
|
{
|
|
if (mImageHost && mImageHost->IsAttached()) {
|
|
return mImageHost.get();
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
void
|
|
ImageLayerComposite::CleanupResources()
|
|
{
|
|
if (mImageHost) {
|
|
mImageHost->Detach(this);
|
|
}
|
|
mImageHost = nullptr;
|
|
}
|
|
|
|
gfx::Filter
|
|
ImageLayerComposite::GetEffectFilter()
|
|
{
|
|
return gfx::ToFilter(mFilter);
|
|
}
|
|
|
|
void
|
|
ImageLayerComposite::GenEffectChain(EffectChain& aEffect)
|
|
{
|
|
aEffect.mLayerRef = this;
|
|
aEffect.mPrimaryEffect = mImageHost->GenEffect(GetEffectFilter());
|
|
}
|
|
|
|
void
|
|
ImageLayerComposite::PrintInfo(std::stringstream& aStream, const char* aPrefix)
|
|
{
|
|
ImageLayer::PrintInfo(aStream, aPrefix);
|
|
if (mImageHost && mImageHost->IsAttached()) {
|
|
aStream << "\n";
|
|
nsAutoCString pfx(aPrefix);
|
|
pfx += " ";
|
|
mImageHost->PrintInfo(aStream, pfx.get());
|
|
}
|
|
}
|
|
|
|
} /* layers */
|
|
} /* mozilla */
|