gecko/gfx/layers/composite/ImageLayerComposite.cpp
Boris Chiou c900095227 Bug 975346 - Part 1: General functions for Effects. r=dglastonbury
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.
2014-06-22 19:06:00 +02:00

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 */