Bug 1328602 - Make it possible to enable the work-in-progress render thread code using MOZ_USE_RENDER_THREAD and ugly branching, hopefully temporarily. r=gfx?

This commit is contained in:
Nicolas Silva 2017-01-18 18:46:21 -05:00
Родитель 05c510435b
Коммит ee383fa898
7 изменённых файлов: 143 добавлений и 43 удалений

Просмотреть файл

@ -1589,16 +1589,20 @@ CompositorBridgeParent::AllocPWebRenderBridgeParent(const wr::PipelineId& aPipel
MOZ_ASSERT(!mCompositorScheduler);
// TODO(nical) Coming soon...
// MOZ_ASSERT(mWidget);
// RefPtr<widget::CompositorWidget> widget = mWidget;
// RefPtr<WebRenderAPI> wr = WebRenderAPI::Create(gfxPrefs::WebRenderProfilerEnabled(), this, Move(widget));
// mWrBridge = new WebRenderBridgeParent(this, aPipelineId, mWidget, Move(wr));
MOZ_ASSERT(mWidget);
if (MOZ_USE_RENDER_THREAD) {
RefPtr<widget::CompositorWidget> widget = mWidget;
RefPtr<wr::WebRenderAPI> api = wr::WebRenderAPI::Create(gfxPrefs::WebRenderProfilerEnabled(), this, Move(widget));
MOZ_ASSERT(api); // TODO have a fallback
api->SetRootPipeline(aPipelineId);
mWrBridge = new WebRenderBridgeParent(this, aPipelineId, mWidget, Move(api));
} else {
RefPtr<gl::GLContext> glc(gl::GLContextProvider::CreateForCompositorWidget(mWidget, true));
mCompositor = new WebRenderCompositorOGL(this, glc.get());
mWrBridge = new WebRenderBridgeParent(this, aPipelineId,
mWidget, glc.get(), nullptr, mCompositor.get());
}
RefPtr<gl::GLContext> glc(gl::GLContextProvider::CreateForCompositorWidget(mWidget, true));
mCompositor = new WebRenderCompositorOGL(this, glc.get());
mWrBridge = new WebRenderBridgeParent(this, aPipelineId,
mWidget, glc.get(), nullptr, mCompositor.get());
mCompositorScheduler = mWrBridge->CompositorScheduler();
MOZ_ASSERT(mCompositorScheduler);
mWrBridge.get()->AddRef(); // IPDL reference
@ -1606,7 +1610,7 @@ CompositorBridgeParent::AllocPWebRenderBridgeParent(const wr::PipelineId& aPipel
auto pipelineHandle = aPipelineId.mHandle;
MOZ_ASSERT(sIndirectLayerTrees[pipelineHandle].mWrBridge == nullptr);
sIndirectLayerTrees[pipelineHandle].mWrBridge = mWrBridge;
*aTextureFactoryIdentifier = mCompositor->GetTextureFactoryIdentifier();
*aTextureFactoryIdentifier = mWrBridge->GetTextureFactoryIdentifier();
return mWrBridge;
}

Просмотреть файл

@ -217,12 +217,19 @@ CrossProcessCompositorBridgeParent::AllocPWebRenderBridgeParent(const wr::Pipeli
CompositorBridgeParent* cbp = sIndirectLayerTrees[pipelineHandle].mParent;
WebRenderBridgeParent* root = sIndirectLayerTrees[cbp->RootLayerTreeId()].mWrBridge.get();
WebRenderBridgeParent* parent = new WebRenderBridgeParent(
this, aPipelineId, nullptr, root->GLContext(), root->WindowState(), root->Compositor());
WebRenderBridgeParent* parent = nullptr;
if (MOZ_USE_RENDER_THREAD) {
RefPtr<wr::WebRenderAPI> api = root->GetWebRenderAPI();
parent = new WebRenderBridgeParent(this, aPipelineId, nullptr, Move(api));
} else {
parent = new WebRenderBridgeParent(this, aPipelineId, nullptr, root->GLContext(),
root->WindowState(), root->Compositor());
}
parent->AddRef(); // IPDL reference
sIndirectLayerTrees[pipelineHandle].mCrossProcessParent = this;
sIndirectLayerTrees[pipelineHandle].mWrBridge = parent;
*aTextureFactoryIdentifier = parent->Compositor()->GetTextureFactoryIdentifier();
*aTextureFactoryIdentifier = parent->GetTextureFactoryIdentifier();
return parent;
}

Просмотреть файл

@ -18,6 +18,7 @@ using WrGlyphArray from "mozilla/webrender/webrender_ffi.h";
using MaybeImageMask from "mozilla/webrender/WebRenderTypes.h";
using mozilla::gfx::Matrix4x4 from "mozilla/gfx/Matrix.h";
using mozilla::wr::ByteBuffer from "mozilla/webrender/WebRenderTypes.h";
using mozilla::wr::PipelineId from "mozilla/webrender/WebRenderTypes.h";
using mozilla::LayerIntRegion from "Units.h";
namespace mozilla {
@ -75,7 +76,7 @@ struct OpDPPushExternalImageId {
struct OpDPPushIframe {
WrRect bounds;
WrRect clip;
uint64_t layersid;
PipelineId pipelineId;
};
struct OpDPPushText {

Просмотреть файл

@ -143,10 +143,11 @@ WebRenderBridgeParent::RecvCreate(const gfx::IntSize& aSize)
if (mBuilder.isSome()) {
return IPC_OK();
}
MOZ_ASSERT(mWRWindowState);
mGLContext->MakeCurrent();
MOZ_ASSERT(mApi || mWRWindowState);
mBuilder.emplace(LayerIntSize(aSize.width, aSize.height), mPipelineId);
wr_window_init_pipeline_epoch(mWRWindowState, mPipelineId.mHandle, aSize.width, aSize.height);
if (!MOZ_USE_RENDER_THREAD) {
wr_window_init_pipeline_epoch(mWRWindowState, mPipelineId.mHandle, aSize.width, aSize.height);
}
return IPC_OK();
}
@ -184,11 +185,16 @@ WebRenderBridgeParent::RecvAddImage(const gfx::IntSize& aSize,
if (mDestroyed) {
return IPC_OK();
}
MOZ_ASSERT(mWRWindowState);
auto format = wr::SurfaceFormatToWrImageFormat(aFormat).value();
*aOutImageKey = wr::ImageKey(wr_add_image(mWRWindowState, aSize.width, aSize.height,
aStride, format,
aBuffer.mData, aBuffer.mLength));
MOZ_ASSERT(mApi || mWRWindowState);
if (MOZ_USE_RENDER_THREAD) {
*aOutImageKey = mApi->AddImageBuffer(aSize, aStride, aFormat,
aBuffer.AsSlice());
} else {
auto format = wr::SurfaceFormatToWrImageFormat(aFormat).value();
*aOutImageKey = wr::ImageKey(wr_add_image(mWRWindowState, aSize.width, aSize.height,
aStride, format,
aBuffer.mData, aBuffer.mLength));
}
return IPC_OK();
}
@ -201,10 +207,14 @@ WebRenderBridgeParent::RecvUpdateImage(const wr::ImageKey& aImageKey,
if (mDestroyed) {
return IPC_OK();
}
MOZ_ASSERT(mWRWindowState);
auto format = wr::SurfaceFormatToWrImageFormat(aFormat).value();
wr_update_image(mWRWindowState, aImageKey.mHandle, aSize.width, aSize.height, format,
aBuffer.mData, aBuffer.mLength);
MOZ_ASSERT(mApi || mWRWindowState);
if (MOZ_USE_RENDER_THREAD) {
mApi->UpdateImageBuffer(aImageKey, aSize, aFormat, aBuffer.AsSlice());
} else {
auto format = wr::SurfaceFormatToWrImageFormat(aFormat).value();
wr_update_image(mWRWindowState, aImageKey.mHandle, aSize.width, aSize.height, format,
aBuffer.mData, aBuffer.mLength);
}
return IPC_OK();
}
@ -214,7 +224,7 @@ WebRenderBridgeParent::RecvDeleteImage(const wr::ImageKey& aImageKey)
if (mDestroyed) {
return IPC_OK();
}
MOZ_ASSERT(mWRWindowState);
MOZ_ASSERT(mApi || mWRWindowState);
mKeysToDelete.push_back(aImageKey);
return IPC_OK();
}
@ -227,7 +237,11 @@ WebRenderBridgeParent::RecvDPBegin(const gfx::IntSize& aSize,
return IPC_OK();
}
MOZ_ASSERT(mBuilder.isSome());
wr_window_dp_begin(mWRWindowState, mBuilder.ref().Raw(), aSize.width, aSize.height);
if (MOZ_USE_RENDER_THREAD) {
mBuilder.ref().Begin(LayerIntSize(aSize.width, aSize.height));
} else {
wr_window_dp_begin(mWRWindowState, mBuilder.ref().Raw(), aSize.width, aSize.height);
}
*aOutSuccess = true;
return IPC_OK();
}
@ -321,6 +335,10 @@ WebRenderBridgeParent::ProcessWebrenderCommands(InfallibleTArray<WebRenderComman
break;
}
case WebRenderCommand::TOpDPPushExternalImageId: {
if (MOZ_USE_RENDER_THREAD) {
// TODO(bug 1328602)
break;
}
const OpDPPushExternalImageId& op = cmd.get_OpDPPushExternalImageId();
MOZ_ASSERT(mExternalImageIds.Get(op.externalImageId()).get());
@ -358,7 +376,15 @@ WebRenderBridgeParent::ProcessWebrenderCommands(InfallibleTArray<WebRenderComman
if (!dSurf->Map(gfx::DataSourceSurface::MapType::READ, &map)) {
break;
}
wr::ImageKey key(wr_add_image(mWRWindowState, validRect.width, validRect.height, map.mStride, RGBA8, map.mData, validRect.height * map.mStride));
wr::ImageKey key;
if (MOZ_USE_RENDER_THREAD) {
auto slice = Range<uint8_t>(map.mData, validRect.height * map.mStride);
key = mApi->AddImageBuffer(validRect.Size(), map.mStride, SurfaceFormat::B8G8R8A8, slice);
} else {
key = wr::ImageKey(wr_add_image(mWRWindowState, validRect.width, validRect.height, map.mStride, RGBA8, map.mData, validRect.height * map.mStride));
}
builder.PushImage(op.bounds(), op.clip(), op.mask().ptrOr(nullptr), op.filter(), key);
keysToDelete.push_back(key);
dSurf->Unmap();
@ -366,7 +392,11 @@ WebRenderBridgeParent::ProcessWebrenderCommands(InfallibleTArray<WebRenderComman
}
case WebRenderCommand::TOpDPPushIframe: {
const OpDPPushIframe& op = cmd.get_OpDPPushIframe();
wr_window_dp_push_iframe(mWRWindowState, builder.Raw(), op.bounds(), op.clip(), op.layersid());
if (MOZ_USE_RENDER_THREAD) {
builder.PushIFrame(op.bounds(), op.clip(), op.pipelineId());
} else {
wr_window_dp_push_iframe(mWRWindowState, builder.Raw(), op.bounds(), op.clip(), op.pipelineId().mHandle);
}
break;
}
case WebRenderCommand::TCompositableOperation: {
@ -385,10 +415,15 @@ WebRenderBridgeParent::ProcessWebrenderCommands(InfallibleTArray<WebRenderComman
const nsTArray<WRGlyphInstance>& glyphs = glyph_array[i].glyphs;
// TODO: We are leaking the key
auto fontKey = wr::FontKey(wr_window_add_raw_font(mWRWindowState,
op.font_buffer().mData,
op.font_buffer_length()));
wr::FontKey fontKey;
if (MOZ_USE_RENDER_THREAD) {
auto slice = Range<uint8_t>(op.font_buffer().mData, op.font_buffer_length());
fontKey = mApi->AddRawFont(slice);
} else {
fontKey = wr::FontKey(wr_window_add_raw_font(mWRWindowState,
op.font_buffer().mData,
op.font_buffer_length()));
}
builder.PushText(op.bounds(),
op.clip(),
glyph_array[i].color,
@ -403,7 +438,14 @@ WebRenderBridgeParent::ProcessWebrenderCommands(InfallibleTArray<WebRenderComman
NS_RUNTIMEABORT("not reached");
}
}
wr_window_dp_end(mWRWindowState, mBuilder.ref().Raw());
if (MOZ_USE_RENDER_THREAD) {
static uint32_t sTodoReplaceMeWithATransactionId = 0;
auto epoch = wr::Epoch(++sTodoReplaceMeWithATransactionId);
builder.End(*mApi, epoch);
} else {
wr_window_dp_end(mWRWindowState, mBuilder.ref().Raw());
}
ScheduleComposition();
DeleteOldImages();
@ -423,6 +465,10 @@ WebRenderBridgeParent::RecvDPGetSnapshot(PTextureParent* aTexture)
if (mDestroyed) {
return IPC_OK();
}
if (MOZ_USE_RENDER_THREAD) {
// TODO(bug 1328602)
return IPC_OK();
}
RefPtr<TextureHost> texture = TextureHost::AsTextureHost(aTexture);
if (!texture) {
@ -469,6 +515,11 @@ WebRenderBridgeParent::RecvAddExternalImageId(const uint64_t& aImageId,
if (mDestroyed) {
return IPC_OK();
}
if (MOZ_USE_RENDER_THREAD) {
// TODO(bug 1328602)
return IPC_OK();
}
MOZ_ASSERT(!mExternalImageIds.Get(aImageId).get());
ImageBridgeParent* imageBridge = ImageBridgeParent::GetInstance(OtherPid());
@ -500,6 +551,10 @@ WebRenderBridgeParent::RecvAddExternalImageIdForCompositable(const uint64_t& aIm
if (mDestroyed) {
return IPC_OK();
}
if (MOZ_USE_RENDER_THREAD) {
// TODO(bug 1328602)
return IPC_OK();
}
MOZ_ASSERT(!mExternalImageIds.Get(aImageId).get());
RefPtr<CompositableHost> host = FindCompositable(aHandle);
@ -522,6 +577,10 @@ WebRenderBridgeParent::RecvRemoveExternalImageId(const uint64_t& aImageId)
if (mDestroyed) {
return IPC_OK();
}
if (MOZ_USE_RENDER_THREAD) {
// TODO(bug 1328602)
return IPC_OK();
}
MOZ_ASSERT(mExternalImageIds.Get(aImageId).get());
mExternalImageIds.Remove(aImageId);
mCompositor->AsWebRenderCompositorOGL()->RemoveExternalImageId(aImageId);
@ -559,7 +618,7 @@ WebRenderBridgeParent::CompositeToTarget(gfx::DrawTarget* aTarget, const gfx::In
return;
}
if (!mCompositor) {
if (MOZ_USE_RENDER_THREAD) {
MOZ_ASSERT(mApi);
// TODO(bug 1328602) With the RenderThread, calling SetRootStackingContext
// should trigger the composition on the render thread.
@ -612,7 +671,11 @@ void
WebRenderBridgeParent::DeleteOldImages()
{
for (wr::ImageKey key : mKeysToDelete) {
wr_delete_image(mWRWindowState, key.mHandle);
if (MOZ_USE_RENDER_THREAD) {
mApi->DeleteImage(key);
} else {
wr_delete_image(mWRWindowState, key.mHandle);
}
}
mKeysToDelete.clear();
}
@ -620,14 +683,14 @@ WebRenderBridgeParent::DeleteOldImages()
void
WebRenderBridgeParent::ScheduleComposition()
{
if (mCompositor) {
mCompositor->AsWebRenderCompositorOGL()->ScheduleComposition();
} else {
if (MOZ_USE_RENDER_THREAD) {
MOZ_ASSERT(mApi);
// TODO(bug 1328602) should probably send a message to the render
// thread and force rendering, although in most cases where this is
// called, rendering should be triggered automatically already (maybe
// not in the ImageBridge case).
} else {
mCompositor->AsWebRenderCompositorOGL()->ScheduleComposition();
}
}
@ -644,7 +707,9 @@ WebRenderBridgeParent::ClearResources()
mExternalImageIds.Clear();
if (mBuilder.isSome()) {
wr_window_remove_pipeline(mWRWindowState, mBuilder.ref().Raw());
if (!MOZ_USE_RENDER_THREAD) {
wr_window_remove_pipeline(mWRWindowState, mBuilder.ref().Raw());
}
mBuilder.reset();
}
if (mCompositorScheduler) {
@ -726,7 +791,11 @@ WebRenderBridgeParent::SetWebRenderProfilerEnabled(bool aEnabled)
{
if (mWidget) {
// Only set the flag to "root" WebRenderBridgeParent.
wr_profiler_set_enabled(mWRWindowState, aEnabled);
if (MOZ_USE_RENDER_THREAD) {
mApi->SetProfilerEnabled(aEnabled);
} else {
wr_profiler_set_enabled(mWRWindowState, aEnabled);
}
}
}

Просмотреть файл

@ -56,6 +56,7 @@ public:
wr::PipelineId PipelineId() { return mPipelineId; }
gl::GLContext* GLContext() { return mGLContext.get(); }
WrWindowState* WindowState() { return mWRWindowState; }
wr::WebRenderAPI* GetWebRenderAPI() { return mApi; }
layers::Compositor* Compositor() { return mCompositor.get(); }
CompositorVsyncScheduler* CompositorScheduler() { return mCompositorScheduler.get(); }

Просмотреть файл

@ -46,7 +46,7 @@ WebRenderRefLayer::RenderLayer()
gfx::Rect relBounds = TransformedVisibleBoundsRelativeToParent();
gfx::Matrix4x4 transform;// = GetTransform();
if (gfxPrefs::LayersDump()) printf_stderr("RefLayer %p (%" PRIu64 ") using %s as bounds/overflow, %s as transform\n", this, mId, Stringify(relBounds).c_str(), Stringify(transform).c_str());
WrBridge()->AddWebRenderCommand(OpDPPushIframe(wr::ToWrRect(relBounds), wr::ToWrRect(relBounds), mId));
WrBridge()->AddWebRenderCommand(OpDPPushIframe(wr::ToWrRect(relBounds), wr::ToWrRect(relBounds), wr::PipelineId(mId)));
}
} // namespace layers

Просмотреть файл

@ -9,6 +9,20 @@
#include "mozilla/webrender/webrender_ffi.h"
#include "mozilla/Maybe.h"
// The infrastructure and plumbing to use the render thread is not entirely in
// place yet. In order to land code and work in parallel we have to maintain
// the two code paths. Hopefully we'll be able to remove this very soon.
// Note that if you are adding code to the non-MOZ_USE_RENDER_THREAD branches
// it is very likely that you are adding work to someone else and thus making
// him very sad.
//
// The MOZ_USE_RENDER_THREAD are disabled by default because they are not in a
// state where tests can pass. As soon as we can pass the test we'll just remove
// the non-MOZ_USE_RENDER_THREAD code.
// In the mean time, if you are working on making the render thread work, change
// define below to true instead of false.
#define MOZ_USE_RENDER_THREAD false
typedef mozilla::Maybe<WrImageMask> MaybeImageMask;
namespace mozilla {
@ -92,6 +106,10 @@ struct ByteBuffer
}
}
const Range<uint8_t> AsSlice() const { return Range<uint8_t>(mData, mLength); }
Range<uint8_t> AsSlice() { return Range<uint8_t>(mData, mLength); }
bool operator==(const ByteBuffer& other) const {
return mLength == other.mLength &&
!(memcmp(mData, other.mData, mLength));