зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1322500 - Using CanvasClient for WebRenderCanvasLayer. r=sotaro?
MozReview-Commit-ID: 78zbLjZMXFv
This commit is contained in:
Родитель
3110f868f5
Коммит
e6802f8a0d
|
@ -15,6 +15,7 @@
|
|||
#include "mozilla/layers/WebRenderBridgeChild.h"
|
||||
#include "PersistentBufferProvider.h"
|
||||
#include "SharedSurface.h"
|
||||
#include "SharedSurfaceGL.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
@ -22,86 +23,43 @@ namespace layers {
|
|||
WebRenderCanvasLayer::~WebRenderCanvasLayer()
|
||||
{
|
||||
MOZ_COUNT_DTOR(WebRenderCanvasLayer);
|
||||
|
||||
if (mExternalImageId) {
|
||||
WRBridge()->DeallocExternalImageId(mExternalImageId);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderCanvasLayer::Initialize(const Data& aData)
|
||||
{
|
||||
ShareableCanvasLayer::Initialize(aData);
|
||||
|
||||
// XXX: Use basic surface factory until we support shared surface.
|
||||
if (!mGLContext || mGLFrontbuffer)
|
||||
return;
|
||||
|
||||
gl::GLScreenBuffer* screen = mGLContext->Screen();
|
||||
auto factory = MakeUnique<gl::SurfaceFactory_Basic>(mGLContext, screen->mCaps, mFlags);
|
||||
screen->Morph(Move(factory));
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderCanvasLayer::RenderLayer()
|
||||
{
|
||||
FirePreTransactionCallback();
|
||||
RefPtr<gfx::SourceSurface> surface;
|
||||
// Get the canvas buffer
|
||||
AutoReturnSnapshot autoReturn;
|
||||
if (mAsyncRenderer) {
|
||||
MOZ_ASSERT(!mBufferProvider);
|
||||
MOZ_ASSERT(!mGLContext);
|
||||
surface = mAsyncRenderer->GetSurface();
|
||||
} else if (mGLContext) {
|
||||
gl::SharedSurface* frontbuffer = nullptr;
|
||||
if (mGLFrontbuffer) {
|
||||
frontbuffer = mGLFrontbuffer.get();
|
||||
} else {
|
||||
gl::GLScreenBuffer* screen = mGLContext->Screen();
|
||||
const auto& front = screen->Front();
|
||||
if (front) {
|
||||
frontbuffer = front->Surf();
|
||||
}
|
||||
}
|
||||
UpdateCompositableClient();
|
||||
|
||||
if (!frontbuffer) {
|
||||
NS_WARNING("Null frame received.");
|
||||
return;
|
||||
}
|
||||
|
||||
gfx::IntSize readSize(frontbuffer->mSize);
|
||||
gfx::SurfaceFormat format = (GetContentFlags() & CONTENT_OPAQUE)
|
||||
? gfx::SurfaceFormat::B8G8R8X8
|
||||
: gfx::SurfaceFormat::B8G8R8A8;
|
||||
bool needsPremult = frontbuffer->mHasAlpha && !mIsAlphaPremultiplied;
|
||||
|
||||
RefPtr<gfx::DataSourceSurface> resultSurf = GetTempSurface(readSize, format);
|
||||
// There will already be a warning from inside of GetTempSurface, but
|
||||
// it doesn't hurt to complain:
|
||||
if (NS_WARN_IF(!resultSurf)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Readback handles Flush/MarkDirty.
|
||||
mGLContext->Readback(frontbuffer, resultSurf);
|
||||
if (needsPremult) {
|
||||
gfxUtils::PremultiplyDataSurface(resultSurf, resultSurf);
|
||||
}
|
||||
surface = resultSurf;
|
||||
} else if (mBufferProvider) {
|
||||
surface = mBufferProvider->BorrowSnapshot();
|
||||
autoReturn.mSnapshot = &surface;
|
||||
autoReturn.mBufferProvider = mBufferProvider;
|
||||
}
|
||||
FireDidTransactionCallback();
|
||||
|
||||
if (!surface) {
|
||||
return;
|
||||
if (!mExternalImageId) {
|
||||
mExternalImageId = WRBridge()->AllocExternalImageIdForCompositable(mCanvasClient);
|
||||
}
|
||||
|
||||
WRScrollFrameStackingContextGenerator scrollFrames(this);
|
||||
|
||||
RefPtr<gfx::DataSourceSurface> dataSurface = surface->GetDataSurface();
|
||||
gfx::DataSourceSurface::ScopedMap map(dataSurface, gfx::DataSourceSurface::MapType::READ);
|
||||
//XXX
|
||||
MOZ_RELEASE_ASSERT(surface->GetFormat() == gfx::SurfaceFormat::B8G8R8X8 ||
|
||||
surface->GetFormat() == gfx::SurfaceFormat::B8G8R8A8, "bad format");
|
||||
|
||||
gfx::IntSize size = surface->GetSize();
|
||||
|
||||
WRImageKey key;
|
||||
gfx::ByteBuffer buf(size.height * map.GetStride(), map.GetData());
|
||||
WRBridge()->SendAddImage(size.width, size.height, map.GetStride(), RGBA8, buf, &key);
|
||||
MOZ_ASSERT(mExternalImageId);
|
||||
|
||||
gfx::Matrix4x4 transform;// = GetTransform();
|
||||
const bool needsYFlip = (mOriginPos == gl::OriginPos::BottomLeft);
|
||||
if (needsYFlip) {
|
||||
transform.PreTranslate(0, size.height, 0).PreScale(1, -1, 1);
|
||||
transform.PreTranslate(0, mBounds.height, 0).PreScale(1, -1, 1);
|
||||
}
|
||||
gfx::Rect rect(0, 0, size.width, size.height);
|
||||
gfx::Rect rect(0, 0, mBounds.width, mBounds.height);
|
||||
rect = RelativeToTransformedVisible(GetTransform().TransformBounds(rect));
|
||||
|
||||
gfx::Rect clip;
|
||||
|
@ -115,12 +73,17 @@ WebRenderCanvasLayer::RenderLayer()
|
|||
gfx::Rect overflow(0, 0, relBounds.width, relBounds.height);
|
||||
WRBridge()->AddWebRenderCommand(
|
||||
OpPushDLBuilder(toWrRect(relBounds), toWrRect(overflow), transform, FrameMetrics::NULL_SCROLL_ID));
|
||||
WRBridge()->AddWebRenderCommand(OpDPPushImage(toWrRect(rect), toWrRect(clip), Nothing(), key));
|
||||
Manager()->AddImageKeyForDiscard(key);
|
||||
WRBridge()->AddWebRenderCommand(OpDPPushExternalImageId(toWrRect(rect), toWrRect(clip), Nothing(), mExternalImageId));
|
||||
|
||||
if (gfxPrefs::LayersDump()) printf_stderr("CanvasLayer %p using %s as bounds/overflow, %s for transform\n", this, Stringify(relBounds).c_str(), Stringify(transform).c_str());
|
||||
WRBridge()->AddWebRenderCommand(OpPopDLBuilder());
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderCanvasLayer::AttachCompositable()
|
||||
{
|
||||
mCanvasClient->Connect();
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#ifndef GFX_WEBRENDERCANVASLAYER_H
|
||||
#define GFX_WEBRENDERCANVASLAYER_H
|
||||
|
||||
#include "CopyableCanvasLayer.h"
|
||||
#include "ShareableCanvasLayer.h"
|
||||
#include "WebRenderLayerManager.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -17,15 +17,25 @@ class SourceSurface;
|
|||
namespace layers {
|
||||
|
||||
class WebRenderCanvasLayer : public WebRenderLayer,
|
||||
public CopyableCanvasLayer
|
||||
public ShareableCanvasLayer
|
||||
{
|
||||
public:
|
||||
explicit WebRenderCanvasLayer(WebRenderLayerManager* aLayerManager)
|
||||
: CopyableCanvasLayer(aLayerManager, static_cast<WebRenderLayer*>(this))
|
||||
: ShareableCanvasLayer(aLayerManager, static_cast<WebRenderLayer*>(this))
|
||||
, mExternalImageId(0)
|
||||
{
|
||||
MOZ_COUNT_CTOR(WebRenderCanvasLayer);
|
||||
}
|
||||
|
||||
virtual void Initialize(const Data& aData) override;
|
||||
|
||||
virtual CompositableForwarder* GetForwarder() override
|
||||
{
|
||||
return Manager()->WRBridge();
|
||||
}
|
||||
|
||||
virtual void AttachCompositable() override;
|
||||
|
||||
protected:
|
||||
virtual ~WebRenderCanvasLayer();
|
||||
WebRenderLayerManager* Manager()
|
||||
|
@ -36,6 +46,9 @@ protected:
|
|||
public:
|
||||
Layer* GetLayer() override { return this; }
|
||||
void RenderLayer() override;
|
||||
|
||||
protected:
|
||||
uint64_t mExternalImageId;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
|
Загрузка…
Ссылка в новой задаче