mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-27 04:38:02 +00:00
Bug 1616395 - Remove FfiVec. r=jrmuizel
Use ThinVec instead, which is compatible with nsTArray, and makes stuff much harder to misuse. Differential Revision: https://phabricator.services.mozilla.com/D63256 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
a9e9474027
commit
d18caaa054
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -4660,6 +4660,7 @@ dependencies = [
|
||||
"nsstring",
|
||||
"num_cpus",
|
||||
"rayon",
|
||||
"thin-vec",
|
||||
"thread_profiler",
|
||||
"uuid 0.8.1",
|
||||
"webrender",
|
||||
|
@ -89,9 +89,9 @@ void APZUpdater::CompleteSceneSwap(const wr::WrWindowId& aWindowId,
|
||||
return;
|
||||
}
|
||||
|
||||
for (uintptr_t i = 0; i < aInfo.removed_pipelines.length; i++) {
|
||||
WRRootId layersId = WRRootId(aInfo.removed_pipelines.data[i].pipeline_id,
|
||||
aInfo.removed_pipelines.data[i].document_id);
|
||||
for (const auto& removedPipeline : aInfo.removed_pipelines) {
|
||||
WRRootId layersId =
|
||||
WRRootId(removedPipeline.pipeline_id, removedPipeline.document_id);
|
||||
updater->mEpochData.erase(layersId);
|
||||
}
|
||||
// Reset the built info for all pipelines, then put it back for the ones
|
||||
@ -99,10 +99,9 @@ void APZUpdater::CompleteSceneSwap(const wr::WrWindowId& aWindowId,
|
||||
for (auto& i : updater->mEpochData) {
|
||||
i.second.mBuilt = Nothing();
|
||||
}
|
||||
for (uintptr_t i = 0; i < aInfo.epochs.length; i++) {
|
||||
WRRootId layersId = WRRootId(aInfo.epochs.data[i].pipeline_id,
|
||||
aInfo.epochs.data[i].document_id);
|
||||
updater->mEpochData[layersId].mBuilt = Some(aInfo.epochs.data[i].epoch);
|
||||
for (const auto& epoch : aInfo.epochs) {
|
||||
WRRootId layersId = WRRootId(epoch.pipeline_id, epoch.document_id);
|
||||
updater->mEpochData[layersId].mBuilt = Some(epoch.epoch);
|
||||
}
|
||||
|
||||
// Run any tasks that got unblocked, then unlock the tree. The order is
|
||||
@ -597,9 +596,8 @@ void apz_pre_scene_swap(mozilla::wr::WrWindowId aWindowId) {
|
||||
}
|
||||
|
||||
void apz_post_scene_swap(mozilla::wr::WrWindowId aWindowId,
|
||||
mozilla::wr::WrPipelineInfo aInfo) {
|
||||
mozilla::layers::APZUpdater::CompleteSceneSwap(aWindowId, aInfo);
|
||||
wr_pipeline_info_delete(aInfo);
|
||||
const mozilla::wr::WrPipelineInfo* aInfo) {
|
||||
mozilla::layers::APZUpdater::CompleteSceneSwap(aWindowId, *aInfo);
|
||||
}
|
||||
|
||||
void apz_run_updater(mozilla::wr::WrWindowId aWindowId) {
|
||||
|
@ -2296,7 +2296,7 @@ void CompositorBridgeParent::DidComposite(const VsyncId& aId,
|
||||
|
||||
void CompositorBridgeParent::NotifyDidSceneBuild(
|
||||
const nsTArray<wr::RenderRoot>& aRenderRoots,
|
||||
RefPtr<wr::WebRenderPipelineInfo> aInfo) {
|
||||
RefPtr<const wr::WebRenderPipelineInfo> aInfo) {
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
||||
if (mPaused) {
|
||||
return;
|
||||
|
@ -452,7 +452,7 @@ class CompositorBridgeParent final : public CompositorBridgeParentBase,
|
||||
TimeStamp& aRenderStart, TimeStamp& aCompositeEnd,
|
||||
wr::RendererStats* aStats = nullptr);
|
||||
void NotifyDidSceneBuild(const nsTArray<wr::RenderRoot>& aRenderRoots,
|
||||
RefPtr<wr::WebRenderPipelineInfo> aInfo);
|
||||
RefPtr<const wr::WebRenderPipelineInfo> aInfo);
|
||||
RefPtr<AsyncImagePipelineManager> GetAsyncImagePipelineManager() const;
|
||||
|
||||
PCompositorWidgetParent* AllocPCompositorWidgetParent(
|
||||
|
@ -524,7 +524,8 @@ void AsyncImagePipelineManager::HoldExternalImage(
|
||||
}
|
||||
|
||||
void AsyncImagePipelineManager::NotifyPipelinesUpdated(
|
||||
RefPtr<wr::WebRenderPipelineInfo> aInfo, wr::RenderedFrameId aLatestFrameId,
|
||||
RefPtr<const wr::WebRenderPipelineInfo> aInfo,
|
||||
wr::RenderedFrameId aLatestFrameId,
|
||||
wr::RenderedFrameId aLastCompletedFrameId) {
|
||||
MOZ_ASSERT(wr::RenderThread::IsInRenderThread());
|
||||
MOZ_ASSERT(mLastCompletedFrameId <= aLastCompletedFrameId.mId);
|
||||
@ -532,7 +533,7 @@ void AsyncImagePipelineManager::NotifyPipelinesUpdated(
|
||||
|
||||
// This is called on the render thread, so we just stash the data into
|
||||
// mPendingUpdates and process it later on the compositor thread.
|
||||
mPendingUpdates.push_back(aInfo);
|
||||
mPendingUpdates.push_back(std::move(aInfo));
|
||||
mLastCompletedFrameId = aLastCompletedFrameId.mId;
|
||||
|
||||
{
|
||||
@ -575,12 +576,11 @@ void AsyncImagePipelineManager::ProcessPipelineUpdates() {
|
||||
for (auto pipelineInfo : update.second) {
|
||||
auto& info = pipelineInfo->Raw();
|
||||
|
||||
for (uintptr_t i = 0; i < info.epochs.length; i++) {
|
||||
ProcessPipelineRendered(info.epochs.data[i].pipeline_id,
|
||||
info.epochs.data[i].epoch, update.first);
|
||||
for (auto& epoch : info.epochs) {
|
||||
ProcessPipelineRendered(epoch.pipeline_id, epoch.epoch, update.first);
|
||||
}
|
||||
for (uintptr_t i = 0; i < info.removed_pipelines.length; i++) {
|
||||
ProcessPipelineRemoved(info.removed_pipelines.data[i], update.first);
|
||||
for (auto& removedPipeline : info.removed_pipelines) {
|
||||
ProcessPipelineRemoved(removedPipeline, update.first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ class AsyncImagePipelineManager final {
|
||||
// @param aLatestFrameId RenderedFrameId if a frame has been submitted for
|
||||
// rendering, invalid if not
|
||||
// @param aLastCompletedFrameId RenderedFrameId for the last completed frame
|
||||
void NotifyPipelinesUpdated(RefPtr<wr::WebRenderPipelineInfo> aInfo,
|
||||
void NotifyPipelinesUpdated(RefPtr<const wr::WebRenderPipelineInfo> aInfo,
|
||||
wr::RenderedFrameId aLatestFrameId,
|
||||
wr::RenderedFrameId aLastCompletedFrameId);
|
||||
|
||||
@ -244,7 +244,8 @@ class AsyncImagePipelineManager final {
|
||||
|
||||
nsTArray<ImageCompositeNotificationInfo> mImageCompositeNotifications;
|
||||
|
||||
typedef std::vector<RefPtr<wr::WebRenderPipelineInfo>> PipelineInfoVector;
|
||||
typedef std::vector<RefPtr<const wr::WebRenderPipelineInfo>>
|
||||
PipelineInfoVector;
|
||||
|
||||
// PipelineInfo updates to be processed once a render has been submitted.
|
||||
// This is only accessed on the render thread, so does not need a lock.
|
||||
|
@ -2508,7 +2508,7 @@ void WebRenderBridgeParent::NotifySceneBuiltForEpoch(
|
||||
|
||||
void WebRenderBridgeParent::NotifyDidSceneBuild(
|
||||
const nsTArray<wr::RenderRoot>& aRenderRoots,
|
||||
RefPtr<wr::WebRenderPipelineInfo> aInfo) {
|
||||
RefPtr<const wr::WebRenderPipelineInfo> aInfo) {
|
||||
MOZ_ASSERT(IsRootWebRenderBridgeParent());
|
||||
if (!mCompositorScheduler) {
|
||||
return;
|
||||
@ -2533,10 +2533,8 @@ void WebRenderBridgeParent::NotifyDidSceneBuild(
|
||||
|
||||
// Look through all the pipelines contained within the built scene
|
||||
// and check which vsync they initiated from.
|
||||
auto info = aInfo->Raw();
|
||||
for (uintptr_t i = 0; i < info.epochs.length; i++) {
|
||||
auto epoch = info.epochs.data[i];
|
||||
|
||||
const auto& info = aInfo->Raw();
|
||||
for (const auto& epoch : info.epochs) {
|
||||
WebRenderBridgeParent* wrBridge = this;
|
||||
if (!(epoch.pipeline_id == PipelineId())) {
|
||||
wrBridge = mAsyncImageManager->GetWrBridge(epoch.pipeline_id);
|
||||
|
@ -254,7 +254,7 @@ class WebRenderBridgeParent final
|
||||
void ScheduleForcedGenerateFrame();
|
||||
|
||||
void NotifyDidSceneBuild(const nsTArray<wr::RenderRoot>& aRenderRoots,
|
||||
RefPtr<wr::WebRenderPipelineInfo> aInfo);
|
||||
RefPtr<const wr::WebRenderPipelineInfo> aInfo);
|
||||
|
||||
wr::Epoch UpdateWebRender(
|
||||
CompositorVsyncScheduler* aScheduler,
|
||||
|
@ -46,7 +46,7 @@ class RendererRecordedFrame final : public layers::RecordedFrame {
|
||||
};
|
||||
|
||||
void WebRenderCompositionRecorder::MaybeRecordFrame(
|
||||
wr::Renderer* aRenderer, wr::WebRenderPipelineInfo* aFrameEpochs) {
|
||||
wr::Renderer* aRenderer, const wr::WebRenderPipelineInfo* aFrameEpochs) {
|
||||
MOZ_ASSERT(wr::RenderThread::IsInRenderThread());
|
||||
|
||||
if (!aRenderer || !aFrameEpochs || !DidPaintContent(aFrameEpochs)) {
|
||||
@ -66,30 +66,28 @@ void WebRenderCompositionRecorder::MaybeRecordFrame(
|
||||
}
|
||||
|
||||
bool WebRenderCompositionRecorder::DidPaintContent(
|
||||
wr::WebRenderPipelineInfo* aFrameEpochs) {
|
||||
const wr::WebRenderPipelineInfo* aFrameEpochs) {
|
||||
const wr::WrPipelineInfo& info = aFrameEpochs->Raw();
|
||||
bool didPaintContent = false;
|
||||
|
||||
for (wr::usize i = 0; i < info.epochs.length; i++) {
|
||||
const wr::PipelineId pipelineId = info.epochs.data[i].pipeline_id;
|
||||
for (const auto& epoch : info.epochs) {
|
||||
const wr::PipelineId pipelineId = epoch.pipeline_id;
|
||||
|
||||
if (pipelineId == mRootPipelineId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto it = mContentPipelines.find(AsUint64(pipelineId));
|
||||
if (it == mContentPipelines.end() ||
|
||||
it->second != info.epochs.data[i].epoch) {
|
||||
if (it == mContentPipelines.end() || it->second != epoch.epoch) {
|
||||
// This content pipeline has updated list last render or has newly
|
||||
// rendered.
|
||||
didPaintContent = true;
|
||||
mContentPipelines[AsUint64(pipelineId)] = info.epochs.data[i].epoch;
|
||||
mContentPipelines[AsUint64(pipelineId)] = epoch.epoch;
|
||||
}
|
||||
}
|
||||
|
||||
for (wr::usize i = 0; i < info.removed_pipelines.length; i++) {
|
||||
const wr::PipelineId pipelineId =
|
||||
info.removed_pipelines.data[i].pipeline_id;
|
||||
for (const auto& removedPipeline : info.removed_pipelines) {
|
||||
const wr::PipelineId pipelineId = removedPipeline.pipeline_id;
|
||||
if (pipelineId == mRootPipelineId) {
|
||||
continue;
|
||||
}
|
||||
|
@ -60,13 +60,13 @@ class WebRenderCompositionRecorder final : public CompositionRecorder {
|
||||
* recorder structures.
|
||||
*/
|
||||
void MaybeRecordFrame(wr::Renderer* aRenderer,
|
||||
wr::WebRenderPipelineInfo* aFrameEpochs);
|
||||
const wr::WebRenderPipelineInfo* aFrameEpochs);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Determine if any content pipelines updated.
|
||||
*/
|
||||
bool DidPaintContent(wr::WebRenderPipelineInfo* aFrameEpochs);
|
||||
bool DidPaintContent(const wr::WebRenderPipelineInfo* aFrameEpochs);
|
||||
|
||||
// The id of the root WebRender pipeline.
|
||||
//
|
||||
|
@ -19,6 +19,7 @@ nsstring = { path = "../../xpcom/rust/nsstring" }
|
||||
bincode = "1.0"
|
||||
uuid = { version = "0.8", features = ["v4"] }
|
||||
fxhash = "0.2.1"
|
||||
thin-vec = { version = "0.1.0", features = ["gecko-ffi"] }
|
||||
|
||||
[dependencies.webrender]
|
||||
path = "../wr/webrender"
|
||||
|
@ -42,7 +42,7 @@ class RenderCompositor {
|
||||
// have been pushed to the queue.
|
||||
// @return a RenderedFrameId for the frame
|
||||
virtual RenderedFrameId EndFrame(
|
||||
const FfiVec<DeviceIntRect>& aDirtyRects) = 0;
|
||||
const nsTArray<DeviceIntRect>& aDirtyRects) = 0;
|
||||
// Returns false when waiting gpu tasks is failed.
|
||||
// It might happen when rendering context is lost.
|
||||
virtual bool WaitForGPU() { return true; }
|
||||
|
@ -446,7 +446,7 @@ bool RenderCompositorANGLE::BeginFrame() {
|
||||
}
|
||||
|
||||
RenderedFrameId RenderCompositorANGLE::EndFrame(
|
||||
const FfiVec<DeviceIntRect>& aDirtyRects) {
|
||||
const nsTArray<DeviceIntRect>& aDirtyRects) {
|
||||
RenderedFrameId frameId = GetNextRenderFrameId();
|
||||
InsertGraphicsCommandsFinishedWaitQuery(frameId);
|
||||
|
||||
@ -474,10 +474,9 @@ RenderedFrameId RenderCompositorANGLE::EndFrame(
|
||||
// Clear full render flag.
|
||||
mFullRender = false;
|
||||
// If there is no diry rect, we skip SwapChain present.
|
||||
if (aDirtyRects.length > 0) {
|
||||
StackArray<RECT, 1> rects(aDirtyRects.length);
|
||||
for (uintptr_t i = 0; i < aDirtyRects.length; i++) {
|
||||
const DeviceIntRect& rect = aDirtyRects.data[i];
|
||||
if (!aDirtyRects.IsEmpty()) {
|
||||
StackArray<RECT, 1> rects(aDirtyRects.Length());
|
||||
for (const auto& rect : aDirtyRects) {
|
||||
// Clip rect to bufferSize
|
||||
rects[i].left =
|
||||
std::max(0, std::min(rect.origin.x, bufferSize.width));
|
||||
@ -491,7 +490,7 @@ RenderedFrameId RenderCompositorANGLE::EndFrame(
|
||||
|
||||
DXGI_PRESENT_PARAMETERS params;
|
||||
PodZero(¶ms);
|
||||
params.DirtyRectsCount = aDirtyRects.length;
|
||||
params.DirtyRectsCount = aDirtyRects.Length();
|
||||
params.pDirtyRects = rects.data();
|
||||
|
||||
HRESULT hr;
|
||||
|
@ -40,7 +40,7 @@ class RenderCompositorANGLE : public RenderCompositor {
|
||||
bool Initialize();
|
||||
|
||||
bool BeginFrame() override;
|
||||
RenderedFrameId EndFrame(const FfiVec<DeviceIntRect>& aDirtyRects) final;
|
||||
RenderedFrameId EndFrame(const nsTArray<DeviceIntRect>& aDirtyRects) final;
|
||||
bool WaitForGPU() override;
|
||||
RenderedFrameId GetLastCompletedFrameId() final;
|
||||
RenderedFrameId UpdateFrameId() final;
|
||||
|
@ -90,7 +90,7 @@ bool RenderCompositorEGL::BeginFrame() {
|
||||
}
|
||||
|
||||
RenderedFrameId RenderCompositorEGL::EndFrame(
|
||||
const FfiVec<DeviceIntRect>& aDirtyRects) {
|
||||
const nsTArray<DeviceIntRect>& aDirtyRects) {
|
||||
RenderedFrameId frameId = GetNextRenderFrameId();
|
||||
if (mEGLSurface != EGL_NO_SURFACE) {
|
||||
gl()->SwapBuffers();
|
||||
|
@ -23,7 +23,7 @@ class RenderCompositorEGL : public RenderCompositor {
|
||||
virtual ~RenderCompositorEGL();
|
||||
|
||||
bool BeginFrame() override;
|
||||
RenderedFrameId EndFrame(const FfiVec<DeviceIntRect>& aDirtyRects) final;
|
||||
RenderedFrameId EndFrame(const nsTArray<DeviceIntRect>& aDirtyRects) final;
|
||||
void Pause() override;
|
||||
bool Resume() override;
|
||||
|
||||
|
@ -117,7 +117,7 @@ bool RenderCompositorOGL::BeginFrame() {
|
||||
}
|
||||
|
||||
RenderedFrameId RenderCompositorOGL::EndFrame(
|
||||
const FfiVec<DeviceIntRect>& aDirtyRects) {
|
||||
const nsTArray<DeviceIntRect>& aDirtyRects) {
|
||||
RenderedFrameId frameId = GetNextRenderFrameId();
|
||||
InsertFrameDoneSync();
|
||||
|
||||
|
@ -31,7 +31,7 @@ class RenderCompositorOGL : public RenderCompositor {
|
||||
virtual ~RenderCompositorOGL();
|
||||
|
||||
bool BeginFrame() override;
|
||||
RenderedFrameId EndFrame(const FfiVec<DeviceIntRect>& aDirtyRects) final;
|
||||
RenderedFrameId EndFrame(const nsTArray<DeviceIntRect>& aDirtyRects) final;
|
||||
bool WaitForGPU() override;
|
||||
void Pause() override;
|
||||
bool Resume() override;
|
||||
|
@ -415,7 +415,7 @@ void RenderThread::RunEvent(wr::WindowId aWindowId,
|
||||
}
|
||||
|
||||
static void NotifyDidRender(layers::CompositorBridgeParent* aBridge,
|
||||
RefPtr<WebRenderPipelineInfo> aInfo,
|
||||
RefPtr<const WebRenderPipelineInfo> aInfo,
|
||||
VsyncId aCompositeStartId,
|
||||
TimeStamp aCompositeStart, TimeStamp aRenderStart,
|
||||
TimeStamp aEnd, bool aRender,
|
||||
@ -429,10 +429,10 @@ static void NotifyDidRender(layers::CompositorBridgeParent* aBridge,
|
||||
|
||||
auto info = aInfo->Raw();
|
||||
|
||||
for (uintptr_t i = 0; i < info.epochs.length; i++) {
|
||||
aBridge->NotifyPipelineRendered(
|
||||
info.epochs.data[i].pipeline_id, info.epochs.data[i].epoch,
|
||||
aCompositeStartId, aCompositeStart, aRenderStart, aEnd, &aStats);
|
||||
for (const auto& epoch : info.epochs) {
|
||||
aBridge->NotifyPipelineRendered(epoch.pipeline_id, epoch.epoch,
|
||||
aCompositeStartId, aCompositeStart,
|
||||
aRenderStart, aEnd, &aStats);
|
||||
}
|
||||
|
||||
if (aBridge->GetWrBridge()) {
|
||||
@ -484,7 +484,7 @@ void RenderThread::UpdateAndRender(
|
||||
renderer->CheckGraphicsResetStatus();
|
||||
|
||||
TimeStamp end = TimeStamp::Now();
|
||||
RefPtr<WebRenderPipelineInfo> info = renderer->FlushPipelineInfo();
|
||||
RefPtr<const WebRenderPipelineInfo> info = renderer->FlushPipelineInfo();
|
||||
|
||||
layers::CompositorThreadHolder::Loop()->PostTask(
|
||||
NewRunnableFunction("NotifyDidRenderRunnable", &NotifyDidRender,
|
||||
@ -881,13 +881,6 @@ WebRenderShaders::~WebRenderShaders() {
|
||||
wr_shaders_delete(mShaders, mGL.get());
|
||||
}
|
||||
|
||||
WebRenderPipelineInfo::WebRenderPipelineInfo(wr::WrPipelineInfo aPipelineInfo)
|
||||
: mPipelineInfo(aPipelineInfo) {}
|
||||
|
||||
WebRenderPipelineInfo::~WebRenderPipelineInfo() {
|
||||
wr_pipeline_info_delete(mPipelineInfo);
|
||||
}
|
||||
|
||||
WebRenderThreadPool::WebRenderThreadPool(bool low_priority) {
|
||||
mThreadPool = wr_thread_pool_new(low_priority);
|
||||
}
|
||||
@ -1054,17 +1047,18 @@ void wr_schedule_render(mozilla::wr::WrWindowId aWindowId,
|
||||
|
||||
static void NotifyDidSceneBuild(RefPtr<layers::CompositorBridgeParent> aBridge,
|
||||
const nsTArray<wr::RenderRoot>& aRenderRoots,
|
||||
RefPtr<wr::WebRenderPipelineInfo> aInfo) {
|
||||
RefPtr<const wr::WebRenderPipelineInfo> aInfo) {
|
||||
aBridge->NotifyDidSceneBuild(aRenderRoots, aInfo);
|
||||
}
|
||||
|
||||
void wr_finished_scene_build(mozilla::wr::WrWindowId aWindowId,
|
||||
const mozilla::wr::WrDocumentId* aDocumentIds,
|
||||
size_t aDocumentIdsCount,
|
||||
mozilla::wr::WrPipelineInfo aInfo) {
|
||||
mozilla::wr::WrPipelineInfo* aInfo) {
|
||||
RefPtr<mozilla::layers::CompositorBridgeParent> cbp = mozilla::layers::
|
||||
CompositorBridgeParent::GetCompositorBridgeParentFromWindowId(aWindowId);
|
||||
RefPtr<wr::WebRenderPipelineInfo> info = new wr::WebRenderPipelineInfo(aInfo);
|
||||
RefPtr<wr::WebRenderPipelineInfo> info = new wr::WebRenderPipelineInfo();
|
||||
info->Raw() = std::move(*aInfo);
|
||||
if (cbp) {
|
||||
nsTArray<wr::RenderRoot> renderRoots;
|
||||
renderRoots.SetLength(aDocumentIdsCount);
|
||||
|
@ -93,15 +93,12 @@ class WebRenderShaders final {
|
||||
class WebRenderPipelineInfo final {
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WebRenderPipelineInfo);
|
||||
|
||||
public:
|
||||
explicit WebRenderPipelineInfo(wr::WrPipelineInfo aPipelineInfo);
|
||||
|
||||
const wr::WrPipelineInfo& Raw() { return mPipelineInfo; }
|
||||
const wr::WrPipelineInfo& Raw() const { return mPipelineInfo; }
|
||||
wr::WrPipelineInfo& Raw() { return mPipelineInfo; }
|
||||
|
||||
protected:
|
||||
~WebRenderPipelineInfo();
|
||||
|
||||
const wr::WrPipelineInfo mPipelineInfo;
|
||||
~WebRenderPipelineInfo() = default;
|
||||
wr::WrPipelineInfo mPipelineInfo;
|
||||
};
|
||||
|
||||
/// Base class for an event that can be scheduled to run on the render thread.
|
||||
|
@ -20,23 +20,6 @@
|
||||
namespace mozilla {
|
||||
namespace wr {
|
||||
|
||||
class MOZ_STACK_CLASS AutoWrRenderResult {
|
||||
public:
|
||||
explicit AutoWrRenderResult(WrRenderResult&& aResult) : mResult(aResult) {}
|
||||
|
||||
~AutoWrRenderResult() { wr_render_result_delete(mResult); }
|
||||
|
||||
bool Result() const { return mResult.result; }
|
||||
|
||||
FfiVec<DeviceIntRect> DirtyRects() const { return mResult.dirty_rects; }
|
||||
|
||||
private:
|
||||
const WrRenderResult mResult;
|
||||
|
||||
AutoWrRenderResult(const AutoWrRenderResult&) = delete;
|
||||
AutoWrRenderResult& operator=(const AutoWrRenderResult&) = delete;
|
||||
};
|
||||
|
||||
wr::WrExternalImage wr_renderer_lock_external_image(
|
||||
void* aObj, wr::ExternalImageId aId, uint8_t aChannelIndex,
|
||||
wr::ImageRendering aRendering) {
|
||||
@ -154,9 +137,9 @@ RenderedFrameId RendererOGL::UpdateAndRender(
|
||||
|
||||
auto size = mCompositor->GetBufferSize();
|
||||
|
||||
AutoWrRenderResult result(wr_renderer_render(
|
||||
mRenderer, size.width, size.height, aHadSlowFrame, aOutStats));
|
||||
if (!result.Result()) {
|
||||
nsTArray<DeviceIntRect> dirtyRects;
|
||||
if (!wr_renderer_render(mRenderer, size.width, size.height, aHadSlowFrame,
|
||||
aOutStats, &dirtyRects)) {
|
||||
RenderThread::Get()->HandleWebRenderError(WebRenderError::RENDER);
|
||||
mCompositor->GetWidget()->PostRender(&widgetContext);
|
||||
return RenderedFrameId();
|
||||
@ -176,7 +159,7 @@ RenderedFrameId RendererOGL::UpdateAndRender(
|
||||
|
||||
mScreenshotGrabber.MaybeGrabScreenshot(this, size.ToUnknownSize());
|
||||
|
||||
RenderedFrameId frameId = mCompositor->EndFrame(result.DirtyRects());
|
||||
RenderedFrameId frameId = mCompositor->EndFrame(dirtyRects);
|
||||
|
||||
mCompositor->GetWidget()->PostRender(&widgetContext);
|
||||
|
||||
@ -265,8 +248,9 @@ void RendererOGL::SetFrameStartTime(const TimeStamp& aTime) {
|
||||
}
|
||||
|
||||
RefPtr<WebRenderPipelineInfo> RendererOGL::FlushPipelineInfo() {
|
||||
auto info = wr_renderer_flush_pipeline_info(mRenderer);
|
||||
return new WebRenderPipelineInfo(info);
|
||||
RefPtr<WebRenderPipelineInfo> info = new WebRenderPipelineInfo();
|
||||
wr_renderer_flush_pipeline_info(mRenderer, &info->Raw());
|
||||
return info;
|
||||
}
|
||||
|
||||
RenderTextureHost* RendererOGL::GetRenderTexture(
|
||||
|
@ -40,3 +40,6 @@ bitflags = true
|
||||
"target_os = windows" = "XP_WIN"
|
||||
"target_os = macos" = "XP_MACOSX"
|
||||
"target_os = android" = "ANDROID"
|
||||
|
||||
[export.rename]
|
||||
"ThinVec" = "nsTArray"
|
||||
|
@ -23,6 +23,7 @@ use std::os::raw::{c_void, c_char, c_float};
|
||||
use std::os::raw::{c_int};
|
||||
use std::time::Duration;
|
||||
use gleam::gl;
|
||||
use thin_vec::ThinVec;
|
||||
|
||||
use webrender::{
|
||||
api::*, api::units::*, ApiRecordingReceiver, AsyncPropertySampler, AsyncScreenshotHandle,
|
||||
@ -256,40 +257,6 @@ impl WrVecU8 {
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct FfiVec<T> {
|
||||
// We use a *const instead of a *mut because we don't want the C++ side
|
||||
// to be mutating this. It is strictly read-only from C++
|
||||
data: *const T,
|
||||
length: usize,
|
||||
capacity: usize,
|
||||
}
|
||||
|
||||
impl<T> FfiVec<T> {
|
||||
fn from_vec(v: Vec<T>) -> FfiVec<T> {
|
||||
let ret = FfiVec {
|
||||
data: v.as_ptr(),
|
||||
length: v.len(),
|
||||
capacity: v.capacity(),
|
||||
};
|
||||
mem::forget(v);
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Drop for FfiVec<T> {
|
||||
fn drop(&mut self) {
|
||||
// turn the stuff back into a Vec and let it be freed normally
|
||||
let _ = unsafe {
|
||||
Vec::from_raw_parts(
|
||||
self.data as *mut T,
|
||||
self.length,
|
||||
self.capacity
|
||||
)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wr_vec_u8_push_bytes(v: &mut WrVecU8, bytes: ByteSlice) {
|
||||
v.push_bytes(bytes.as_slice());
|
||||
@ -564,10 +531,11 @@ extern "C" {
|
||||
fn wr_schedule_render(window_id: WrWindowId,
|
||||
document_id_array: *const WrDocumentId,
|
||||
document_id_count: usize);
|
||||
// NOTE: This moves away from pipeline_info.
|
||||
fn wr_finished_scene_build(window_id: WrWindowId,
|
||||
document_id_array: *const WrDocumentId,
|
||||
document_id_count: usize,
|
||||
pipeline_info: WrPipelineInfo);
|
||||
pipeline_info: &mut WrPipelineInfo);
|
||||
|
||||
fn wr_transaction_notification_notified(handler: usize, when: Checkpoint);
|
||||
}
|
||||
@ -621,34 +589,23 @@ pub extern "C" fn wr_renderer_update(renderer: &mut Renderer) {
|
||||
renderer.update();
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct WrRenderResult {
|
||||
result: bool,
|
||||
dirty_rects: FfiVec<DeviceIntRect>,
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wr_render_result_delete(_result: WrRenderResult) {
|
||||
// _result will be dropped here, and the drop impl on FfiVec will free
|
||||
// the underlying vec memory
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wr_renderer_render(renderer: &mut Renderer,
|
||||
width: i32,
|
||||
height: i32,
|
||||
had_slow_frame: bool,
|
||||
out_stats: &mut RendererStats) -> WrRenderResult {
|
||||
pub extern "C" fn wr_renderer_render(
|
||||
renderer: &mut Renderer,
|
||||
width: i32,
|
||||
height: i32,
|
||||
had_slow_frame: bool,
|
||||
out_stats: &mut RendererStats,
|
||||
out_dirty_rects: &mut ThinVec<DeviceIntRect>,
|
||||
) -> bool {
|
||||
if had_slow_frame {
|
||||
renderer.notify_slow_frame();
|
||||
}
|
||||
match renderer.render(DeviceIntSize::new(width, height)) {
|
||||
Ok(results) => {
|
||||
*out_stats = results.stats;
|
||||
WrRenderResult {
|
||||
result: true,
|
||||
dirty_rects: FfiVec::from_vec(results.dirty_rects),
|
||||
}
|
||||
out_dirty_rects.extend(results.dirty_rects);
|
||||
true
|
||||
}
|
||||
Err(errors) => {
|
||||
for e in errors {
|
||||
@ -658,10 +615,7 @@ pub extern "C" fn wr_renderer_render(renderer: &mut Renderer,
|
||||
gfx_critical_note(msg.as_ptr());
|
||||
}
|
||||
}
|
||||
WrRenderResult {
|
||||
result: false,
|
||||
dirty_rects: FfiVec::from_vec(vec![]),
|
||||
}
|
||||
false
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -829,40 +783,36 @@ impl<'a> From<&'a (WrPipelineId, WrDocumentId)> for WrRemovedPipeline {
|
||||
|
||||
#[repr(C)]
|
||||
pub struct WrPipelineInfo {
|
||||
// This contains an entry for each pipeline that was rendered, along with
|
||||
// the epoch at which it was rendered. Rendered pipelines include the root
|
||||
// pipeline and any other pipelines that were reachable via IFrame display
|
||||
// items from the root pipeline.
|
||||
epochs: FfiVec<WrPipelineEpoch>,
|
||||
// This contains an entry for each pipeline that was removed during the
|
||||
// last transaction. These pipelines would have been explicitly removed by
|
||||
// calling remove_pipeline on the transaction object; the pipeline showing
|
||||
// up in this array means that the data structures have been torn down on
|
||||
// the webrender side, and so any remaining data structures on the caller
|
||||
// side can now be torn down also.
|
||||
removed_pipelines: FfiVec<WrRemovedPipeline>,
|
||||
/// This contains an entry for each pipeline that was rendered, along with
|
||||
/// the epoch at which it was rendered. Rendered pipelines include the root
|
||||
/// pipeline and any other pipelines that were reachable via IFrame display
|
||||
/// items from the root pipeline.
|
||||
epochs: ThinVec<WrPipelineEpoch>,
|
||||
/// This contains an entry for each pipeline that was removed during the
|
||||
/// last transaction. These pipelines would have been explicitly removed by
|
||||
/// calling remove_pipeline on the transaction object; the pipeline showing
|
||||
/// up in this array means that the data structures have been torn down on
|
||||
/// the webrender side, and so any remaining data structures on the caller
|
||||
/// side can now be torn down also.
|
||||
removed_pipelines: ThinVec<WrRemovedPipeline>,
|
||||
}
|
||||
|
||||
impl WrPipelineInfo {
|
||||
fn new(info: &PipelineInfo) -> Self {
|
||||
WrPipelineInfo {
|
||||
epochs: FfiVec::from_vec(info.epochs.iter().map(WrPipelineEpoch::from).collect()),
|
||||
removed_pipelines: FfiVec::from_vec(info.removed_pipelines.iter()
|
||||
.map(WrRemovedPipeline::from).collect()),
|
||||
epochs: info.epochs.iter().map(WrPipelineEpoch::from).collect(),
|
||||
removed_pipelines: info.removed_pipelines.iter().map(WrRemovedPipeline::from).collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wr_renderer_flush_pipeline_info(renderer: &mut Renderer) -> WrPipelineInfo {
|
||||
pub unsafe extern "C" fn wr_renderer_flush_pipeline_info(
|
||||
renderer: &mut Renderer,
|
||||
out: &mut WrPipelineInfo,
|
||||
) {
|
||||
let info = renderer.flush_pipeline_info();
|
||||
WrPipelineInfo::new(&info)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wr_pipeline_info_delete(_info: WrPipelineInfo) {
|
||||
// _info will be dropped here, and the drop impl on FfiVec will free
|
||||
// the underlying vec memory
|
||||
*out = WrPipelineInfo::new(&info);
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
@ -912,9 +862,7 @@ extern "C" {
|
||||
// updater thread)
|
||||
fn apz_register_updater(window_id: WrWindowId);
|
||||
fn apz_pre_scene_swap(window_id: WrWindowId);
|
||||
// This function takes ownership of the pipeline_info and is responsible for
|
||||
// freeing it via wr_pipeline_info_delete.
|
||||
fn apz_post_scene_swap(window_id: WrWindowId, pipeline_info: WrPipelineInfo);
|
||||
fn apz_post_scene_swap(window_id: WrWindowId, pipeline_info: &WrPipelineInfo);
|
||||
fn apz_run_updater(window_id: WrWindowId);
|
||||
fn apz_deregister_updater(window_id: WrWindowId);
|
||||
|
||||
@ -955,17 +903,16 @@ impl SceneBuilderHooks for APZCallbacks {
|
||||
}
|
||||
|
||||
fn post_scene_swap(&self, document_ids: &Vec<DocumentId>, info: PipelineInfo, sceneswap_time: u64) {
|
||||
let mut info = WrPipelineInfo::new(&info);
|
||||
unsafe {
|
||||
let info = WrPipelineInfo::new(&info);
|
||||
record_telemetry_time(TelemetryProbe::SceneSwapTime, sceneswap_time);
|
||||
apz_post_scene_swap(self.window_id, info);
|
||||
apz_post_scene_swap(self.window_id, &info);
|
||||
}
|
||||
let info = WrPipelineInfo::new(&info);
|
||||
|
||||
// After a scene swap we should schedule a render for the next vsync,
|
||||
// otherwise there's no guarantee that the new scene will get rendered
|
||||
// anytime soon
|
||||
unsafe { wr_finished_scene_build(self.window_id, document_ids.as_ptr(), document_ids.len(), info) }
|
||||
unsafe { wr_finished_scene_build(self.window_id, document_ids.as_ptr(), document_ids.len(), &mut info) }
|
||||
unsafe { gecko_profiler_end_marker(b"SceneBuilding\0".as_ptr() as *const c_char); }
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@ extern crate nsstring;
|
||||
extern crate rayon;
|
||||
extern crate num_cpus;
|
||||
extern crate thread_profiler;
|
||||
extern crate thin_vec;
|
||||
extern crate bincode;
|
||||
extern crate uuid;
|
||||
extern crate fxhash;
|
||||
|
@ -81,7 +81,7 @@ const uint64_t ROOT_CLIP_CHAIN = ~0;
|
||||
void apz_register_updater(mozilla::wr::WrWindowId aWindowId);
|
||||
void apz_pre_scene_swap(mozilla::wr::WrWindowId aWindowId);
|
||||
void apz_post_scene_swap(mozilla::wr::WrWindowId aWindowId,
|
||||
mozilla::wr::WrPipelineInfo aInfo);
|
||||
const mozilla::wr::WrPipelineInfo* aInfo);
|
||||
void apz_run_updater(mozilla::wr::WrWindowId aWindowId);
|
||||
void apz_deregister_updater(mozilla::wr::WrWindowId aWindowId);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user