gecko/gfx/layers/composite/LayerManagerComposite.cpp
Kartikaya Gupta 189805593c Bug 732971 - For Fennec move the resolution from the top-level presShell to the content presShell. r=BenWa
The bulk of this patch is fixing up pieces of code that infer the resolution
as the inverse of the scaling transform on the root layer. This used to be
how various bits of gfx code obtained the resolution, but now that we can set
the resolution on the actual presShell that contains the content, we can also
just read the resolution from the FrameMetrics directly.
2013-10-29 09:27:50 -04:00

809 lines
24 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 "LayerManagerComposite.h"
#include <stddef.h> // for size_t
#include <stdint.h> // for uint16_t, uint32_t
#include "CanvasLayerComposite.h" // for CanvasLayerComposite
#include "ColorLayerComposite.h" // for ColorLayerComposite
#include "Composer2D.h" // for Composer2D
#include "CompositableHost.h" // for CompositableHost
#include "ContainerLayerComposite.h" // for ContainerLayerComposite, etc
#include "FrameMetrics.h" // for FrameMetrics
#include "GeckoProfiler.h" // for profiler_set_frame_number, etc
#include "ImageLayerComposite.h" // for ImageLayerComposite
#include "Layers.h" // for Layer, ContainerLayer, etc
#include "ThebesLayerComposite.h" // for ThebesLayerComposite
#include "TiledLayerBuffer.h" // for TiledLayerComposer
#include "Units.h" // for ScreenIntRect
#include "gfx2DGlue.h" // for ToMatrix4x4
#include "gfx3DMatrix.h" // for gfx3DMatrix
#include "gfxMatrix.h" // for gfxMatrix
#include "gfxPlatform.h" // for gfxPlatform
#ifdef XP_MACOSX
#include "gfxPlatformMac.h"
#endif
#include "gfxPoint.h" // for gfxIntSize
#include "gfxRect.h" // for gfxRect
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
#include "mozilla/RefPtr.h" // for RefPtr, TemporaryRef
#include "mozilla/gfx/2D.h" // for DrawTarget
#include "mozilla/gfx/Matrix.h" // for Matrix4x4
#include "mozilla/gfx/Point.h" // for IntSize, Point
#include "mozilla/gfx/Rect.h" // for Rect
#include "mozilla/gfx/Types.h" // for Color, SurfaceFormat
#include "mozilla/layers/Compositor.h" // for Compositor
#include "mozilla/layers/CompositorTypes.h"
#include "mozilla/layers/Effects.h" // for Effect, EffectChain, etc
#include "mozilla/layers/LayersTypes.h" // for MOZ_LAYERS_HAVE_LOG, etc
#include "ipc/ShadowLayerUtils.h"
#include "mozilla/mozalloc.h" // for operator new, etc
#include "nsAutoPtr.h" // for nsRefPtr
#include "nsCOMPtr.h" // for already_AddRefed
#include "nsDebug.h" // for NS_WARNING, NS_RUNTIMEABORT, etc
#include "nsISupportsImpl.h" // for Layer::AddRef, etc
#include "nsIWidget.h" // for nsIWidget
#include "nsPoint.h" // for nsIntPoint
#include "nsRect.h" // for nsIntRect
#include "nsRegion.h" // for nsIntRegion, etc
#ifdef MOZ_WIDGET_ANDROID
#include <android/log.h>
#endif
#include "GeckoProfiler.h"
class gfxASurface;
class gfxContext;
struct nsIntSize;
namespace mozilla {
namespace layers {
class ImageLayer;
using namespace mozilla::gfx;
using namespace mozilla::gl;
static LayerComposite*
ToLayerComposite(Layer* aLayer)
{
return static_cast<LayerComposite*>(aLayer->ImplData());
}
static void ClearSubtree(Layer* aLayer)
{
ToLayerComposite(aLayer)->CleanupResources();
for (Layer* child = aLayer->GetFirstChild(); child;
child = child->GetNextSibling()) {
ClearSubtree(child);
}
}
void
LayerManagerComposite::ClearCachedResources(Layer* aSubtree)
{
MOZ_ASSERT(!aSubtree || aSubtree->Manager() == this);
Layer* subtree = aSubtree ? aSubtree : mRoot.get();
if (!subtree) {
return;
}
ClearSubtree(subtree);
// FIXME [bjacob]
// XXX the old LayerManagerOGL code had a mMaybeInvalidTree that it set to true here.
// Do we need that?
}
/**
* LayerManagerComposite
*/
LayerManagerComposite::LayerManagerComposite(Compositor* aCompositor)
: mCompositor(aCompositor)
{
MOZ_ASSERT(aCompositor);
}
LayerManagerComposite::~LayerManagerComposite()
{
Destroy();
}
bool
LayerManagerComposite::Initialize()
{
bool result = mCompositor->Initialize();
mComposer2D = mCompositor->GetWidget()->GetComposer2D();
return result;
}
void
LayerManagerComposite::Destroy()
{
if (!mDestroyed) {
mCompositor->GetWidget()->CleanupWindowEffects();
if (mRoot) {
RootLayer()->Destroy();
}
mRoot = nullptr;
mCompositor->Destroy();
mDestroyed = true;
}
}
void
LayerManagerComposite::UpdateRenderBounds(const nsIntRect& aRect)
{
mRenderBounds = aRect;
}
void
LayerManagerComposite::BeginTransaction()
{
mInTransaction = true;
}
void
LayerManagerComposite::BeginTransactionWithDrawTarget(DrawTarget* aTarget)
{
mInTransaction = true;
#ifdef MOZ_LAYERS_HAVE_LOG
MOZ_LAYERS_LOG(("[----- BeginTransaction"));
Log();
#endif
if (mDestroyed) {
NS_WARNING("Call on destroyed layer manager");
return;
}
mCompositor->SetTargetContext(aTarget);
}
bool
LayerManagerComposite::EndEmptyTransaction(EndTransactionFlags aFlags)
{
mInTransaction = false;
if (!mRoot)
return false;
EndTransaction(nullptr, nullptr);
return true;
}
void
LayerManagerComposite::EndTransaction(DrawThebesLayerCallback aCallback,
void* aCallbackData,
EndTransactionFlags aFlags)
{
mInTransaction = false;
#ifdef MOZ_LAYERS_HAVE_LOG
MOZ_LAYERS_LOG((" ----- (beginning paint)"));
Log();
#endif
if (mDestroyed) {
NS_WARNING("Call on destroyed layer manager");
return;
}
if (mRoot && !(aFlags & END_NO_IMMEDIATE_REDRAW)) {
if (aFlags & END_NO_COMPOSITE) {
// Apply pending tree updates before recomputing effective
// properties.
mRoot->ApplyPendingUpdatesToSubtree();
}
// The results of our drawing always go directly into a pixel buffer,
// so we don't need to pass any global transform here.
mRoot->ComputeEffectiveTransforms(gfx3DMatrix());
mThebesLayerCallback = aCallback;
mThebesLayerCallbackData = aCallbackData;
Render();
mThebesLayerCallback = nullptr;
mThebesLayerCallbackData = nullptr;
}
mCompositor->SetTargetContext(nullptr);
#ifdef MOZ_LAYERS_HAVE_LOG
Log();
MOZ_LAYERS_LOG(("]----- EndTransaction"));
#endif
}
already_AddRefed<gfxASurface>
LayerManagerComposite::CreateOptimalMaskSurface(const gfxIntSize &aSize)
{
NS_RUNTIMEABORT("Should only be called on the drawing side");
return nullptr;
}
already_AddRefed<ThebesLayer>
LayerManagerComposite::CreateThebesLayer()
{
NS_RUNTIMEABORT("Should only be called on the drawing side");
return nullptr;
}
already_AddRefed<ContainerLayer>
LayerManagerComposite::CreateContainerLayer()
{
NS_RUNTIMEABORT("Should only be called on the drawing side");
return nullptr;
}
already_AddRefed<ImageLayer>
LayerManagerComposite::CreateImageLayer()
{
NS_RUNTIMEABORT("Should only be called on the drawing side");
return nullptr;
}
already_AddRefed<ColorLayer>
LayerManagerComposite::CreateColorLayer()
{
NS_RUNTIMEABORT("Should only be called on the drawing side");
return nullptr;
}
already_AddRefed<CanvasLayer>
LayerManagerComposite::CreateCanvasLayer()
{
NS_RUNTIMEABORT("Should only be called on the drawing side");
return nullptr;
}
LayerComposite*
LayerManagerComposite::RootLayer() const
{
if (mDestroyed) {
NS_WARNING("Call on destroyed layer manager");
return nullptr;
}
return static_cast<LayerComposite*>(mRoot->ImplData());
}
static uint16_t sFrameCount = 0;
void
LayerManagerComposite::RenderDebugOverlay(const Rect& aBounds)
{
if (!gfxPlatform::DrawFrameCounter()) {
return;
}
profiler_set_frame_number(sFrameCount);
uint16_t frameNumber = sFrameCount;
const uint16_t bitWidth = 3;
float opacity = 1.0;
gfx::Rect clip(0,0, bitWidth*16, bitWidth);
for (size_t i = 0; i < 16; i++) {
gfx::Color bitColor;
if ((frameNumber >> i) & 0x1) {
bitColor = gfx::Color(0, 0, 0, 1.0);
} else {
bitColor = gfx::Color(1.0, 1.0, 1.0, 1.0);
}
EffectChain effects;
effects.mPrimaryEffect = new EffectSolidColor(bitColor);
mCompositor->DrawQuad(gfx::Rect(bitWidth*i, 0, bitWidth, bitWidth),
clip,
effects,
opacity,
gfx::Matrix4x4(),
gfx::Point());
}
// We intentionally overflow at 2^16.
sFrameCount++;
}
void
LayerManagerComposite::Render()
{
PROFILER_LABEL("LayerManagerComposite", "Render");
if (mDestroyed) {
NS_WARNING("Call on destroyed layer manager");
return;
}
if (mComposer2D && mComposer2D->TryRender(mRoot, mWorldMatrix)) {
mCompositor->EndFrameForExternalComposition(mWorldMatrix);
return;
}
{
PROFILER_LABEL("LayerManagerComposite", "PreRender");
if (!mCompositor->GetWidget()->PreRender(this)) {
return;
}
}
nsIntRect clipRect;
Rect bounds(mRenderBounds.x, mRenderBounds.y, mRenderBounds.width, mRenderBounds.height);
Rect actualBounds;
if (mRoot->GetClipRect()) {
clipRect = *mRoot->GetClipRect();
WorldTransformRect(clipRect);
Rect rect(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
mCompositor->BeginFrame(&rect, mWorldMatrix, bounds, nullptr, &actualBounds);
} else {
gfx::Rect rect;
mCompositor->BeginFrame(nullptr, mWorldMatrix, bounds, &rect, &actualBounds);
clipRect = nsIntRect(rect.x, rect.y, rect.width, rect.height);
}
if (actualBounds.IsEmpty()) {
mCompositor->GetWidget()->PostRender(this);
return;
}
// Allow widget to render a custom background.
mCompositor->SaveState();
mCompositor->GetWidget()->DrawWindowUnderlay(this, nsIntRect(actualBounds.x,
actualBounds.y,
actualBounds.width,
actualBounds.height));
mCompositor->RestoreState();
// Render our layers.
RootLayer()->RenderLayer(nsIntPoint(0, 0), clipRect);
// Allow widget to render a custom foreground.
mCompositor->SaveState();
mCompositor->GetWidget()->DrawWindowOverlay(this, nsIntRect(actualBounds.x,
actualBounds.y,
actualBounds.width,
actualBounds.height));
mCompositor->RestoreState();
// Debugging
RenderDebugOverlay(actualBounds);
{
PROFILER_LABEL("LayerManagerComposite", "EndFrame");
mCompositor->EndFrame();
}
mCompositor->GetWidget()->PostRender(this);
}
void
LayerManagerComposite::SetWorldTransform(const gfxMatrix& aMatrix)
{
NS_ASSERTION(aMatrix.PreservesAxisAlignedRectangles(),
"SetWorldTransform only accepts matrices that satisfy PreservesAxisAlignedRectangles");
NS_ASSERTION(!aMatrix.HasNonIntegerScale(),
"SetWorldTransform only accepts matrices with integer scale");
mWorldMatrix = aMatrix;
}
gfxMatrix&
LayerManagerComposite::GetWorldTransform(void)
{
return mWorldMatrix;
}
void
LayerManagerComposite::WorldTransformRect(nsIntRect& aRect)
{
gfxRect grect(aRect.x, aRect.y, aRect.width, aRect.height);
grect = mWorldMatrix.TransformBounds(grect);
aRect.SetRect(grect.X(), grect.Y(), grect.Width(), grect.Height());
}
static void
SubtractTransformedRegion(nsIntRegion& aRegion,
const nsIntRegion& aRegionToSubtract,
const gfx3DMatrix& aTransform)
{
if (aRegionToSubtract.IsEmpty()) {
return;
}
// For each rect in the region, find out its bounds in screen space and
// subtract it from the screen region.
nsIntRegionRectIterator it(aRegionToSubtract);
while (const nsIntRect* rect = it.Next()) {
gfxRect incompleteRect = aTransform.TransformBounds(gfxRect(*rect));
aRegion.Sub(aRegion, nsIntRect(incompleteRect.x,
incompleteRect.y,
incompleteRect.width,
incompleteRect.height));
}
}
/* static */ void
LayerManagerComposite::ComputeRenderIntegrityInternal(Layer* aLayer,
nsIntRegion& aScreenRegion,
nsIntRegion& aLowPrecisionScreenRegion,
const gfx3DMatrix& aTransform)
{
if (aLayer->GetOpacity() <= 0.f ||
(aScreenRegion.IsEmpty() && aLowPrecisionScreenRegion.IsEmpty())) {
return;
}
// If the layer's a container, recurse into all of its children
ContainerLayer* container = aLayer->AsContainerLayer();
if (container) {
// Accumulate the transform of intermediate surfaces
gfx3DMatrix transform = aTransform;
if (container->UseIntermediateSurface()) {
transform = aLayer->GetEffectiveTransform();
transform.PreMultiply(aTransform);
}
for (Layer* child = aLayer->GetFirstChild(); child;
child = child->GetNextSibling()) {
ComputeRenderIntegrityInternal(child, aScreenRegion, aLowPrecisionScreenRegion, transform);
}
return;
}
// Only thebes layers can be incomplete
ThebesLayer* thebesLayer = aLayer->AsThebesLayer();
if (!thebesLayer) {
return;
}
// See if there's any incomplete rendering
nsIntRegion incompleteRegion = aLayer->GetEffectiveVisibleRegion();
incompleteRegion.Sub(incompleteRegion, thebesLayer->GetValidRegion());
if (!incompleteRegion.IsEmpty()) {
// Calculate the transform to get between screen and layer space
gfx3DMatrix transformToScreen = aLayer->GetEffectiveTransform();
transformToScreen.PreMultiply(aTransform);
SubtractTransformedRegion(aScreenRegion, incompleteRegion, transformToScreen);
// See if there's any incomplete low-precision rendering
TiledLayerComposer* composer = nullptr;
LayerComposite* shadow = aLayer->AsLayerComposite();
if (shadow) {
composer = shadow->GetTiledLayerComposer();
if (composer) {
incompleteRegion.Sub(incompleteRegion, composer->GetValidLowPrecisionRegion());
if (!incompleteRegion.IsEmpty()) {
SubtractTransformedRegion(aLowPrecisionScreenRegion, incompleteRegion, transformToScreen);
}
}
}
// If we can't get a valid low precision region, assume it's the same as
// the high precision region.
if (!composer) {
SubtractTransformedRegion(aLowPrecisionScreenRegion, incompleteRegion, transformToScreen);
}
}
}
#ifdef MOZ_ANDROID_OMTC
static float
GetDisplayportCoverage(const CSSRect& aDisplayPort,
const gfx3DMatrix& aTransformToScreen,
const nsIntRect& aScreenRect)
{
gfxRect transformedDisplayport =
aTransformToScreen.TransformBounds(gfxRect(aDisplayPort.x,
aDisplayPort.y,
aDisplayPort.width,
aDisplayPort.height));
transformedDisplayport.RoundOut();
nsIntRect displayport = nsIntRect(transformedDisplayport.x,
transformedDisplayport.y,
transformedDisplayport.width,
transformedDisplayport.height);
if (!displayport.Contains(aScreenRect)) {
nsIntRegion coveredRegion;
coveredRegion.And(aScreenRect, displayport);
return coveredRegion.Area() / (float)(aScreenRect.width * aScreenRect.height);
}
return 1.0f;
}
#endif // MOZ_ANDROID_OMTC
float
LayerManagerComposite::ComputeRenderIntegrity()
{
// We only ever have incomplete rendering when progressive tiles are enabled.
Layer* root = GetRoot();
if (!gfxPlatform::UseProgressiveTilePainting() || !root) {
return 1.f;
}
const FrameMetrics& rootMetrics = root->AsContainerLayer()->GetFrameMetrics();
nsIntRect screenRect(rootMetrics.mCompositionBounds.x,
rootMetrics.mCompositionBounds.y,
rootMetrics.mCompositionBounds.width,
rootMetrics.mCompositionBounds.height);
float lowPrecisionMultiplier = 1.0f;
float highPrecisionMultiplier = 1.0f;
#ifdef MOZ_ANDROID_OMTC
// Use the transform on the primary scrollable layer and its FrameMetrics
// to find out how much of the viewport the current displayport covers
Layer* primaryScrollable = GetPrimaryScrollableLayer();
if (primaryScrollable) {
// This is derived from the code in
// AsyncCompositionManager::TransformScrollableLayer
const FrameMetrics& metrics = primaryScrollable->AsContainerLayer()->GetFrameMetrics();
gfx3DMatrix transform = primaryScrollable->GetEffectiveTransform();
transform.ScalePost(metrics.mResolution.scale, metrics.mResolution.scale, 1);
// Clip the screen rect to the document bounds
gfxRect documentBounds =
transform.TransformBounds(gfxRect(metrics.mScrollableRect.x - metrics.mScrollOffset.x,
metrics.mScrollableRect.y - metrics.mScrollOffset.y,
metrics.mScrollableRect.width,
metrics.mScrollableRect.height));
documentBounds.RoundOut();
screenRect = screenRect.Intersect(nsIntRect(documentBounds.x, documentBounds.y,
documentBounds.width, documentBounds.height));
// If the screen rect is empty, the user has scrolled entirely into
// over-scroll and so we can be considered to have full integrity.
if (screenRect.IsEmpty()) {
return 1.0f;
}
// Work out how much of the critical display-port covers the screen
bool hasLowPrecision = false;
if (!metrics.mCriticalDisplayPort.IsEmpty()) {
hasLowPrecision = true;
highPrecisionMultiplier =
GetDisplayportCoverage(metrics.mCriticalDisplayPort, transform, screenRect);
}
// Work out how much of the display-port covers the screen
if (!metrics.mDisplayPort.IsEmpty()) {
if (hasLowPrecision) {
lowPrecisionMultiplier =
GetDisplayportCoverage(metrics.mDisplayPort, transform, screenRect);
} else {
lowPrecisionMultiplier = highPrecisionMultiplier =
GetDisplayportCoverage(metrics.mDisplayPort, transform, screenRect);
}
}
}
// If none of the screen is covered, we have zero integrity.
if (highPrecisionMultiplier <= 0.0f && lowPrecisionMultiplier <= 0.0f) {
return 0.0f;
}
#endif // MOZ_ANDROID_OMTC
nsIntRegion screenRegion(screenRect);
nsIntRegion lowPrecisionScreenRegion(screenRect);
gfx3DMatrix transform;
ComputeRenderIntegrityInternal(root, screenRegion,
lowPrecisionScreenRegion, transform);
if (!screenRegion.IsEqual(screenRect)) {
// Calculate the area of the region. All rects in an nsRegion are
// non-overlapping.
float screenArea = screenRect.width * screenRect.height;
float highPrecisionIntegrity = screenRegion.Area() / screenArea;
float lowPrecisionIntegrity = 1.f;
if (!lowPrecisionScreenRegion.IsEqual(screenRect)) {
lowPrecisionIntegrity = lowPrecisionScreenRegion.Area() / screenArea;
}
return ((highPrecisionIntegrity * highPrecisionMultiplier) +
(lowPrecisionIntegrity * lowPrecisionMultiplier)) / 2;
}
return 1.f;
}
already_AddRefed<ThebesLayerComposite>
LayerManagerComposite::CreateThebesLayerComposite()
{
if (mDestroyed) {
NS_WARNING("Call on destroyed layer manager");
return nullptr;
}
return nsRefPtr<ThebesLayerComposite>(new ThebesLayerComposite(this)).forget();
}
already_AddRefed<ContainerLayerComposite>
LayerManagerComposite::CreateContainerLayerComposite()
{
if (mDestroyed) {
NS_WARNING("Call on destroyed layer manager");
return nullptr;
}
return nsRefPtr<ContainerLayerComposite>(new ContainerLayerComposite(this)).forget();
}
already_AddRefed<ImageLayerComposite>
LayerManagerComposite::CreateImageLayerComposite()
{
if (mDestroyed) {
NS_WARNING("Call on destroyed layer manager");
return nullptr;
}
return nsRefPtr<ImageLayerComposite>(new ImageLayerComposite(this)).forget();
}
already_AddRefed<ColorLayerComposite>
LayerManagerComposite::CreateColorLayerComposite()
{
if (LayerManagerComposite::mDestroyed) {
NS_WARNING("Call on destroyed layer manager");
return nullptr;
}
return nsRefPtr<ColorLayerComposite>(new ColorLayerComposite(this)).forget();
}
already_AddRefed<CanvasLayerComposite>
LayerManagerComposite::CreateCanvasLayerComposite()
{
if (LayerManagerComposite::mDestroyed) {
NS_WARNING("Call on destroyed layer manager");
return nullptr;
}
return nsRefPtr<CanvasLayerComposite>(new CanvasLayerComposite(this)).forget();
}
already_AddRefed<RefLayerComposite>
LayerManagerComposite::CreateRefLayerComposite()
{
if (LayerManagerComposite::mDestroyed) {
NS_WARNING("Call on destroyed layer manager");
return nullptr;
}
return nsRefPtr<RefLayerComposite>(new RefLayerComposite(this)).forget();
}
LayerManagerComposite::AutoAddMaskEffect::AutoAddMaskEffect(Layer* aMaskLayer,
EffectChain& aEffects,
bool aIs3D)
: mCompositable(nullptr)
{
if (!aMaskLayer) {
return;
}
mCompositable = static_cast<LayerComposite*>(aMaskLayer->ImplData())->GetCompositableHost();
if (!mCompositable) {
NS_WARNING("Mask layer with no compositable host");
return;
}
gfx::Matrix4x4 transform;
ToMatrix4x4(aMaskLayer->GetEffectiveTransform(), transform);
mCompositable->AddMaskEffect(aEffects, transform, aIs3D);
}
LayerManagerComposite::AutoAddMaskEffect::~AutoAddMaskEffect()
{
if (!mCompositable) {
return;
}
mCompositable->RemoveMaskEffect();
}
TemporaryRef<DrawTarget>
LayerManagerComposite::CreateDrawTarget(const IntSize &aSize,
SurfaceFormat aFormat)
{
#ifdef XP_MACOSX
// We don't want to accelerate if the surface is too small which indicates
// that it's likely used for an icon/static image. We also don't want to
// accelerate anything that is above the maximum texture size of weakest gpu.
// Safari uses 5000 area as the minimum for acceleration, we decided 64^2 is more logical.
bool useAcceleration = aSize.width <= 4096 && aSize.height <= 4096 &&
aSize.width > 64 && aSize.height > 64 &&
gfxPlatformMac::GetPlatform()->UseAcceleratedCanvas();
if (useAcceleration) {
return Factory::CreateDrawTarget(BACKEND_COREGRAPHICS_ACCELERATED,
aSize, aFormat);
}
#endif
return LayerManager::CreateDrawTarget(aSize, aFormat);
}
LayerComposite::LayerComposite(LayerManagerComposite *aManager)
: mCompositeManager(aManager)
, mCompositor(aManager->GetCompositor())
, mShadowOpacity(1.0)
, mUseShadowClipRect(false)
, mShadowTransformSetByAnimation(false)
, mDestroyed(false)
, mLayerComposited(false)
{ }
LayerComposite::~LayerComposite()
{
}
void
LayerComposite::Destroy()
{
if (!mDestroyed) {
mDestroyed = true;
CleanupResources();
}
}
const nsIntSize&
LayerManagerComposite::GetWidgetSize()
{
return mCompositor->GetWidgetSize();
}
void
LayerManagerComposite::SetCompositorID(uint32_t aID)
{
NS_ASSERTION(mCompositor, "No compositor");
mCompositor->SetCompositorID(aID);
}
void
LayerManagerComposite::NotifyShadowTreeTransaction()
{
mCompositor->NotifyLayersTransaction();
}
bool
LayerManagerComposite::CanUseCanvasLayerForSize(const gfxIntSize &aSize)
{
return mCompositor->CanUseCanvasLayerForSize(gfx::IntSize(aSize.width,
aSize.height));
}
TextureFactoryIdentifier
LayerManagerComposite::GetTextureFactoryIdentifier()
{
return mCompositor->GetTextureFactoryIdentifier();
}
int32_t
LayerManagerComposite::GetMaxTextureSize() const
{
return mCompositor->GetMaxTextureSize();
}
#ifndef MOZ_HAVE_PLATFORM_SPECIFIC_LAYER_BUFFERS
/*static*/ already_AddRefed<TextureImage>
LayerManagerComposite::OpenDescriptorForDirectTexturing(GLContext*,
const SurfaceDescriptor&,
GLenum)
{
return nullptr;
}
/*static*/ bool
LayerManagerComposite::SupportsDirectTexturing()
{
return false;
}
/*static*/ void
LayerManagerComposite::PlatformSyncBeforeReplyUpdate()
{
}
#endif // !defined(MOZ_HAVE_PLATFORM_SPECIFIC_LAYER_BUFFERS)
} /* layers */
} /* mozilla */