gecko-dev/gfx/layers/composite/ThebesLayerComposite.cpp
Boris Chiou 80b67114ce 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

217 lines
5.9 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 "ThebesLayerComposite.h"
#include "CompositableHost.h" // for TiledLayerProperties, etc
#include "FrameMetrics.h" // for FrameMetrics
#include "Units.h" // for CSSRect, LayerPixel, etc
#include "gfx2DGlue.h" // for ToMatrix4x4
#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 Point
#include "mozilla/gfx/Rect.h" // for RoundedToInt, Rect
#include "mozilla/gfx/Types.h" // for Filter::Filter::LINEAR
#include "mozilla/layers/Compositor.h" // for Compositor
#include "mozilla/layers/ContentHost.h" // for ContentHost
#include "mozilla/layers/Effects.h" // for EffectChain
#include "mozilla/mozalloc.h" // for operator delete
#include "nsAString.h"
#include "nsAutoPtr.h" // for nsRefPtr
#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
#include "nsMathUtils.h" // for NS_lround
#include "nsPoint.h" // for nsIntPoint
#include "nsRect.h" // for nsIntRect
#include "nsSize.h" // for nsIntSize
#include "nsString.h" // for nsAutoCString
#include "TextRenderer.h"
#include "GeckoProfiler.h"
namespace mozilla {
namespace layers {
class TiledLayerComposer;
ThebesLayerComposite::ThebesLayerComposite(LayerManagerComposite *aManager)
: ThebesLayer(aManager, nullptr)
, LayerComposite(aManager)
, mBuffer(nullptr)
, mRequiresTiledProperties(false)
{
MOZ_COUNT_CTOR(ThebesLayerComposite);
mImplData = static_cast<LayerComposite*>(this);
}
ThebesLayerComposite::~ThebesLayerComposite()
{
MOZ_COUNT_DTOR(ThebesLayerComposite);
CleanupResources();
}
bool
ThebesLayerComposite::SetCompositableHost(CompositableHost* aHost)
{
switch (aHost->GetType()) {
case CompositableType::BUFFER_CONTENT_INC:
case CompositableType::BUFFER_TILED:
case CompositableType::CONTENT_SINGLE:
case CompositableType::CONTENT_DOUBLE:
mBuffer = static_cast<ContentHost*>(aHost);
return true;
default:
return false;
}
}
void
ThebesLayerComposite::Disconnect()
{
Destroy();
}
void
ThebesLayerComposite::Destroy()
{
if (!mDestroyed) {
CleanupResources();
mDestroyed = true;
}
}
Layer*
ThebesLayerComposite::GetLayer()
{
return this;
}
TiledLayerComposer*
ThebesLayerComposite::GetTiledLayerComposer()
{
if (!mBuffer) {
return nullptr;
}
MOZ_ASSERT(mBuffer->IsAttached());
return mBuffer->AsTiledLayerComposer();
}
LayerRenderState
ThebesLayerComposite::GetRenderState()
{
if (!mBuffer || !mBuffer->IsAttached() || mDestroyed) {
return LayerRenderState();
}
return mBuffer->GetRenderState();
}
void
ThebesLayerComposite::RenderLayer(const nsIntRect& aClipRect)
{
if (!mBuffer || !mBuffer->IsAttached()) {
return;
}
PROFILER_LABEL("ThebesLayerComposite", "RenderLayer",
js::ProfileEntry::Category::GRAPHICS);
MOZ_ASSERT(mBuffer->GetCompositor() == mCompositeManager->GetCompositor() &&
mBuffer->GetLayer() == this,
"buffer is corrupted");
gfx::Rect clipRect(aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height);
#ifdef MOZ_DUMP_PAINTING
if (gfxUtils::sDumpPainting) {
RefPtr<gfx::DataSourceSurface> surf = mBuffer->GetAsSurface();
if (surf) {
WriteSnapshotToDumpFile(this, surf);
}
}
#endif
EffectChain effectChain(this);
LayerManagerComposite::AutoAddMaskEffect autoMaskEffect(mMaskLayer, effectChain);
AddBlendModeEffect(effectChain);
const nsIntRegion& visibleRegion = GetEffectiveVisibleRegion();
TiledLayerProperties tiledLayerProps;
if (mRequiresTiledProperties) {
tiledLayerProps.mVisibleRegion = visibleRegion;
tiledLayerProps.mEffectiveResolution = GetEffectiveResolution();
tiledLayerProps.mValidRegion = mValidRegion;
}
mBuffer->SetPaintWillResample(MayResample());
mBuffer->Composite(effectChain,
GetEffectiveOpacity(),
GetEffectiveTransform(),
GetEffectFilter(),
clipRect,
&visibleRegion,
mRequiresTiledProperties ? &tiledLayerProps
: nullptr);
mBuffer->BumpFlashCounter();
if (mRequiresTiledProperties) {
mValidRegion = tiledLayerProps.mValidRegion;
}
mCompositeManager->GetCompositor()->MakeCurrent();
}
CompositableHost*
ThebesLayerComposite::GetCompositableHost()
{
if (mBuffer && mBuffer->IsAttached()) {
return mBuffer.get();
}
return nullptr;
}
void
ThebesLayerComposite::CleanupResources()
{
if (mBuffer) {
mBuffer->Detach(this);
}
mBuffer = nullptr;
}
void
ThebesLayerComposite::GenEffectChain(EffectChain& aEffect)
{
aEffect.mLayerRef = this;
aEffect.mPrimaryEffect = mBuffer->GenEffect(GetEffectFilter());
}
CSSToScreenScale
ThebesLayerComposite::GetEffectiveResolution()
{
for (ContainerLayer* parent = GetParent(); parent; parent = parent->GetParent()) {
const FrameMetrics& metrics = parent->GetFrameMetrics();
if (metrics.GetScrollId() != FrameMetrics::NULL_SCROLL_ID) {
return metrics.GetZoom();
}
}
return CSSToScreenScale(1.0);
}
void
ThebesLayerComposite::PrintInfo(std::stringstream& aStream, const char* aPrefix)
{
ThebesLayer::PrintInfo(aStream, aPrefix);
if (mBuffer && mBuffer->IsAttached()) {
aStream << "\n";
nsAutoCString pfx(aPrefix);
pfx += " ";
mBuffer->PrintInfo(aStream, pfx.get());
}
}
} /* layers */
} /* mozilla */