gecko-dev/gfx/webrender_bindings/RenderCompositor.h

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

223 lines
8.3 KiB
C
Raw Normal View History

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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 MOZILLA_GFX_RENDERCOMPOSITOR_H
#define MOZILLA_GFX_RENDERCOMPOSITOR_H
#include "mozilla/ipc/FileDescriptor.h"
#include "mozilla/RefPtr.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/webrender/WebRenderTypes.h"
#include "Units.h"
#include "GLTypes.h"
namespace mozilla {
namespace gl {
class GLContext;
}
namespace layers {
class CompositionRecorder;
class SyncObjectHost;
} // namespace layers
namespace widget {
class CompositorWidget;
}
namespace wr {
class RenderCompositorLayersSWGL;
class RenderCompositorD3D11SWGL;
class RenderCompositor {
public:
static UniquePtr<RenderCompositor> Create(
const RefPtr<widget::CompositorWidget>& aWidget, nsACString& aError);
RenderCompositor(const RefPtr<widget::CompositorWidget>& aWidget);
virtual ~RenderCompositor();
virtual bool BeginFrame() = 0;
// Optional handler in case the frame was aborted allowing the compositor
// to clean up relevant resources if required.
virtual void CancelFrame() {}
// Called to notify the RenderCompositor that all of the commands for a frame
// have been pushed to the queue.
// @return a RenderedFrameId for the frame
virtual RenderedFrameId EndFrame(
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; }
// Check for and return the last completed frame.
// @return the last (highest) completed RenderedFrameId
virtual RenderedFrameId GetLastCompletedFrameId() {
return mLatestRenderFrameId.Prev();
}
// Update FrameId when WR rendering does not happen.
virtual RenderedFrameId UpdateFrameId() { return GetNextRenderFrameId(); }
virtual void Pause() = 0;
virtual bool Resume() = 0;
// Called when WR rendering is skipped
virtual void Update() {}
virtual gl::GLContext* gl() const { return nullptr; }
virtual void* swgl() const { return nullptr; }
virtual bool MakeCurrent();
virtual bool UseANGLE() const { return false; }
virtual bool UseDComp() const { return false; }
virtual bool UseTripleBuffering() const { return false; }
virtual layers::WebRenderBackend BackendType() const {
return layers::WebRenderBackend::HARDWARE;
}
virtual layers::WebRenderCompositor CompositorType() const {
return layers::WebRenderCompositor::DRAW;
}
virtual RenderCompositorD3D11SWGL* AsRenderCompositorD3D11SWGL() {
return nullptr;
}
virtual RenderCompositorLayersSWGL* AsRenderCompositorLayersSWGL() {
return nullptr;
}
// True if AttachExternalImage supports being used with an external
// image that maps to a RenderBufferTextureHost
virtual bool SupportsExternalBufferTextures() const { return false; }
virtual LayoutDeviceIntSize GetBufferSize() = 0;
widget::CompositorWidget* GetWidget() const { return mWidget; }
layers::SyncObjectHost* GetSyncObject() const { return mSyncObject.get(); }
virtual GLenum IsContextLost(bool aForce);
virtual bool SupportAsyncScreenshot() { return true; }
virtual bool ShouldUseNativeCompositor() { return false; }
// Interface for wr::Compositor
virtual void CompositorBeginFrame() {}
virtual void CompositorEndFrame() {}
virtual void Bind(wr::NativeTileId aId, wr::DeviceIntPoint* aOffset,
uint32_t* aFboId, wr::DeviceIntRect aDirtyRect,
wr::DeviceIntRect aValidRect) {}
virtual void Unbind() {}
virtual bool MapTile(wr::NativeTileId aId, wr::DeviceIntRect aDirtyRect,
wr::DeviceIntRect aValidRect, void** aData,
int32_t* aStride) {
return false;
}
virtual void UnmapTile() {}
virtual void CreateSurface(wr::NativeSurfaceId aId,
wr::DeviceIntPoint aVirtualOffset,
wr::DeviceIntSize aTileSize, bool aIsOpaque) {}
virtual void CreateExternalSurface(wr::NativeSurfaceId aId, bool aIsOpaque) {}
virtual void CreateBackdropSurface(wr::NativeSurfaceId aId,
wr::ColorF aColor) {}
virtual void DestroySurface(NativeSurfaceId aId) {}
virtual void CreateTile(wr::NativeSurfaceId, int32_t aX, int32_t aY) {}
virtual void DestroyTile(wr::NativeSurfaceId, int32_t aX, int32_t aY) {}
virtual void AttachExternalImage(wr::NativeSurfaceId aId,
wr::ExternalImageId aExternalImage) {}
virtual void AddSurface(wr::NativeSurfaceId aId,
const wr::CompositorSurfaceTransform& aTransform,
wr::DeviceIntRect aClipRect,
wr::ImageRendering aImageRendering) {}
// Called in the middle of a frame after all surfaces have been added but
// before tiles are updated to signal that early compositing can start
virtual void StartCompositing(wr::ColorF aClearColor,
const wr::DeviceIntRect* aDirtyRects,
size_t aNumDirtyRects,
const wr::DeviceIntRect* aOpaqueRects,
size_t aNumOpaqueRects) {}
virtual void EnableNativeCompositor(bool aEnable) {}
virtual void DeInit() {}
// Overrides any of the default compositor capabilities for behavior this
// compositor might require.
virtual void GetCompositorCapabilities(CompositorCapabilities* aCaps);
virtual void GetWindowVisibility(WindowVisibility* aVisibility);
// Interface for partial present
virtual bool UsePartialPresent() { return false; }
virtual bool RequestFullRender() { return false; }
virtual uint32_t GetMaxPartialPresentRects() { return 0; }
virtual bool ShouldDrawPreviousPartialPresentRegions() { return false; }
// Returns the age of the current backbuffer., This should be used, if
// ShouldDrawPreviousPartialPresentRegions() returns true, to determine the
// region which must be rendered in addition to the current frame's dirty
// rect.
virtual size_t GetBufferAge() const { return 0; }
Bug 1575765 - Implement KHR_partial_update for webrender. r=sotaro,jgilbert KHR_partial_update allows us to avoid rerendering the entire backbuffer every frame, and instead only render what has changed on the current frame, as well as the difference between the current backbuffer and the current frontbuffer. It works similarily to EXT_buffer_age, which we already support, with the additional requirement that we must call eglSetDamageRegion each frame before rendering to the backbuffer. Modify GLContextEGL::GetBufferAge() so that it queries the age if either EXT_buffer_age or KHR_partial_update are available. This will now automatically be queried by webrender through the PartialPresentCompositor trait. Add a new function to that trait, set_buffer_damage_region(), whose RenderCompositorEGL implementation calls eglSetDamageRegion(). Call this from composite_simple(), once the damage rect has been calculated but before rendering to the backbuffer. Additionally, change both RenderCompositorEGL and RenderCompositorOGL's implementations of ShouldDrawPreviousPartialPresentRegions() to unconditionally return true, rather than checking for the existence of EXT_buffer_age (or adding a new check for KHR_partial_update). The lack of these extensions does not mean that webrender is able to skip rendering previous frames' damage. Rather the opposite, it means we cannot render *only* the previous frames' damage, and must instead always render the entire buffer. Differential Revision: https://phabricator.services.mozilla.com/D91203
2020-10-02 10:23:56 +00:00
// Allows webrender to specify the total region that will be rendered to this
// frame, ie the frame's dirty region and some previous frames' dirty regions,
// if applicable (calculated using the buffer age). Must be called before
// anything has been rendered to the main framebuffer.
virtual void SetBufferDamageRegion(const wr::DeviceIntRect* aRects,
size_t aNumRects) {}
// Whether the surface origin is top-left.
virtual bool SurfaceOriginIsTopLeft() { return false; }
// Does readback if wr_renderer_readback() could not get correct WR rendered
// result. It could happen when WebRender renders to multiple overlay layers.
virtual bool MaybeReadback(const gfx::IntSize& aReadbackSize,
const wr::ImageFormat& aReadbackFormat,
const Range<uint8_t>& aReadbackBuffer,
bool* aNeedsYFlip) {
return false;
}
virtual void MaybeRequestAllowFrameRecording(bool aWillRecord) {}
virtual bool MaybeRecordFrame(layers::CompositionRecorder& aRecorder) {
return false;
}
virtual bool MaybeGrabScreenshot(const gfx::IntSize& aWindowSize) {
return false;
}
virtual bool MaybeProcessScreenshotQueue() { return false; }
// Returns FileDescriptor of release fence.
// Release fence is a fence that is used for waiting until usage/composite of
// AHardwareBuffer is ended. The fence is delivered to client side via
// ImageBridge. It is used only on android.
virtual ipc::FileDescriptor GetAndResetReleaseFence() {
return ipc::FileDescriptor();
}
virtual bool IsPaused() { return false; }
protected:
// We default this to 2, so that mLatestRenderFrameId.Prev() is always valid.
RenderedFrameId mLatestRenderFrameId = RenderedFrameId{2};
RenderedFrameId GetNextRenderFrameId() {
mLatestRenderFrameId = mLatestRenderFrameId.Next();
return mLatestRenderFrameId;
}
RefPtr<widget::CompositorWidget> mWidget;
RefPtr<layers::SyncObjectHost> mSyncObject;
};
} // namespace wr
} // namespace mozilla
#endif