mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 947781 - Part 4: Add ReadbackLayer functionality to ClientLayerManager. r=mattwoodrow
This commit is contained in:
parent
337d782d7e
commit
e9f3470cf0
@ -15,6 +15,8 @@
|
||||
#include "nsISupportsUtils.h" // for NS_ADDREF, NS_RELEASE
|
||||
#include "nsRegion.h" // for nsIntRegion
|
||||
#include "nsTArray.h" // for nsAutoTArray
|
||||
#include "ReadbackProcessor.h"
|
||||
#include "ClientThebesLayer.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
@ -55,13 +57,20 @@ public:
|
||||
nsAutoTArray<Layer*, 12> children;
|
||||
SortChildrenBy3DZOrder(children);
|
||||
|
||||
ReadbackProcessor readback;
|
||||
readback.BuildUpdates(this);
|
||||
|
||||
for (uint32_t i = 0; i < children.Length(); i++) {
|
||||
Layer* child = children.ElementAt(i);
|
||||
if (child->GetEffectiveVisibleRegion().IsEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ToClientLayer(child)->RenderLayer();
|
||||
if (child->GetType() != TYPE_THEBES) {
|
||||
ToClientLayer(child)->RenderLayer();
|
||||
} else {
|
||||
static_cast<ClientThebesLayer*>(child)->RenderLayer(&readback);
|
||||
}
|
||||
|
||||
if (!ClientManager()->GetRepeatTransaction() &&
|
||||
!child->GetInvalidRegion().IsEmpty()) {
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "mozilla/layers/LayerTransactionChild.h"
|
||||
#include "mozilla/layers/TextureClientPool.h" // for TextureClientPool
|
||||
#include "mozilla/layers/SimpleTextureClientPool.h" // for SimpleTextureClientPool
|
||||
#include "ClientReadbackLayer.h" // for ClientReadbackLayer
|
||||
#include "nsAString.h"
|
||||
#include "nsIWidget.h" // for nsIWidget
|
||||
#include "nsIWidgetListener.h"
|
||||
@ -116,6 +117,13 @@ ClientLayerManager::Mutated(Layer* aLayer)
|
||||
mForwarder->Mutated(Hold(aLayer));
|
||||
}
|
||||
|
||||
already_AddRefed<ReadbackLayer>
|
||||
ClientLayerManager::CreateReadbackLayer()
|
||||
{
|
||||
nsRefPtr<ReadbackLayer> layer = new ClientReadbackLayer(this);
|
||||
return layer.forget();
|
||||
}
|
||||
|
||||
void
|
||||
ClientLayerManager::BeginTransactionWithTarget(gfxContext* aTarget)
|
||||
{
|
||||
|
@ -88,6 +88,7 @@ public:
|
||||
virtual already_AddRefed<ContainerLayer> CreateContainerLayer();
|
||||
virtual already_AddRefed<ImageLayer> CreateImageLayer();
|
||||
virtual already_AddRefed<CanvasLayer> CreateCanvasLayer();
|
||||
virtual already_AddRefed<ReadbackLayer> CreateReadbackLayer();
|
||||
virtual already_AddRefed<ColorLayer> CreateColorLayer();
|
||||
virtual already_AddRefed<RefLayer> CreateRefLayer();
|
||||
|
||||
|
33
gfx/layers/client/ClientReadbackLayer.h
Normal file
33
gfx/layers/client/ClientReadbackLayer.h
Normal file
@ -0,0 +1,33 @@
|
||||
/* -*- 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/. */
|
||||
|
||||
#ifndef GFX_CLIENTREADBACKLAYER_H
|
||||
#define GFX_CLIENTREADBACKLAYER_H
|
||||
|
||||
#include "ClientLayerManager.h"
|
||||
#include "ReadbackLayer.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class ClientReadbackLayer :
|
||||
public ReadbackLayer,
|
||||
public ClientLayer
|
||||
{
|
||||
public:
|
||||
ClientReadbackLayer(ClientLayerManager *aManager)
|
||||
: ReadbackLayer(aManager, nullptr)
|
||||
{
|
||||
mImplData = static_cast<ClientLayer*>(this);
|
||||
}
|
||||
|
||||
virtual Layer* AsLayer() { return this; }
|
||||
virtual void RenderLayer() {}
|
||||
};
|
||||
|
||||
} /* layers */
|
||||
} /* mozilla */
|
||||
|
||||
#endif /* GFX_CLIENTREADBACKLAYER_H */
|
@ -24,6 +24,7 @@
|
||||
#include "nsISupportsImpl.h" // for Layer::AddRef, etc
|
||||
#include "nsRect.h" // for nsIntRect
|
||||
#include "gfx2DGlue.h"
|
||||
#include "ReadbackProcessor.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
@ -104,7 +105,7 @@ ClientThebesLayer::PaintThebes()
|
||||
}
|
||||
|
||||
void
|
||||
ClientThebesLayer::RenderLayer()
|
||||
ClientThebesLayer::RenderLayer(ReadbackProcessor *aReadback)
|
||||
{
|
||||
if (GetMaskLayer()) {
|
||||
ToClientLayer(GetMaskLayer())->RenderLayer();
|
||||
@ -120,9 +121,16 @@ ClientThebesLayer::RenderLayer()
|
||||
MOZ_ASSERT(mContentClient->GetForwarder());
|
||||
}
|
||||
|
||||
nsTArray<ReadbackProcessor::Update> readbackUpdates;
|
||||
nsIntRegion readbackRegion;
|
||||
if (aReadback && UsedForReadback()) {
|
||||
aReadback->GetThebesLayerUpdates(this, &readbackUpdates);
|
||||
}
|
||||
|
||||
IntPoint origin(mVisibleRegion.GetBounds().x, mVisibleRegion.GetBounds().y);
|
||||
mContentClient->BeginPaint();
|
||||
PaintThebes();
|
||||
mContentClient->EndPaint();
|
||||
mContentClient->EndPaint(&readbackUpdates);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -69,7 +69,9 @@ public:
|
||||
mValidRegion.Sub(mValidRegion, mInvalidRegion);
|
||||
}
|
||||
|
||||
virtual void RenderLayer();
|
||||
virtual void RenderLayer() { RenderLayer(nullptr); }
|
||||
|
||||
virtual void RenderLayer(ReadbackProcessor *aReadback);
|
||||
|
||||
virtual void ClearCachedResources()
|
||||
{
|
||||
|
@ -36,6 +36,11 @@
|
||||
#include "gfxPlatformGtk.h"
|
||||
#endif
|
||||
#include "gfx2DGlue.h"
|
||||
#include "ReadbackLayer.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@ -101,7 +106,7 @@ ContentClient::CreateContentClient(CompositableForwarder* aForwarder)
|
||||
}
|
||||
|
||||
void
|
||||
ContentClient::EndPaint()
|
||||
ContentClient::EndPaint(nsTArray<ReadbackProcessor::Update>* aReadbackUpdates)
|
||||
{
|
||||
// It is very important that this is called after any overridden EndPaint behaviour,
|
||||
// because destroying textures is a three stage process:
|
||||
@ -157,6 +162,64 @@ ContentClientRemoteBuffer::DestroyBuffers()
|
||||
DestroyFrontBuffer();
|
||||
}
|
||||
|
||||
class RemoteBufferReadbackProcessor : public TextureReadbackSink
|
||||
{
|
||||
public:
|
||||
RemoteBufferReadbackProcessor(nsTArray<ReadbackProcessor::Update>* aReadbackUpdates,
|
||||
const nsIntRect& aBufferRect, const nsIntPoint& aBufferRotation)
|
||||
: mReadbackUpdates(*aReadbackUpdates)
|
||||
, mBufferRect(aBufferRect)
|
||||
, mBufferRotation(aBufferRotation)
|
||||
{
|
||||
for (uint32_t i = 0; i < mReadbackUpdates.Length(); ++i) {
|
||||
mLayerRefs.push_back(mReadbackUpdates[i].mLayer);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void ProcessReadback(gfx::DataSourceSurface *aSourceSurface)
|
||||
{
|
||||
SourceRotatedBuffer rotBuffer(aSourceSurface, nullptr, mBufferRect, mBufferRotation);
|
||||
|
||||
for (uint32_t i = 0; i < mReadbackUpdates.Length(); ++i) {
|
||||
ReadbackProcessor::Update& update = mReadbackUpdates[i];
|
||||
nsIntPoint offset = update.mLayer->GetBackgroundLayerOffset();
|
||||
|
||||
ReadbackSink* sink = update.mLayer->GetSink();
|
||||
|
||||
if (!sink) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!aSourceSurface) {
|
||||
sink->SetUnknown(update.mSequenceCounter);
|
||||
continue;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxContext> ctx =
|
||||
sink->BeginUpdate(update.mUpdateRect + offset, update.mSequenceCounter);
|
||||
|
||||
if (!ctx) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DrawTarget* dt = ctx->GetDrawTarget();
|
||||
dt->SetTransform(Matrix::Translation(offset.x, offset.y));
|
||||
|
||||
rotBuffer.DrawBufferWithRotation(dt, RotatedBuffer::BUFFER_BLACK);
|
||||
|
||||
update.mLayer->GetSink()->EndUpdate(ctx, update.mUpdateRect + offset);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
nsTArray<ReadbackProcessor::Update> mReadbackUpdates;
|
||||
// This array is used to keep the layers alive until the callback.
|
||||
vector<RefPtr<Layer>> mLayerRefs;
|
||||
|
||||
nsIntRect mBufferRect;
|
||||
nsIntPoint mBufferRotation;
|
||||
};
|
||||
|
||||
void
|
||||
ContentClientRemoteBuffer::BeginPaint()
|
||||
{
|
||||
@ -173,8 +236,10 @@ ContentClientRemoteBuffer::BeginPaint()
|
||||
}
|
||||
|
||||
void
|
||||
ContentClientRemoteBuffer::EndPaint()
|
||||
ContentClientRemoteBuffer::EndPaint(nsTArray<ReadbackProcessor::Update>* aReadbackUpdates)
|
||||
{
|
||||
MOZ_ASSERT(!mTextureClientOnWhite || !aReadbackUpdates || aReadbackUpdates->Length() == 0);
|
||||
|
||||
// XXX: We might still not have a texture client if PaintThebes
|
||||
// decided we didn't need one yet because the region to draw was empty.
|
||||
SetBufferProvider(nullptr);
|
||||
@ -187,12 +252,18 @@ ContentClientRemoteBuffer::EndPaint()
|
||||
mOldTextures.Clear();
|
||||
|
||||
if (mTextureClient && mTextureClient->IsLocked()) {
|
||||
if (aReadbackUpdates->Length() > 0) {
|
||||
RefPtr<TextureReadbackSink> readbackSink = new RemoteBufferReadbackProcessor(aReadbackUpdates, mBufferRect, mBufferRotation);
|
||||
|
||||
mTextureClient->SetReadbackSink(readbackSink);
|
||||
}
|
||||
|
||||
mTextureClient->Unlock();
|
||||
}
|
||||
if (mTextureClientOnWhite && mTextureClientOnWhite->IsLocked()) {
|
||||
mTextureClientOnWhite->Unlock();
|
||||
}
|
||||
ContentClientRemote::EndPaint();
|
||||
ContentClientRemote::EndPaint(aReadbackUpdates);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor
|
||||
#include "mozilla/layers/TextureClient.h" // for TextureClient
|
||||
#include "mozilla/mozalloc.h" // for operator delete
|
||||
#include "ReadbackProcessor.h" // For ReadbackProcessor::Update
|
||||
#include "nsCOMPtr.h" // for already_AddRefed
|
||||
#include "nsPoint.h" // for nsIntPoint
|
||||
#include "nsRect.h" // for nsIntRect
|
||||
@ -103,7 +104,7 @@ public:
|
||||
|
||||
// call before and after painting into this content client
|
||||
virtual void BeginPaint() {}
|
||||
virtual void EndPaint();
|
||||
virtual void EndPaint(nsTArray<ReadbackProcessor::Update>* aReadbackUpdates = nullptr);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -231,7 +232,7 @@ public:
|
||||
* are affected by mapping/unmapping.
|
||||
*/
|
||||
virtual void BeginPaint() MOZ_OVERRIDE;
|
||||
virtual void EndPaint() MOZ_OVERRIDE;
|
||||
virtual void EndPaint(nsTArray<ReadbackProcessor::Update>* aReadbackUpdates = nullptr) MOZ_OVERRIDE;
|
||||
|
||||
virtual void Updated(const nsIntRegion& aRegionToDraw,
|
||||
const nsIntRegion& aVisibleRegion,
|
||||
@ -430,7 +431,7 @@ public:
|
||||
const nsIntRegion& aVisibleRegion,
|
||||
bool aDidSelfCopy);
|
||||
|
||||
virtual void EndPaint()
|
||||
virtual void EndPaint(nsTArray<ReadbackProcessor::Update>* aReadbackUpdates = nullptr)
|
||||
{
|
||||
if (IsSurfaceDescriptorValid(mUpdateDescriptor)) {
|
||||
mForwarder->DestroySharedSurface(&mUpdateDescriptor);
|
||||
@ -438,7 +439,7 @@ public:
|
||||
if (IsSurfaceDescriptorValid(mUpdateDescriptorOnWhite)) {
|
||||
mForwarder->DestroySharedSurface(&mUpdateDescriptorOnWhite);
|
||||
}
|
||||
ContentClientRemote::EndPaint();
|
||||
ContentClientRemote::EndPaint(aReadbackUpdates);
|
||||
}
|
||||
|
||||
private:
|
||||
|
Loading…
Reference in New Issue
Block a user