diff -r 000000000000 -r 6474c204b198 gfx/layers/client/ClientThebesLayer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gfx/layers/client/ClientThebesLayer.cpp Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,166 @@ +/* -*- Mode: C++; tab-width: 2; 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 "ClientThebesLayer.h" +#include "ClientTiledThebesLayer.h" // for ClientTiledThebesLayer +#include "SimpleTiledContentClient.h" +#include // for uint32_t +#include "GeckoProfiler.h" // for PROFILER_LABEL +#include "client/ClientLayerManager.h" // for ClientLayerManager, etc +#include "gfxContext.h" // for gfxContext +#include "gfxRect.h" // for gfxRect +#include "gfxPrefs.h" // for gfxPrefs +#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc +#include "mozilla/gfx/2D.h" // for DrawTarget +#include "mozilla/gfx/Matrix.h" // for Matrix +#include "mozilla/gfx/Rect.h" // for Rect, IntRect +#include "mozilla/gfx/Types.h" // for Float, etc +#include "mozilla/layers/LayersTypes.h" +#include "mozilla/Preferences.h" +#include "nsAutoPtr.h" // for nsRefPtr +#include "nsCOMPtr.h" // for already_AddRefed +#include "nsISupportsImpl.h" // for Layer::AddRef, etc +#include "nsRect.h" // for nsIntRect +#include "gfx2DGlue.h" + +using namespace mozilla::gfx; + +namespace mozilla { +namespace layers { + +void +ClientThebesLayer::PaintThebes() +{ + PROFILER_LABEL("ClientThebesLayer", "PaintThebes"); + NS_ASSERTION(ClientManager()->InDrawing(), + "Can only draw in drawing phase"); + + uint32_t flags = RotatedContentBuffer::PAINT_CAN_DRAW_ROTATED; +#ifndef MOZ_WIDGET_ANDROID + if (ClientManager()->CompositorMightResample()) { + flags |= RotatedContentBuffer::PAINT_WILL_RESAMPLE; + } + if (!(flags & RotatedContentBuffer::PAINT_WILL_RESAMPLE)) { + if (MayResample()) { + flags |= RotatedContentBuffer::PAINT_WILL_RESAMPLE; + } + } +#endif + PaintState state = + mContentClient->BeginPaintBuffer(this, flags); + mValidRegion.Sub(mValidRegion, state.mRegionToInvalidate); + + if (!state.mRegionToDraw.IsEmpty() && !ClientManager()->GetThebesLayerCallback()) { + ClientManager()->SetTransactionIncomplete(); + return; + } + + // The area that became invalid and is visible needs to be repainted + // (this could be the whole visible area if our buffer switched + // from RGB to RGBA, because we might need to repaint with + // subpixel AA) + state.mRegionToInvalidate.And(state.mRegionToInvalidate, + GetEffectiveVisibleRegion()); + + bool didUpdate = false; + RotatedContentBuffer::DrawIterator iter; + while (DrawTarget* target = mContentClient->BorrowDrawTargetForPainting(state, &iter)) { + SetAntialiasingFlags(this, target); + + nsRefPtr ctx = gfxContext::ContextForDrawTarget(target); + + ClientManager()->GetThebesLayerCallback()(this, + ctx, + iter.mDrawRegion, + state.mClip, + state.mRegionToInvalidate, + ClientManager()->GetThebesLayerCallbackData()); + + ctx = nullptr; + mContentClient->ReturnDrawTargetToBuffer(target); + didUpdate = true; + } + + if (didUpdate) { + Mutated(); + + mValidRegion.Or(mValidRegion, state.mRegionToDraw); + + ContentClientRemote* contentClientRemote = static_cast(mContentClient.get()); + MOZ_ASSERT(contentClientRemote->GetIPDLActor()); + + // Hold(this) ensures this layer is kept alive through the current transaction + // The ContentClient assumes this layer is kept alive (e.g., in CreateBuffer), + // so deleting this Hold for whatever reason will break things. + ClientManager()->Hold(this); + contentClientRemote->Updated(state.mRegionToDraw, + mVisibleRegion, + state.mDidSelfCopy); + } +} + +void +ClientThebesLayer::RenderLayer() +{ + if (GetMaskLayer()) { + ToClientLayer(GetMaskLayer())->RenderLayer(); + } + + if (!mContentClient) { + mContentClient = ContentClient::CreateContentClient(ClientManager()->AsShadowForwarder()); + if (!mContentClient) { + return; + } + mContentClient->Connect(); + ClientManager()->AsShadowForwarder()->Attach(mContentClient, this); + MOZ_ASSERT(mContentClient->GetForwarder()); + } + + mContentClient->BeginPaint(); + PaintThebes(); + mContentClient->EndPaint(); +} + +already_AddRefed +ClientLayerManager::CreateThebesLayer() +{ + return CreateThebesLayerWithHint(NONE); +} + +already_AddRefed +ClientLayerManager::CreateThebesLayerWithHint(ThebesLayerCreationHint aHint) +{ + NS_ASSERTION(InConstruction(), "Only allowed in construction phase"); + if ( +#ifdef MOZ_B2G + aHint == SCROLLABLE && +#endif + gfxPrefs::LayersTilesEnabled() && + (AsShadowForwarder()->GetCompositorBackendType() == LayersBackend::LAYERS_OPENGL || + AsShadowForwarder()->GetCompositorBackendType() == LayersBackend::LAYERS_D3D9 || + AsShadowForwarder()->GetCompositorBackendType() == LayersBackend::LAYERS_D3D11)) { + if (gfxPrefs::LayersUseSimpleTiles()) { + nsRefPtr layer = + new SimpleClientTiledThebesLayer(this); + CREATE_SHADOW(Thebes); + return layer.forget(); + } else { + nsRefPtr layer = + new ClientTiledThebesLayer(this); + CREATE_SHADOW(Thebes); + return layer.forget(); + } + } else + { + nsRefPtr layer = + new ClientThebesLayer(this); + CREATE_SHADOW(Thebes); + return layer.forget(); + } +} + + +} +}