Merge graphics to m-c. a=merge

This commit is contained in:
Ryan VanderMeulen 2017-05-30 12:13:40 -04:00
Родитель 5fc4f414f8 e49fb92e99
Коммит aba48c1a5b
61 изменённых файлов: 806 добавлений и 574 удалений

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

@ -114,6 +114,8 @@
#include "mozilla/gfx/GPUProcessManager.h"
#include "mozilla/dom/TimeoutManager.h"
#include "mozilla/PreloadedStyleSheet.h"
#include "mozilla/layers/WebRenderBridgeChild.h"
#include "mozilla/layers/WebRenderLayerManager.h"
#ifdef XP_WIN
#undef GetClassName
@ -2522,6 +2524,14 @@ nsDOMWindowUtils::SetAsyncScrollOffset(nsIDOMNode* aNode,
if (!manager) {
return NS_ERROR_FAILURE;
}
if (WebRenderLayerManager* wrlm = manager->AsWebRenderLayerManager()) {
WebRenderBridgeChild* wrbc = wrlm->WrBridge();
if (!wrbc) {
return NS_ERROR_UNEXPECTED;
}
wrbc->SendSetAsyncScrollOffset(viewId, aX, aY);
return NS_OK;
}
ShadowLayerForwarder* forwarder = manager->AsShadowForwarder();
if (!forwarder || !forwarder->HasShadowManager()) {
return NS_ERROR_UNEXPECTED;
@ -2549,6 +2559,14 @@ nsDOMWindowUtils::SetAsyncZoom(nsIDOMNode* aRootElement, float aValue)
if (!manager) {
return NS_ERROR_FAILURE;
}
if (WebRenderLayerManager* wrlm = manager->AsWebRenderLayerManager()) {
WebRenderBridgeChild* wrbc = wrlm->WrBridge();
if (!wrbc) {
return NS_ERROR_UNEXPECTED;
}
wrbc->SendSetAsyncZoom(viewId, aValue);
return NS_OK;
}
ShadowLayerForwarder* forwarder = manager->AsShadowForwarder();
if (!forwarder || !forwarder->HasShadowManager()) {
return NS_ERROR_UNEXPECTED;
@ -2575,6 +2593,14 @@ nsDOMWindowUtils::FlushApzRepaints(bool* aOutResult)
*aOutResult = false;
return NS_OK;
}
if (WebRenderLayerManager* wrlm = manager->AsWebRenderLayerManager()) {
WebRenderBridgeChild* wrbc = wrlm->WrBridge();
if (!wrbc) {
return NS_ERROR_UNEXPECTED;
}
wrbc->SendFlushApzRepaints();
return NS_OK;
}
ShadowLayerForwarder* forwarder = manager->AsShadowForwarder();
if (!forwarder || !forwarder->HasShadowManager()) {
*aOutResult = false;

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

@ -5215,18 +5215,6 @@ ContentParent::RecvClassifyLocal(const URIParams& aURI, const nsCString& aTables
return IPC_OK();
}
mozilla::ipc::IPCResult
ContentParent::RecvAllocPipelineId(RefPtr<AllocPipelineIdPromise>&& aPromise)
{
GPUProcessManager* pm = GPUProcessManager::Get();
if (!pm) {
aPromise->Reject(PromiseRejectReason::HandlerRejected, __func__);
return IPC_OK();
}
aPromise->Resolve(wr::AsPipelineId(pm->AllocateLayerTreeId()), __func__);
return IPC_OK();
}
mozilla::ipc::IPCResult
ContentParent::RecvFileCreationRequest(const nsID& aID,
const nsString& aFullPath,

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

@ -643,9 +643,6 @@ public:
nsresult* aRv,
nsTArray<nsCString>* aResults) override;
virtual mozilla::ipc::IPCResult
RecvAllocPipelineId(RefPtr<AllocPipelineIdPromise>&& aPromise) override;
// Use the PHangMonitor channel to ask the child to repaint a tab.
void ForceTabPaint(TabParent* aTabParent, uint64_t aLayerObserverEpoch);

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

@ -63,7 +63,6 @@ include MemoryReportTypes;
// are put into different UnifiedProtocolsXX.cpp files.
// XXX Remove this once bug 1069073 is fixed
include "mozilla/dom/PContentBridgeParent.h";
include "mozilla/layers/WebRenderMessageUtils.h";
using GeoPosition from "nsGeoPositionIPCSerialiser.h";
using AlertNotificationType from "mozilla/AlertNotificationIPCSerializer.h";
@ -96,7 +95,6 @@ using mozilla::Telemetry::KeyedAccumulation from "mozilla/TelemetryComms.h";
using mozilla::Telemetry::ScalarAction from "mozilla/TelemetryComms.h";
using mozilla::Telemetry::KeyedScalarAction from "mozilla/TelemetryComms.h";
using mozilla::Telemetry::ChildEventData from "mozilla/TelemetryComms.h";
using mozilla::wr::PipelineId from "mozilla/webrender/WebRenderTypes.h";
union ChromeRegistryItem
{
@ -1104,8 +1102,6 @@ parent:
async AddMemoryReport(MemoryReport aReport);
async FinishMemoryReport(uint32_t aGeneration);
async AllocPipelineId() returns (PipelineId pipelineId);
both:
async AsyncMessage(nsString aMessage, CpowEntry[] aCpows,
Principal aPrincipal, ClonedMessageData aData);

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

@ -79,4 +79,4 @@ to make sure that mozjs_sys also has its Cargo.lock file updated if needed, henc
the need to run the cargo update command in js/src as well. Hopefully this will
be resolved soon.
Latest Commit: 102603520d52f335f152ab74b6bcfdae061b6bc8
Latest Commit: 76a3213080ca5c2e2a612c3023c50c81a111fd55

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

@ -81,8 +81,9 @@ GPUProcessManager::Shutdown()
GPUProcessManager::GPUProcessManager()
: mTaskFactory(this),
mNextLayerTreeId(0),
mNextNamespace(0),
mIdNamespace(0),
mResourceId(0),
mNumProcessAttempts(0),
mDeviceResetCount(0),
mProcess(nullptr),
@ -90,6 +91,7 @@ GPUProcessManager::GPUProcessManager()
{
MOZ_COUNT_CTOR(GPUProcessManager);
mIdNamespace = AllocateNamespace();
mObserver = new Observer(this);
nsContentUtils::RegisterShutdownObserver(mObserver);
@ -888,8 +890,20 @@ GPUProcessManager::IsLayerTreeIdMapped(uint64_t aLayersId, base::ProcessId aRequ
uint64_t
GPUProcessManager::AllocateLayerTreeId()
{
// Allocate tree id by using id namespace.
// By it, tree id does not conflict with external image id and
// async image pipeline id.
MOZ_ASSERT(NS_IsMainThread());
return ++mNextLayerTreeId;
++mResourceId;
if (mResourceId == UINT32_MAX) {
// Move to next id namespace.
mIdNamespace = AllocateNamespace();
mResourceId = 1;
}
uint64_t layerTreeId = mIdNamespace;
layerTreeId = (layerTreeId << 32) | mResourceId;
return layerTreeId;
}
uint32_t

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

@ -244,8 +244,9 @@ private:
RefPtr<Observer> mObserver;
ipc::TaskFactory<GPUProcessManager> mTaskFactory;
RefPtr<VsyncIOThreadHolder> mVsyncIOThread;
uint64_t mNextLayerTreeId;
uint32_t mNextNamespace;
uint32_t mIdNamespace;
uint32_t mResourceId;
uint32_t mNumProcessAttempts;
nsTArray<RefPtr<RemoteCompositorSession>> mRemoteSessions;

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

@ -11,8 +11,8 @@
#include "mozilla/gfx/Matrix.h" // for Matrix4x4, Matrix
#include "mozilla/gfx/Point.h" // for IntSize
#include "nsDebug.h" // for NS_ERROR
#include "nsPoint.h" // for nsIntPoint
#include "nsRect.h" // for mozilla::gfx::IntRect
#include "nsPoint.h" // for nsPoint
#include "nsRect.h" // for nsRect
#include "base/basictypes.h"
using namespace mozilla::gfx;
@ -70,25 +70,38 @@ AppendToString(std::stringstream& aStream, const nsRect& r,
}
void
AppendToString(std::stringstream& aStream, const nsIntPoint& p,
const char* pfx, const char* sfx)
{
aStream << pfx;
aStream << nsPrintfCString("(x=%d, y=%d)", p.x, p.y).get();
aStream << sfx;
}
void
AppendToString(std::stringstream& aStream, const IntRect& r,
AppendToString(std::stringstream& aStream, const WrColor& c,
const char* pfx, const char* sfx)
{
aStream << pfx;
aStream << nsPrintfCString(
"(x=%d, y=%d, w=%d, h=%d)",
"rgba(%d, %d, %d, %f)",
uint8_t(c.r*255.f), uint8_t(c.g*255.f), uint8_t(c.b*255.f), c.a).get();
aStream << sfx;
}
void
AppendToString(std::stringstream& aStream, const WrRect& r,
const char* pfx, const char* sfx)
{
aStream << pfx;
aStream << nsPrintfCString(
"(x=%f, y=%f, w=%f, h=%f)",
r.x, r.y, r.width, r.height).get();
aStream << sfx;
}
void
AppendToString(std::stringstream& aStream, const WrSize& s,
const char* pfx, const char* sfx)
{
aStream << pfx;
aStream << nsPrintfCString(
"(w=%f, h=%f)",
s.width, s.height).get();
aStream << sfx;
}
void
AppendToString(std::stringstream& aStream, const nsRegion& r,
const char* pfx, const char* sfx)

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

@ -18,6 +18,10 @@
#include "nsRegion.h" // for nsRegion, nsIntRegion
#include "nscore.h" // for nsACString, etc
struct WrColor;
struct WrRect;
struct WrSize;
namespace mozilla {
namespace gfx {
template <class units, class F> struct RectTyped;
@ -87,6 +91,18 @@ AppendToString(std::stringstream& aStream, const mozilla::gfx::IntRectTyped<T>&
aStream << sfx;
}
void
AppendToString(std::stringstream& aStream, const WrColor& c,
const char* pfx="", const char* sfx="");
void
AppendToString(std::stringstream& aStream, const WrRect& r,
const char* pfx="", const char* sfx="");
void
AppendToString(std::stringstream& aStream, const WrSize& s,
const char* pfx="", const char* sfx="");
void
AppendToString(std::stringstream& aStream, const nsRegion& r,
const char* pfx="", const char* sfx="");

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

@ -1804,6 +1804,25 @@ APZCTreeManager::GetTargetAPZC(const ScrollableLayerGuid& aGuid)
return apzc.forget();
}
static bool
GuidComparatorIgnoringPresShell(const ScrollableLayerGuid& aOne, const ScrollableLayerGuid& aTwo)
{
return aOne.mLayersId == aTwo.mLayersId
&& aOne.mScrollId == aTwo.mScrollId;
}
already_AddRefed<AsyncPanZoomController>
APZCTreeManager::GetTargetAPZC(const uint64_t& aLayersId,
const FrameMetrics::ViewID& aScrollId)
{
MutexAutoLock lock(mTreeLock);
ScrollableLayerGuid guid(aLayersId, 0, aScrollId);
RefPtr<HitTestingTreeNode> node = GetTargetNode(guid, &GuidComparatorIgnoringPresShell);
MOZ_ASSERT(!node || node->GetApzc()); // any node returned must have an APZC
RefPtr<AsyncPanZoomController> apzc = node ? node->GetApzc() : nullptr;
return apzc.forget();
}
already_AddRefed<HitTestingTreeNode>
APZCTreeManager::GetTargetNode(const ScrollableLayerGuid& aGuid,
GuidComparator aComparator) const
@ -1844,13 +1863,6 @@ APZCTreeManager::GetTargetAPZC(const ScreenPoint& aPoint,
return target.forget();
}
static bool
GuidComparatorIgnoringPresShell(const ScrollableLayerGuid& aOne, const ScrollableLayerGuid& aTwo)
{
return aOne.mLayersId == aTwo.mLayersId
&& aOne.mScrollId == aTwo.mScrollId;
}
RefPtr<const OverscrollHandoffChain>
APZCTreeManager::BuildOverscrollHandoffChain(const RefPtr<AsyncPanZoomController>& aInitialTarget)
{

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

@ -460,6 +460,8 @@ public:
already_AddRefed<AsyncPanZoomController> GetTargetAPZC(const ScreenPoint& aPoint,
HitTestResult* aOutHitResult,
HitTestingTreeNode** aOutScrollbarNode = nullptr);
already_AddRefed<AsyncPanZoomController> GetTargetAPZC(const uint64_t& aLayersId,
const FrameMetrics::ViewID& aScrollId);
ScreenToParentLayerMatrix4x4 GetScreenToApzcTransform(const AsyncPanZoomController *aApzc) const;
ParentLayerToScreenMatrix4x4 GetApzcToGeckoTransform(const AsyncPanZoomController *aApzc) const;

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

@ -14,6 +14,8 @@
#include "mozilla/IntegerPrintfMacros.h"
#include "mozilla/layers/LayerTransactionChild.h"
#include "mozilla/layers/ShadowLayers.h"
#include "mozilla/layers/WebRenderLayerManager.h"
#include "mozilla/layers/WebRenderBridgeChild.h"
#include "mozilla/TouchEvents.h"
#include "nsContentUtils.h"
#include "nsContainerFrame.h"
@ -703,6 +705,13 @@ SendLayersDependentApzcTargetConfirmation(nsIPresShell* aShell, uint64_t aInputB
return;
}
if (WebRenderLayerManager* wrlm = lm->AsWebRenderLayerManager()) {
if (WebRenderBridgeChild* wrbc = wrlm->WrBridge()) {
wrbc->SendSetConfirmedTargetAPZC(aInputBlockId, aTargets);
}
return;
}
LayerTransactionChild* shadow = lm->AsShadowForwarder()->GetShadowManager();
if (!shadow) {
return;

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

@ -79,14 +79,15 @@ Atomic<int32_t> KnowsCompositor::sSerialCounter(0);
CompositorBridgeChild::CompositorBridgeChild(LayerManager *aLayerManager, uint32_t aNamespace)
: mLayerManager(aLayerManager)
, mNamespace(aNamespace)
, mIdNamespace(aNamespace)
, mResourceId(0)
, mCanSend(false)
, mFwdTransactionId(0)
, mDeviceResetSequenceNumber(0)
, mMessageLoop(MessageLoop::current())
, mSectionAllocator(nullptr)
{
MOZ_ASSERT(mNamespace);
MOZ_ASSERT(mIdNamespace);
MOZ_ASSERT(NS_IsMainThread());
}
@ -1169,16 +1170,28 @@ CompositorBridgeChild::DeallocPWebRenderBridgeChild(PWebRenderBridgeChild* aActo
return true;
}
uint64_t
CompositorBridgeChild::GetNextResourceId()
{
++mResourceId;
MOZ_RELEASE_ASSERT(mResourceId != UINT32_MAX);
uint64_t id = mIdNamespace;
id = (id << 32) | mResourceId;
return id;
}
wr::MaybeExternalImageId
CompositorBridgeChild::GetNextExternalImageId()
{
static uint32_t sNextID = 1;
++sNextID;
MOZ_RELEASE_ASSERT(sNextID != UINT32_MAX);
return Some(wr::ToExternalImageId(GetNextResourceId()));
}
uint64_t imageId = mNamespace;
imageId = (imageId << 32) | sNextID;
return Some(wr::ToExternalImageId(imageId));
wr::PipelineId
CompositorBridgeChild::GetNextPipelineId()
{
return wr::AsPipelineId(GetNextResourceId());
}
} // namespace layers

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

@ -235,6 +235,8 @@ public:
wr::MaybeExternalImageId GetNextExternalImageId() override;
wr::PipelineId GetNextPipelineId();
private:
// Private destructor, to discourage deletion outside of Release():
virtual ~CompositorBridgeChild();
@ -268,6 +270,8 @@ private:
already_AddRefed<nsIEventTarget>
GetSpecificMessageEventTarget(const Message& aMsg) override;
uint64_t GetNextResourceId();
// Class used to store the shared FrameMetrics, mutex, and APZCId in a hash table
class SharedFrameMetricsData {
public:
@ -296,7 +300,8 @@ private:
RefPtr<LayerManager> mLayerManager;
uint32_t mNamespace;
uint32_t mIdNamespace;
uint32_t mResourceId;
// When not multi-process, hold a reference to the CompositorBridgeParent to keep it
// alive. This reference should be null in multi-process.

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

@ -1308,10 +1308,10 @@ CompositorBridgeParent::RecvGetFrameUniformity(FrameUniformityData* aOutData)
}
void
CompositorBridgeParent::FlushApzRepaints(const LayerTransactionParent* aLayerTree)
CompositorBridgeParent::FlushApzRepaints(const uint64_t& aLayersId)
{
MOZ_ASSERT(mApzcTreeManager);
uint64_t layersId = aLayerTree->GetId();
uint64_t layersId = aLayersId;
if (layersId == 0) {
// The request is coming from the parent-process layer tree, so we should
// use the compositor's root layer tree id.
@ -1332,9 +1332,9 @@ CompositorBridgeParent::GetAPZTestData(const LayerTransactionParent* aLayerTree,
}
void
CompositorBridgeParent::SetConfirmedTargetAPZC(const LayerTransactionParent* aLayerTree,
const uint64_t& aInputBlockId,
const nsTArray<ScrollableLayerGuid>& aTargets)
CompositorBridgeParent::SetConfirmedTargetAPZC(const uint64_t& aLayersId,
const uint64_t& aInputBlockId,
const nsTArray<ScrollableLayerGuid>& aTargets)
{
if (!mApzcTreeManager) {
return;
@ -1347,7 +1347,6 @@ CompositorBridgeParent::SetConfirmedTargetAPZC(const LayerTransactionParent* aLa
<uint64_t, StoreCopyPassByConstLRef<nsTArray<ScrollableLayerGuid>>>
(mApzcTreeManager.get(), setTargetApzcFunc, aInputBlockId, aTargets);
APZThreadUtils::RunOnControllerThread(task.forget());
}
void

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

@ -108,10 +108,10 @@ public:
virtual void LeaveTestMode(LayerTransactionParent* aLayerTree) { }
virtual void ApplyAsyncProperties(LayerTransactionParent* aLayerTree) = 0;
virtual CompositorAnimationStorage* GetAnimationStorage(const uint64_t& aId) { return nullptr; }
virtual void FlushApzRepaints(const LayerTransactionParent* aLayerTree) = 0;
virtual void FlushApzRepaints(const uint64_t& aLayersId) = 0;
virtual void GetAPZTestData(const LayerTransactionParent* aLayerTree,
APZTestData* aOutData) { }
virtual void SetConfirmedTargetAPZC(const LayerTransactionParent* aLayerTree,
virtual void SetConfirmedTargetAPZC(const uint64_t& aLayersId,
const uint64_t& aInputBlockId,
const nsTArray<ScrollableLayerGuid>& aTargets) = 0;
virtual void UpdatePaintTime(LayerTransactionParent* aLayerTree, const TimeDuration& aPaintTime) {}
@ -231,10 +231,10 @@ public:
virtual void ApplyAsyncProperties(LayerTransactionParent* aLayerTree)
override;
virtual CompositorAnimationStorage* GetAnimationStorage(const uint64_t& aId) override;
virtual void FlushApzRepaints(const LayerTransactionParent* aLayerTree) override;
virtual void FlushApzRepaints(const uint64_t& aLayersId) override;
virtual void GetAPZTestData(const LayerTransactionParent* aLayerTree,
APZTestData* aOutData) override;
virtual void SetConfirmedTargetAPZC(const LayerTransactionParent* aLayerTree,
virtual void SetConfirmedTargetAPZC(const uint64_t& aLayersId,
const uint64_t& aInputBlockId,
const nsTArray<ScrollableLayerGuid>& aTargets) override;
virtual AsyncCompositionManager* GetCompositionManager(LayerTransactionParent* aLayerTree) override { return mCompositionManager; }

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

@ -422,18 +422,17 @@ CrossProcessCompositorBridgeParent::GetAnimationStorage(
}
void
CrossProcessCompositorBridgeParent::FlushApzRepaints(const LayerTransactionParent* aLayerTree)
CrossProcessCompositorBridgeParent::FlushApzRepaints(const uint64_t& aLayersId)
{
uint64_t id = aLayerTree->GetId();
MOZ_ASSERT(id != 0);
MOZ_ASSERT(aLayersId != 0);
const CompositorBridgeParent::LayerTreeState* state =
CompositorBridgeParent::GetIndirectShadowTree(id);
CompositorBridgeParent::GetIndirectShadowTree(aLayersId);
if (!state) {
return;
}
MOZ_ASSERT(state->mParent);
state->mParent->FlushApzRepaints(aLayerTree);
state->mParent->FlushApzRepaints(aLayersId);
}
void
@ -449,19 +448,18 @@ CrossProcessCompositorBridgeParent::GetAPZTestData(
void
CrossProcessCompositorBridgeParent::SetConfirmedTargetAPZC(
const LayerTransactionParent* aLayerTree,
const uint64_t& aLayersId,
const uint64_t& aInputBlockId,
const nsTArray<ScrollableLayerGuid>& aTargets)
{
uint64_t id = aLayerTree->GetId();
MOZ_ASSERT(id != 0);
MOZ_ASSERT(aLayersId != 0);
const CompositorBridgeParent::LayerTreeState* state =
CompositorBridgeParent::GetIndirectShadowTree(id);
CompositorBridgeParent::GetIndirectShadowTree(aLayersId);
if (!state || !state->mParent) {
return;
}
state->mParent->SetConfirmedTargetAPZC(aLayerTree, aInputBlockId, aTargets);
state->mParent->SetConfirmedTargetAPZC(aLayersId, aInputBlockId, aTargets);
}
AsyncCompositionManager*

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

@ -104,10 +104,10 @@ public:
override;
virtual CompositorAnimationStorage*
GetAnimationStorage(const uint64_t& aId) override;
virtual void FlushApzRepaints(const LayerTransactionParent* aLayerTree) override;
virtual void FlushApzRepaints(const uint64_t& aLayersId) override;
virtual void GetAPZTestData(const LayerTransactionParent* aLayerTree,
APZTestData* aOutData) override;
virtual void SetConfirmedTargetAPZC(const LayerTransactionParent* aLayerTree,
virtual void SetConfirmedTargetAPZC(const uint64_t& aLayersId,
const uint64_t& aInputBlockId,
const nsTArray<ScrollableLayerGuid>& aTargets) override;

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

@ -844,7 +844,7 @@ LayerTransactionParent::RecvSetAsyncZoom(const FrameMetrics::ViewID& aScrollID,
mozilla::ipc::IPCResult
LayerTransactionParent::RecvFlushApzRepaints()
{
mCompositorBridge->FlushApzRepaints(this);
mCompositorBridge->FlushApzRepaints(GetId());
return IPC_OK();
}
@ -866,7 +866,7 @@ mozilla::ipc::IPCResult
LayerTransactionParent::RecvSetConfirmedTargetAPZC(const uint64_t& aBlockId,
nsTArray<ScrollableLayerGuid>&& aTargets)
{
mCompositorBridge->SetConfirmedTargetAPZC(this, aBlockId, aTargets);
mCompositorBridge->SetConfirmedTargetAPZC(GetId(), aBlockId, aTargets);
return IPC_OK();
}

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

@ -71,6 +71,10 @@ parent:
async ReleaseLayer(LayerHandle layer);
async ReleaseCompositable(CompositableHandle compositable);
// Tell the compositor to notify APZ that a layer has been confirmed for an
// input event.
async SetConfirmedTargetAPZC(uint64_t aInputBlockId, ScrollableLayerGuid[] aTargets);
// Testing APIs
// Enter test mode, set the sample time to sampleTime, and resample
@ -122,10 +126,6 @@ parent:
// Return the TextureFactoryIdentifier for this compositor.
sync GetTextureFactoryIdentifier() returns (TextureFactoryIdentifier aIdentifier);
// Tell the compositor to notify APZ that a layer has been confirmed for an
// input event.
async SetConfirmedTargetAPZC(uint64_t aInputBlockId, ScrollableLayerGuid[] aTargets);
async RecordPaintTimes(PaintTiming timing);
async Shutdown();

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

@ -14,6 +14,7 @@ include WebRenderMessages;
include protocol PCompositorBridge;
include protocol PTexture;
using struct mozilla::layers::ScrollableLayerGuid from "FrameMetrics.h";
using struct mozilla::layers::TextureInfo from "mozilla/layers/CompositorTypes.h";
using mozilla::layers::CompositableHandle from "mozilla/layers/LayersTypes.h";
using mozilla::wr::ByteBuffer from "mozilla/webrender/WebRenderTypes.h";
@ -67,6 +68,14 @@ parent:
// Schedule a composite if one isn't already scheduled.
async ForceComposite();
// These correspond exactly to the equivalent APIs in PLayerTransaction -
// see those for documentation.
async SetConfirmedTargetAPZC(uint64_t aInputBlockId, ScrollableLayerGuid[] aTargets);
// More copied from PLayerTransaction, but these are only used for testing.
sync SetAsyncScrollOffset(ViewID scrollId, float x, float y);
sync SetAsyncZoom(ViewID scrollId, float zoom);
async FlushApzRepaints();
async Shutdown();
child:
async __delete__();

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

@ -32,12 +32,21 @@ ScrollingLayersHelper::ScrollingLayersHelper(WebRenderLayer* aLayer,
if (!fm.IsScrollable()) {
return;
}
LayoutDeviceRect contentRect = fm.GetExpandedScrollableRect()
* fm.GetDevPixelsPerCSSPixel();
LayerRect contentRect = ViewAs<LayerPixel>(
fm.GetExpandedScrollableRect() * fm.GetDevPixelsPerCSSPixel(),
PixelCastJustification::WebRenderHasUnitResolution);
// TODO: check coordinate systems are sane here
LayerRect clipBounds = ViewAs<LayerPixel>(
fm.GetCompositionBounds(),
PixelCastJustification::MovingDownToChildren);
// The content rect that we hand to PushScrollLayer should be relative to
// the same origin as the clipBounds that we hand to PushScrollLayer - that
// is, both of them should be relative to the stacking context `aStackingContext`.
// However, when we get the scrollable rect from the FrameMetrics, it has
// a nominal top-left of 0,0 (maybe different for RTL pages?) and so to
// get it in the same coordinate space we're going to shift it by the
// composition bounds top-left.
contentRect.MoveBy(clipBounds.TopLeft());
mBuilder->PushScrollLayer(fm.GetScrollId(),
aStackingContext.ToRelativeWrRect(contentRect),
aStackingContext.ToRelativeWrRect(clipBounds));

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

@ -6,6 +6,7 @@
#include "mozilla/layers/WebRenderBridgeParent.h"
#include "apz/src/AsyncPanZoomController.h"
#include "CompositableHost.h"
#include "gfxPrefs.h"
#include "GLContext.h"
@ -275,7 +276,7 @@ WebRenderBridgeParent::RecvDeleteCompositorAnimations(InfallibleTArray<uint64_t>
return IPC_OK();
}
uint64_t storageId = mWidget ? 0 : mPipelineId.mHandle;
uint64_t storageId = mWidget ? 0 : GetLayersId();
CompositorAnimationStorage* storage =
mCompositorBridge->GetAnimationStorage(storageId);
MOZ_ASSERT(storage);
@ -346,9 +347,8 @@ WebRenderBridgeParent::GetRootCompositorBridgeParent() const
// Otherwise, this WebRenderBridgeParent is attached to a
// CrossProcessCompositorBridgeParent so we have an extra level of
// indirection to unravel.
uint64_t layersId = wr::AsUint64(mPipelineId);
CompositorBridgeParent::LayerTreeState* lts =
CompositorBridgeParent::GetIndirectShadowTree(layersId);
CompositorBridgeParent::GetIndirectShadowTree(GetLayersId());
MOZ_ASSERT(lts);
return lts->mParent;
}
@ -367,7 +367,7 @@ WebRenderBridgeParent::UpdateAPZ()
}
if (RefPtr<APZCTreeManager> apzc = cbp->GetAPZCTreeManager()) {
apzc->UpdateHitTestingTree(rootLayersId, rootWrbp->GetScrollData(),
mScrollData.IsFirstPaint(), wr::AsUint64(mPipelineId),
mScrollData.IsFirstPaint(), GetLayersId(),
/* TODO: propagate paint sequence number */ 0);
}
}
@ -538,7 +538,7 @@ WebRenderBridgeParent::ProcessWebRenderCommands(const gfx::IntSize &aSize,
const OpAddCompositorAnimations& op = cmd.get_OpAddCompositorAnimations();
CompositorAnimations data(Move(op.data()));
if (data.animations().Length()) {
uint64_t id = mWidget ? 0 : wr::AsUint64(mPipelineId);
uint64_t id = mWidget ? 0 : GetLayersId();
CompositorAnimationStorage* storage =
mCompositorBridge->GetAnimationStorage(id);
if (storage) {
@ -574,7 +574,7 @@ WebRenderBridgeParent::ProcessWebRenderCommands(const gfx::IntSize &aSize,
DeleteOldImages();
if (ShouldParentObserveEpoch()) {
mCompositorBridge->ObserveLayerUpdate(wr::AsUint64(mPipelineId), GetChildLayerObserverEpoch(), true);
mCompositorBridge->ObserveLayerUpdate(GetLayersId(), GetChildLayerObserverEpoch(), true);
}
}
@ -712,7 +712,7 @@ WebRenderBridgeParent::RecvSetLayerObserverEpoch(const uint64_t& aLayerObserverE
mozilla::ipc::IPCResult
WebRenderBridgeParent::RecvClearCachedResources()
{
mCompositorBridge->ObserveLayerUpdate(wr::AsUint64(mPipelineId), GetChildLayerObserverEpoch(), false);
mCompositorBridge->ObserveLayerUpdate(GetLayersId(), GetChildLayerObserverEpoch(), false);
return IPC_OK();
}
@ -726,6 +726,58 @@ WebRenderBridgeParent::RecvForceComposite()
return IPC_OK();
}
already_AddRefed<AsyncPanZoomController>
WebRenderBridgeParent::GetTargetAPZC(const FrameMetrics::ViewID& aScrollId)
{
RefPtr<AsyncPanZoomController> apzc;
if (CompositorBridgeParent* cbp = GetRootCompositorBridgeParent()) {
if (RefPtr<APZCTreeManager> apzctm = cbp->GetAPZCTreeManager()) {
apzc = apzctm->GetTargetAPZC(GetLayersId(), aScrollId);
}
}
return apzc.forget();
}
mozilla::ipc::IPCResult
WebRenderBridgeParent::RecvSetConfirmedTargetAPZC(const uint64_t& aBlockId,
nsTArray<ScrollableLayerGuid>&& aTargets)
{
mCompositorBridge->SetConfirmedTargetAPZC(GetLayersId(), aBlockId, aTargets);
return IPC_OK();
}
mozilla::ipc::IPCResult
WebRenderBridgeParent::RecvSetAsyncScrollOffset(const FrameMetrics::ViewID& aScrollId,
const float& aX,
const float& aY)
{
RefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(aScrollId);
if (!apzc) {
return IPC_FAIL_NO_REASON(this);
}
apzc->SetTestAsyncScrollOffset(CSSPoint(aX, aY));
return IPC_OK();
}
mozilla::ipc::IPCResult
WebRenderBridgeParent::RecvSetAsyncZoom(const FrameMetrics::ViewID& aScrollId,
const float& aZoom)
{
RefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(aScrollId);
if (!apzc) {
return IPC_FAIL_NO_REASON(this);
}
apzc->SetTestAsyncZoom(LayerToParentLayerScale(aZoom));
return IPC_OK();
}
mozilla::ipc::IPCResult
WebRenderBridgeParent::RecvFlushApzRepaints()
{
mCompositorBridge->FlushApzRepaints(GetLayersId());
return IPC_OK();
}
void
WebRenderBridgeParent::ActorDestroy(ActorDestroyReason aWhy)
{
@ -736,7 +788,7 @@ void
WebRenderBridgeParent::SampleAnimations(nsTArray<WrOpacityProperty>& aOpacityArray,
nsTArray<WrTransformProperty>& aTransformArray)
{
uint64_t id = mWidget ? 0 : wr::AsUint64(mPipelineId);
uint64_t id = mWidget ? 0 : GetLayersId();
CompositorAnimationStorage* storage =
mCompositorBridge->GetAnimationStorage(id);
@ -862,6 +914,12 @@ WebRenderBridgeParent::~WebRenderBridgeParent()
{
}
uint64_t
WebRenderBridgeParent::GetLayersId() const
{
return wr::AsUint64(mPipelineId);
}
void
WebRenderBridgeParent::DeleteOldImages()
{

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

@ -116,6 +116,15 @@ public:
mozilla::ipc::IPCResult RecvClearCachedResources() override;
mozilla::ipc::IPCResult RecvForceComposite() override;
mozilla::ipc::IPCResult RecvSetConfirmedTargetAPZC(const uint64_t& aBlockId,
nsTArray<ScrollableLayerGuid>&& aTargets) override;
mozilla::ipc::IPCResult RecvSetAsyncScrollOffset(const FrameMetrics::ViewID& aScrollId,
const float& aX,
const float& aY) override;
mozilla::ipc::IPCResult RecvSetAsyncZoom(const FrameMetrics::ViewID& aScrollId,
const float& aZoom) override;
mozilla::ipc::IPCResult RecvFlushApzRepaints() override;
void ActorDestroy(ActorDestroyReason aWhy) override;
void SetWebRenderProfilerEnabled(bool aEnabled);
@ -171,6 +180,7 @@ public:
private:
virtual ~WebRenderBridgeParent();
uint64_t GetLayersId() const;
void DeleteOldImages();
void ProcessWebRenderCommands(const gfx::IntSize &aSize,
InfallibleTArray<WebRenderParentCommand>& commands,
@ -203,6 +213,10 @@ private:
// is populated with the property update details.
bool PushAPZStateToWR(nsTArray<WrTransformProperty>& aTransformArray);
// Helper method to get an APZC reference from a scroll id. Uses the layers
// id of this bridge, and may return null if the APZC wasn't found.
already_AddRefed<AsyncPanZoomController> GetTargetAPZC(const FrameMetrics::ViewID& aId);
private:
struct PendingTransactionId {
PendingTransactionId(wr::Epoch aEpoch, uint64_t aId)

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

@ -8,6 +8,7 @@
#include "gfxPrefs.h"
#include "LayersLogging.h"
#include "mozilla/gfx/gfxVars.h"
#include "mozilla/layers/CompositorBridgeChild.h"
#include "mozilla/layers/ImageClient.h"
#include "mozilla/layers/ScrollingLayersHelper.h"
#include "mozilla/layers/StackingContextHelper.h"
@ -31,7 +32,6 @@ WebRenderImageLayer::WebRenderImageLayer(WebRenderLayerManager* aLayerManager)
WebRenderImageLayer::~WebRenderImageLayer()
{
MOZ_COUNT_DTOR(WebRenderImageLayer);
mPipelineIdRequest.DisconnectIfExists();
for (auto key : mVideoKeys) {
WrManager()->AddImageKeyForDiscard(key);
@ -116,24 +116,6 @@ WebRenderImageLayer::RenderLayer(wr::DisplayListBuilder& aBuilder,
MOZ_ASSERT(GetImageClientType() != CompositableType::UNKNOWN);
// Allocate PipelineId if necessary
if (GetImageClientType() == CompositableType::IMAGE_BRIDGE &&
mPipelineId.isNothing() && !mPipelineIdRequest.Exists()) {
// Use Holder to pass this pointer to lambda.
// Static anaysis tool does not permit to pass refcounted variable to lambda.
// And we do not want to use RefPtr<WebRenderImageLayer> here.
Holder holder(this);
WrManager()->AllocPipelineId()
->Then(AbstractThread::MainThread(), __func__,
[holder] (const wr::PipelineId& aPipelineId) {
holder->mPipelineIdRequest.Complete();
holder->mPipelineId = Some(aPipelineId);
},
[holder] (const ipc::PromiseRejectReason &aReason) {
holder->mPipelineIdRequest.Complete();
})->Track(mPipelineIdRequest);
}
if (GetImageClientType() == CompositableType::IMAGE && !mImageClient) {
mImageClient = ImageClient::CreateImageClient(CompositableType::IMAGE,
WrBridge(),
@ -148,6 +130,8 @@ WebRenderImageLayer::RenderLayer(wr::DisplayListBuilder& aBuilder,
if (GetImageClientType() == CompositableType::IMAGE_BRIDGE) {
MOZ_ASSERT(!mImageClient);
mExternalImageId = Some(WrBridge()->AllocExternalImageId(mContainer->GetAsyncContainerHandle()));
// Alloc async image pipeline id.
mPipelineId = Some(WrBridge()->GetCompositorBridgeChild()->GetNextPipelineId());
} else {
// Handle CompositableType::IMAGE case
MOZ_ASSERT(mImageClient);

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

@ -38,16 +38,6 @@ protected:
void AddWRVideoImage(size_t aChannelNumber);
class Holder {
public:
explicit Holder(WebRenderImageLayer* aLayer)
: mLayer(aLayer)
{}
WebRenderImageLayer* operator ->() const { return mLayer; }
private:
WebRenderImageLayer* mLayer;
};
wr::MaybeExternalImageId mExternalImageId;
// Some video image format contains multiple channel data.
nsTArray<wr::ImageKey> mVideoKeys;
@ -56,7 +46,6 @@ protected:
RefPtr<ImageClient> mImageClient;
CompositableType mImageClientTypeContainer;
Maybe<wr::PipelineId> mPipelineId;
MozPromiseRequestHolder<PipelineIdPromise> mPipelineIdRequest;
};
} // namespace layers

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

@ -7,8 +7,6 @@
#include "gfxPrefs.h"
#include "LayersLogging.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/gfx/GPUProcessManager.h"
#include "mozilla/layers/CompositorBridgeChild.h"
#include "mozilla/layers/StackingContextHelper.h"
#include "mozilla/layers/TextureClient.h"
@ -493,25 +491,6 @@ WebRenderLayerManager::Composite()
WrBridge()->SendForceComposite();
}
RefPtr<PipelineIdPromise>
WebRenderLayerManager::AllocPipelineId()
{
if (XRE_IsParentProcess()) {
GPUProcessManager* pm = GPUProcessManager::Get();
if (!pm) {
return PipelineIdPromise::CreateAndReject(ipc::PromiseRejectReason::HandlerRejected, __func__);
}
return PipelineIdPromise::CreateAndResolve(wr::AsPipelineId(pm->AllocateLayerTreeId()), __func__);;
}
MOZ_ASSERT(XRE_IsContentProcess());
RefPtr<dom::ContentChild> contentChild = dom::ContentChild::GetSingleton();
if (!contentChild) {
return PipelineIdPromise::CreateAndReject(ipc::PromiseRejectReason::HandlerRejected, __func__);
}
return contentChild->SendAllocPipelineId();
}
void
WebRenderLayerManager::SetRoot(Layer* aLayer)
{

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

@ -7,7 +7,6 @@
#define GFX_WEBRENDERLAYERMANAGER_H
#include "Layers.h"
#include "mozilla/ipc/MessageChannel.h"
#include "mozilla/MozPromise.h"
#include "mozilla/layers/TransactionIdAllocator.h"
#include "mozilla/webrender/WebRenderTypes.h"
@ -22,8 +21,6 @@ class KnowsCompositor;
class PCompositorBridgeChild;
class WebRenderBridgeChild;
typedef MozPromise<mozilla::wr::PipelineId, mozilla::ipc::PromiseRejectReason, false> PipelineIdPromise;
class WebRenderLayerManager final : public LayerManager
{
typedef nsTArray<RefPtr<Layer> > LayerRefArray;
@ -129,8 +126,6 @@ public:
void SetTransactionIncomplete() { mTransactionIncomplete = true; }
bool IsMutatedLayer(Layer* aLayer);
RefPtr<PipelineIdPromise> AllocPipelineId();
private:
/**
* Take a snapshot of the parent context, and copy

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

@ -25,7 +25,7 @@ gfxQuartzNativeDrawing::BeginNativeDrawing()
DrawTarget *dt = mDrawTarget;
if (dt->IsDualDrawTarget() || dt->IsTiledDrawTarget() ||
dt->GetBackendType() != BackendType::SKIA) {
dt->GetBackendType() != BackendType::SKIA || dt->IsRecording()) {
// We need a DrawTarget that we can get a CGContextRef from:
Matrix transform = dt->GetTransform();

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

@ -34,6 +34,7 @@ plane-split = "0.3"
[dev-dependencies]
angle = {git = "https://github.com/servo/angle", branch = "servo"}
rand = "0.3" # for the benchmarks
servo-glutin = "0.10.1" # for the example apps
[target.'cfg(any(target_os = "android", all(unix, not(target_os = "macos"))))'.dependencies]

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

@ -0,0 +1,23 @@
#![feature(test)]
extern crate rand;
extern crate test;
extern crate webrender;
extern crate webrender_traits;
use rand::Rng;
use test::Bencher;
use webrender::TexturePage;
use webrender_traits::{DeviceUintSize as Size};
#[bench]
fn bench_coalesce(b: &mut Bencher) {
let mut rng = rand::thread_rng();
let mut page = TexturePage::new_dummy(Size::new(10000, 10000));
let mut test_page = TexturePage::new_dummy(Size::new(10000, 10000));
while page.allocate(&Size::new(rng.gen_range(1, 100), rng.gen_range(1, 100))).is_some() {}
b.iter(|| {
test_page.fill_from(&page);
test_page.coalesce();
});
}

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

@ -4,9 +4,9 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
void main(void) {
CachePrimitiveInstance cpi = fetch_cache_instance();
RenderTaskData task = fetch_render_task(cpi.render_task_index);
BoxShadow bs = fetch_boxshadow(cpi.specific_prim_index);
PrimitiveInstance pi = fetch_prim_instance();
RenderTaskData task = fetch_render_task(pi.render_task_index);
BoxShadow bs = fetch_boxshadow(pi.specific_prim_address);
vec2 p0 = task.data0.xy;
vec2 p1 = p0 + task.data0.zw;

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

@ -8,12 +8,12 @@
// as text-shadow.
void main(void) {
CachePrimitiveInstance cpi = fetch_cache_instance();
RenderTaskData task = fetch_render_task(cpi.render_task_index);
TextRun text = fetch_text_run(cpi.specific_prim_index);
Glyph glyph = fetch_glyph(cpi.sub_index);
PrimitiveGeometry pg = fetch_prim_geometry(cpi.global_prim_index);
ResourceRect res = fetch_resource_rect(cpi.user_data.x);
PrimitiveInstance pi = fetch_prim_instance();
RenderTaskData task = fetch_render_task(pi.render_task_index);
TextRun text = fetch_text_run(pi.specific_prim_address);
Glyph glyph = fetch_glyph(pi.user_data0);
PrimitiveGeometry pg = fetch_prim_geometry(pi.global_prim_index);
ResourceRect res = fetch_resource_rect(pi.user_data1);
// Glyphs size is already in device-pixels.
// The render task origin is in device-pixels. Offset that by

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

@ -117,7 +117,7 @@ varying vec3 vClipMaskUv;
#ifdef WR_VERTEX_SHADER
#define VECS_PER_LAYER 13
#define VECS_PER_LAYER 9
#define VECS_PER_RENDER_TASK 3
#define VECS_PER_PRIM_GEOM 2
#define VECS_PER_SPLIT_GEOM 3
@ -133,14 +133,8 @@ uniform sampler2D sData128;
uniform sampler2D sResourceRects;
// Instanced attributes
in int aGlobalPrimId;
in int aPrimitiveAddress;
in int aTaskIndex;
in int aClipTaskIndex;
in int aLayerIndex;
in int aElementIndex;
in ivec2 aUserData;
in int aZIndex;
in ivec4 aData0;
in ivec4 aData1;
// get_fetch_uv is a macro to work around a macOS Intel driver parsing bug.
// TODO: convert back to a function once the driver issues are resolved, if ever.
@ -190,7 +184,6 @@ struct Layer {
mat4 transform;
mat4 inv_transform;
RectWithSize local_clip_rect;
vec4 screen_vertices[4];
};
Layer fetch_layer(int index) {
@ -217,11 +210,6 @@ Layer fetch_layer(int index) {
vec4 clip_rect = texelFetchOffset(sLayers, uv1, 0, ivec2(0, 0));
layer.local_clip_rect = RectWithSize(clip_rect.xy, clip_rect.zw);
layer.screen_vertices[0] = texelFetchOffset(sLayers, uv1, 0, ivec2(1, 0));
layer.screen_vertices[1] = texelFetchOffset(sLayers, uv1, 0, ivec2(2, 0));
layer.screen_vertices[2] = texelFetchOffset(sLayers, uv1, 0, ivec2(3, 0));
layer.screen_vertices[3] = texelFetchOffset(sLayers, uv1, 0, ivec2(4, 0));
return layer;
}
@ -447,50 +435,51 @@ PrimitiveGeometry fetch_prim_geometry(int index) {
struct PrimitiveInstance {
int global_prim_index;
int specific_prim_index;
int specific_prim_address;
int render_task_index;
int clip_task_index;
int layer_index;
int sub_index;
int z;
ivec2 user_data;
int user_data0;
int user_data1;
};
PrimitiveInstance fetch_prim_instance() {
PrimitiveInstance pi;
pi.global_prim_index = aGlobalPrimId;
pi.specific_prim_index = aPrimitiveAddress;
pi.render_task_index = aTaskIndex;
pi.clip_task_index = aClipTaskIndex;
pi.layer_index = aLayerIndex;
pi.sub_index = aElementIndex;
pi.user_data = aUserData;
pi.z = aZIndex;
pi.global_prim_index = aData0.x;
pi.specific_prim_address = aData0.y;
pi.render_task_index = aData0.z;
pi.clip_task_index = aData0.w;
pi.layer_index = aData1.x;
pi.z = aData1.y;
pi.user_data0 = aData1.z;
pi.user_data1 = aData1.w;
return pi;
}
struct CachePrimitiveInstance {
int global_prim_index;
int specific_prim_index;
struct CompositeInstance {
int render_task_index;
int sub_index;
ivec2 user_data;
int src_task_index;
int backdrop_task_index;
int user_data0;
int user_data1;
float z;
};
CachePrimitiveInstance fetch_cache_instance() {
CachePrimitiveInstance cpi;
CompositeInstance fetch_composite_instance() {
CompositeInstance ci;
PrimitiveInstance pi = fetch_prim_instance();
ci.render_task_index = aData0.x;
ci.src_task_index = aData0.y;
ci.backdrop_task_index = aData0.z;
ci.z = float(aData0.w);
cpi.global_prim_index = pi.global_prim_index;
cpi.specific_prim_index = pi.specific_prim_index;
cpi.render_task_index = pi.render_task_index;
cpi.sub_index = pi.sub_index;
cpi.user_data = pi.user_data;
ci.user_data0 = aData1.x;
ci.user_data1 = aData1.y;
return cpi;
return ci;
}
struct Primitive {
@ -500,10 +489,8 @@ struct Primitive {
RectWithSize local_rect;
RectWithSize local_clip_rect;
int prim_index;
// when sending multiple primitives of the same type (e.g. border segments)
// this index allows the vertex shader to recognize the difference
int sub_index;
ivec2 user_data;
int user_data0;
int user_data1;
float z;
};
@ -518,9 +505,9 @@ Primitive load_primitive_custom(PrimitiveInstance pi) {
prim.local_rect = pg.local_rect;
prim.local_clip_rect = pg.local_clip_rect;
prim.prim_index = pi.specific_prim_index;
prim.sub_index = pi.sub_index;
prim.user_data = pi.user_data;
prim.prim_index = pi.specific_prim_address;
prim.user_data0 = pi.user_data0;
prim.user_data1 = pi.user_data1;
prim.z = float(pi.z);
return prim;
@ -539,7 +526,7 @@ Primitive load_primitive() {
bool ray_plane(vec3 normal, vec3 point, vec3 ray_origin, vec3 ray_dir, out float t)
{
float denom = dot(normal, ray_dir);
if (denom > 1e-6) {
if (abs(denom) > 1e-6) {
vec3 d = point - ray_origin;
t = dot(d, normal) / denom;
return t >= 0.0;
@ -568,12 +555,11 @@ vec4 untransform(vec2 ref, vec3 n, vec3 a, mat4 inv_transform) {
// Given a CSS space position, transform it back into the layer space.
vec4 get_layer_pos(vec2 pos, Layer layer) {
// get 3 of the layer corners in CSS space
vec3 a = layer.screen_vertices[0].xyz / layer.screen_vertices[0].w;
vec3 b = layer.screen_vertices[3].xyz / layer.screen_vertices[3].w;
vec3 c = layer.screen_vertices[2].xyz / layer.screen_vertices[2].w;
// get a point on the layer plane
vec4 ah = layer.transform * vec4(0.0, 0.0, 0.0, 1.0);
vec3 a = ah.xyz / ah.w;
// get the normal to the layer plane
vec3 n = normalize(cross(b-a, c-a));
vec3 n = transpose(mat3(layer.inv_transform)) * vec3(0.0, 0.0, 1.0);
return untransform(pos, n, a, layer.inv_transform);
}

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

@ -27,7 +27,7 @@ void main(void) {
vTileRepeat = gradient.tile_size_repeat.zw;
// V coordinate of gradient row in lookup texture.
vGradientIndex = float(prim.sub_index);
vGradientIndex = float(prim.user_data0);
// The texture size of the lookup texture
vGradientTextureSize = vec2(textureSize(sGradients, 0));

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

@ -4,9 +4,9 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
void main(void) {
PrimitiveInstance pi = fetch_prim_instance();
AlphaBatchTask dest_task = fetch_alpha_batch_task(pi.render_task_index);
AlphaBatchTask src_task = fetch_alpha_batch_task(pi.user_data.x);
CompositeInstance ci = fetch_composite_instance();
AlphaBatchTask dest_task = fetch_alpha_batch_task(ci.render_task_index);
AlphaBatchTask src_task = fetch_alpha_batch_task(ci.src_task_index);
vec2 dest_origin = dest_task.render_target_origin -
dest_task.screen_space_origin +
@ -24,8 +24,8 @@ void main(void) {
vUv = vec3(uv / texture_size, src_task.render_target_layer_index);
vUvBounds = vec4(st0 + 0.5, st1 - 0.5) / texture_size.xyxy;
vOp = pi.sub_index;
vAmount = float(pi.user_data.y) / 65535.0;
vOp = ci.user_data0;
vAmount = float(ci.user_data1) / 65535.0;
gl_Position = uTransform * vec4(local_pos, pi.z, 1.0);
gl_Position = uTransform * vec4(local_pos, ci.z, 1.0);
}

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

@ -91,6 +91,7 @@ int select_style(int color_select, vec2 fstyle) {
switch (color_select) {
case SIDE_BOTH:
{
// TODO(gw): A temporary hack! While we don't support
// border corners that have dots or dashes
// with another style, pretend they are solid
@ -102,6 +103,7 @@ int select_style(int color_select, vec2 fstyle) {
if (style.x != style.y && (has_dots || has_dashes))
return BORDER_STYLE_SOLID;
return style.x;
}
case SIDE_FIRST:
return style.x;
case SIDE_SECOND:
@ -112,7 +114,7 @@ int select_style(int color_select, vec2 fstyle) {
void main(void) {
Primitive prim = load_primitive();
Border border = fetch_border(prim.prim_index);
int sub_part = prim.sub_index;
int sub_part = prim.user_data0;
BorderCorners corners = get_border_corners(border, prim.local_rect);
vec2 p0, p1;
@ -135,7 +137,7 @@ void main(void) {
color1 = border.colors[1];
vClipCenter = corners.tl_outer + border.radii[0].xy;
vClipSign = vec2(1.0);
style = select_style(prim.user_data.x, border.style.yx);
style = select_style(prim.user_data1, border.style.yx);
vec4 adjusted_widths = get_effective_border_widths(border, style);
vec4 inv_adjusted_widths = border.widths - adjusted_widths;
set_radii(style,
@ -157,7 +159,7 @@ void main(void) {
color1 = border.colors[2];
vClipCenter = corners.tr_outer + vec2(-border.radii[0].z, border.radii[0].w);
vClipSign = vec2(-1.0, 1.0);
style = select_style(prim.user_data.x, border.style.zy);
style = select_style(prim.user_data1, border.style.zy);
vec4 adjusted_widths = get_effective_border_widths(border, style);
vec4 inv_adjusted_widths = border.widths - adjusted_widths;
set_radii(style,
@ -181,7 +183,7 @@ void main(void) {
color1 = border.colors[3];
vClipCenter = corners.br_outer - border.radii[1].xy;
vClipSign = vec2(-1.0, -1.0);
style = select_style(prim.user_data.x, border.style.wz);
style = select_style(prim.user_data1, border.style.wz);
vec4 adjusted_widths = get_effective_border_widths(border, style);
vec4 inv_adjusted_widths = border.widths - adjusted_widths;
set_radii(style,
@ -205,7 +207,7 @@ void main(void) {
color1 = border.colors[0];
vClipCenter = corners.bl_outer + vec2(border.radii[1].z, -border.radii[1].w);
vClipSign = vec2(1.0, -1.0);
style = select_style(prim.user_data.x, border.style.xw);
style = select_style(prim.user_data1, border.style.xw);
vec4 adjusted_widths = get_effective_border_widths(border, style);
vec4 inv_adjusted_widths = border.widths - adjusted_widths;
set_radii(style,
@ -253,7 +255,7 @@ void main(void) {
}
}
write_color(color0, color1, style, color_delta, prim.user_data.x);
write_color(color0, color1, style, color_delta, prim.user_data1);
RectWithSize segment_rect;
segment_rect.p0 = p0;

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

@ -42,11 +42,15 @@ void write_color(vec4 color, float style, bool flip) {
switch (int(style)) {
case BORDER_STYLE_GROOVE:
{
modulate = flip ? vec2(1.3, 0.7) : vec2(0.7, 1.3);
break;
}
case BORDER_STYLE_RIDGE:
{
modulate = flip ? vec2(0.7, 1.3) : vec2(1.3, 0.7);
break;
}
default:
modulate = vec2(1.0);
break;
@ -101,7 +105,7 @@ void write_clip_params(float style,
void main(void) {
Primitive prim = load_primitive();
Border border = fetch_border(prim.prim_index);
int sub_part = prim.sub_index;
int sub_part = prim.user_data0;
BorderCorners corners = get_border_corners(border, prim.local_rect);
vec4 color = border.colors[sub_part];

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

@ -6,7 +6,7 @@
void main(void) {
Primitive prim = load_primitive();
BoxShadow bs = fetch_boxshadow(prim.prim_index);
RectWithSize segment_rect = fetch_instance_geometry(prim.sub_index);
RectWithSize segment_rect = fetch_instance_geometry(prim.user_data0);
VertexInfo vi = write_vertex(segment_rect,
prim.local_clip_rect,
@ -15,7 +15,7 @@ void main(void) {
prim.task,
prim.local_rect.p0);
RenderTaskData child_task = fetch_render_task(prim.user_data.x);
RenderTaskData child_task = fetch_render_task(prim.user_data1);
vUv.z = child_task.data1.x;
// Constant offsets to inset from bilinear filtering border.

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

@ -16,7 +16,7 @@ void main(void) {
prim.task,
prim.local_rect.p0);
RenderTaskData child_task = fetch_render_task(prim.user_data.x);
RenderTaskData child_task = fetch_render_task(prim.user_data1);
vUv.z = child_task.data1.x;
vec2 texture_size = vec2(textureSize(sCacheRGBA8, 0));

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

@ -4,10 +4,10 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
void main(void) {
PrimitiveInstance pi = fetch_prim_instance();
AlphaBatchTask dest_task = fetch_alpha_batch_task(pi.render_task_index);
ReadbackTask backdrop_task = fetch_readback_task(pi.user_data.x);
AlphaBatchTask src_task = fetch_alpha_batch_task(pi.user_data.y);
CompositeInstance ci = fetch_composite_instance();
AlphaBatchTask dest_task = fetch_alpha_batch_task(ci.render_task_index);
ReadbackTask backdrop_task = fetch_readback_task(ci.backdrop_task_index);
AlphaBatchTask src_task = fetch_alpha_batch_task(ci.src_task_index);
vec2 dest_origin = dest_task.render_target_origin -
dest_task.screen_space_origin +
@ -27,8 +27,7 @@ void main(void) {
st1 = (src_task.render_target_origin + src_task.size) / texture_size;
vUv1 = vec3(mix(st0, st1, aPosition.xy), src_task.render_target_layer_index);
vOp = pi.sub_index;
gl_Position = uTransform * vec4(local_pos, pi.z, 1.0);
vOp = ci.user_data0;
gl_Position = uTransform * vec4(local_pos, ci.z, 1.0);
}

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

@ -9,8 +9,8 @@ void main(void) {
vec4 abs_start_end_point = gradient.start_end_point + prim.local_rect.p0.xyxy;
GradientStop g0 = fetch_gradient_stop(prim.sub_index + 0);
GradientStop g1 = fetch_gradient_stop(prim.sub_index + 1);
GradientStop g0 = fetch_gradient_stop(prim.user_data0 + 0);
GradientStop g1 = fetch_gradient_stop(prim.user_data0 + 1);
RectWithSize segment_rect;
vec2 axis;

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

@ -4,9 +4,9 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
void main(void) {
PrimitiveInstance pi = fetch_prim_instance();
AlphaBatchTask dest_task = fetch_alpha_batch_task(pi.render_task_index);
AlphaBatchTask src_task = fetch_alpha_batch_task(pi.user_data.x);
CompositeInstance ci = fetch_composite_instance();
AlphaBatchTask dest_task = fetch_alpha_batch_task(ci.render_task_index);
AlphaBatchTask src_task = fetch_alpha_batch_task(ci.src_task_index);
vec2 dest_origin = dest_task.render_target_origin -
dest_task.screen_space_origin +
@ -21,5 +21,5 @@ void main(void) {
vec2 st1 = (src_task.render_target_origin + src_task.size) / texture_size;
vUv = vec3(mix(st0, st1, aPosition.xy), src_task.render_target_layer_index);
gl_Position = uTransform * vec4(local_pos, pi.z, 1.0);
gl_Position = uTransform * vec4(local_pos, ci.z, 1.0);
}

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

@ -6,7 +6,7 @@
void main(void) {
Primitive prim = load_primitive();
Image image = fetch_image(prim.prim_index);
ResourceRect res = fetch_resource_rect(prim.user_data.x);
ResourceRect res = fetch_resource_rect(prim.user_data0);
#ifdef WR_FEATURE_TRANSFORM
TransformVertexInfo vi = write_transform_vertex(prim.local_rect,

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

@ -35,7 +35,7 @@ void main(void) {
vTileRepeat.y *= ratio_xy;
// V coordinate of gradient row in lookup texture.
vGradientIndex = float(prim.sub_index);
vGradientIndex = float(prim.user_data0);
// The texture size of the lookup texture
vGradientTextureSize = vec2(textureSize(sGradients, 0));

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

@ -31,14 +31,14 @@ vec3 bilerp(vec3 a, vec3 b, vec3 c, vec3 d, float s, float t) {
}
void main(void) {
PrimitiveInstance pi = fetch_prim_instance();
SplitGeometry geometry = fetch_split_geometry(pi.specific_prim_index);
AlphaBatchTask src_task = fetch_alpha_batch_task(pi.user_data.x);
CompositeInstance ci = fetch_composite_instance();
SplitGeometry geometry = fetch_split_geometry(ci.user_data0);
AlphaBatchTask src_task = fetch_alpha_batch_task(ci.src_task_index);
vec3 world_pos = bilerp(geometry.points[0], geometry.points[1],
geometry.points[3], geometry.points[2],
aPosition.y, aPosition.x);
vec4 final_pos = vec4(world_pos.xy * uDevicePixelRatio, pi.z, 1.0);
vec4 final_pos = vec4(world_pos.xy * uDevicePixelRatio, ci.z, 1.0);
gl_Position = uTransform * final_pos;

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

@ -6,8 +6,8 @@
void main(void) {
Primitive prim = load_primitive();
TextRun text = fetch_text_run(prim.prim_index);
Glyph glyph = fetch_glyph(prim.sub_index);
ResourceRect res = fetch_resource_rect(prim.user_data.x);
Glyph glyph = fetch_glyph(prim.user_data0);
ResourceRect res = fetch_resource_rect(prim.user_data1);
RectWithSize local_rect = RectWithSize(glyph.offset.xy,
(res.uv_rect.zw - res.uv_rect.xy) / uDevicePixelRatio);

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

@ -25,11 +25,11 @@ void main(void) {
write_clip(vi.screen_pos, prim.clip_area);
ResourceRect y_rect = fetch_resource_rect(prim.user_data.x);
ResourceRect y_rect = fetch_resource_rect(prim.user_data0);
#ifndef WR_FEATURE_INTERLEAVED_Y_CB_CR // only 1 channel
ResourceRect u_rect = fetch_resource_rect(prim.user_data.x + 1);
ResourceRect u_rect = fetch_resource_rect(prim.user_data0 + 1);
#ifndef WR_FEATURE_NV12 // 2 channel
ResourceRect v_rect = fetch_resource_rect(prim.user_data.x + 2);
ResourceRect v_rect = fetch_resource_rect(prim.user_data0 + 2);
#endif
#endif

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

@ -6,7 +6,7 @@ use euclid::Matrix4D;
use fnv::FnvHasher;
use gleam::gl;
use internal_types::{PackedVertex, RenderTargetMode, TextureSampler, DEFAULT_TEXTURE};
use internal_types::{BlurAttribute, ClearAttribute, ClipAttribute, VertexAttribute};
use internal_types::{BlurAttribute, ClipAttribute, VertexAttribute};
use internal_types::{DebugFontVertex, DebugColorVertex};
//use notify::{self, Watcher};
use super::shader_source;
@ -76,10 +76,8 @@ pub enum TextureFilter {
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum VertexFormat {
Triangles,
Rectangles,
DebugFont,
DebugColor,
Clear,
Blur,
Clip,
}
@ -89,7 +87,7 @@ enum FBOTarget {
Draw,
}
fn get_gl_format_bgra(gl: &gl::Gl) -> gl::GLuint {
pub fn get_gl_format_bgra(gl: &gl::Gl) -> gl::GLuint {
match gl.get_type() {
gl::GlType::Gl => {
GL_FORMAT_BGRA_GL
@ -190,7 +188,6 @@ impl VertexFormat {
vertex_stride as gl::GLint,
8 + vertex_stride * offset);
}
VertexFormat::Rectangles |
VertexFormat::Triangles => {
let vertex_stride = mem::size_of::<PackedVertex>() as gl::GLuint;
gl.enable_vertex_attrib_array(VertexAttribute::Position as gl::GLuint);
@ -206,53 +203,18 @@ impl VertexFormat {
instance.bind(gl);
let mut offset = 0;
for &attrib in [VertexAttribute::GlobalPrimId,
VertexAttribute::PrimitiveAddress,
VertexAttribute::TaskIndex,
VertexAttribute::ClipTaskIndex,
VertexAttribute::LayerIndex,
VertexAttribute::ElementIndex,
VertexAttribute::ZIndex,
for &attrib in [VertexAttribute::Data0,
VertexAttribute::Data1,
].into_iter() {
gl.enable_vertex_attrib_array(attrib as gl::GLuint);
gl.vertex_attrib_divisor(attrib as gl::GLuint, 1);
gl.vertex_attrib_i_pointer(attrib as gl::GLuint,
1,
4,
gl::INT,
instance_stride,
offset);
offset += 4;
offset += 16;
}
gl.enable_vertex_attrib_array(VertexAttribute::UserData as gl::GLuint);
gl.vertex_attrib_divisor(VertexAttribute::UserData as gl::GLuint, 1);
gl.vertex_attrib_i_pointer(VertexAttribute::UserData as gl::GLuint,
2,
gl::INT,
instance_stride,
offset);
}
VertexFormat::Clear => {
let vertex_stride = mem::size_of::<PackedVertex>() as gl::GLuint;
gl.enable_vertex_attrib_array(ClearAttribute::Position as gl::GLuint);
gl.vertex_attrib_divisor(ClearAttribute::Position as gl::GLuint, 0);
gl.vertex_attrib_pointer(ClearAttribute::Position as gl::GLuint,
2,
gl::FLOAT,
false,
vertex_stride as gl::GLint,
0);
instance.bind(gl);
gl.enable_vertex_attrib_array(ClearAttribute::Rectangle as gl::GLuint);
gl.vertex_attrib_divisor(ClearAttribute::Rectangle as gl::GLuint, 1);
gl.vertex_attrib_i_pointer(ClearAttribute::Rectangle as gl::GLuint,
4,
gl::INT,
instance_stride,
0);
}
VertexFormat::Blur => {
let vertex_stride = mem::size_of::<PackedVertex>() as gl::GLuint;
@ -412,24 +374,15 @@ impl Program {
self.gl.attach_shader(self.id, fs_id);
match vertex_format {
VertexFormat::Triangles | VertexFormat::Rectangles |
VertexFormat::DebugFont | VertexFormat::DebugColor => {
VertexFormat::Triangles |
VertexFormat::DebugFont |
VertexFormat::DebugColor => {
self.gl.bind_attrib_location(self.id, VertexAttribute::Position as gl::GLuint, "aPosition");
self.gl.bind_attrib_location(self.id, VertexAttribute::Color as gl::GLuint, "aColor");
self.gl.bind_attrib_location(self.id, VertexAttribute::ColorTexCoord as gl::GLuint, "aColorTexCoord");
self.gl.bind_attrib_location(self.id, VertexAttribute::GlobalPrimId as gl::GLuint, "aGlobalPrimId");
self.gl.bind_attrib_location(self.id, VertexAttribute::PrimitiveAddress as gl::GLuint, "aPrimitiveAddress");
self.gl.bind_attrib_location(self.id, VertexAttribute::TaskIndex as gl::GLuint, "aTaskIndex");
self.gl.bind_attrib_location(self.id, VertexAttribute::ClipTaskIndex as gl::GLuint, "aClipTaskIndex");
self.gl.bind_attrib_location(self.id, VertexAttribute::LayerIndex as gl::GLuint, "aLayerIndex");
self.gl.bind_attrib_location(self.id, VertexAttribute::ElementIndex as gl::GLuint, "aElementIndex");
self.gl.bind_attrib_location(self.id, VertexAttribute::UserData as gl::GLuint, "aUserData");
self.gl.bind_attrib_location(self.id, VertexAttribute::ZIndex as gl::GLuint, "aZIndex");
}
VertexFormat::Clear => {
self.gl.bind_attrib_location(self.id, ClearAttribute::Position as gl::GLuint, "aPosition");
self.gl.bind_attrib_location(self.id, ClearAttribute::Rectangle as gl::GLuint, "aClearRectangle");
self.gl.bind_attrib_location(self.id, VertexAttribute::Data0 as gl::GLuint, "aData0");
self.gl.bind_attrib_location(self.id, VertexAttribute::Data1 as gl::GLuint, "aData1");
}
VertexFormat::Blur => {
self.gl.bind_attrib_location(self.id, BlurAttribute::Position as gl::GLuint, "aPosition");

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

@ -118,22 +118,8 @@ pub enum VertexAttribute {
Color,
ColorTexCoord,
// instance-frequency primitive attributes
GlobalPrimId,
PrimitiveAddress,
TaskIndex,
ClipTaskIndex,
LayerIndex,
ElementIndex,
UserData,
ZIndex,
}
#[derive(Clone, Copy, Debug)]
pub enum ClearAttribute {
// vertex frequency
Position,
// instance frequency
Rectangle,
Data0,
Data1,
}
#[derive(Clone, Copy, Debug)]

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

@ -73,6 +73,9 @@ mod texture_cache;
mod tiling;
mod util;
#[doc(hidden)] // for benchmarks
pub use texture_cache::TexturePage;
#[cfg(feature = "webgl")]
mod webgl_types;
@ -140,4 +143,4 @@ extern crate plane_split;
extern crate gamma_lut;
pub use renderer::{ExternalImage, ExternalImageSource, ExternalImageHandler};
pub use renderer::{Renderer, RendererOptions};
pub use renderer::{GraphicsApi, GraphicsApiInfo, ReadPixelsFormat, Renderer, RendererOptions};

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

@ -13,6 +13,7 @@ use debug_colors;
use debug_render::DebugRenderer;
use device::{DepthFunction, Device, FrameId, ProgramId, TextureId, VertexFormat, GpuMarker, GpuProfiler};
use device::{GpuSample, TextureFilter, VAOId, VertexUsageHint, FileWatcherHandler, TextureTarget, ShaderError};
use device::get_gl_format_bgra;
use euclid::Matrix4D;
use fnv::FnvHasher;
use frame_builder::FrameBuilderConfig;
@ -43,7 +44,7 @@ use std::thread;
use texture_cache::TextureCache;
use rayon::ThreadPool;
use rayon::Configuration as ThreadPoolConfig;
use tiling::{AlphaBatchKind, BlurCommand, Frame, PrimitiveBatch, RenderTarget};
use tiling::{AlphaBatchKind, BlurCommand, CompositePrimitiveInstance, Frame, PrimitiveBatch, RenderTarget};
use tiling::{AlphaRenderTarget, CacheClipInstance, PrimitiveInstance, ColorRenderTarget, RenderTargetKind};
use time::precise_time_ns;
use thread_profiler::{register_thread_with_profiler, write_profile};
@ -51,7 +52,7 @@ use util::TransformedRectKind;
use webgl_types::GLContextHandleWrapper;
use webrender_traits::{ColorF, Epoch, PipelineId, RenderNotifier, RenderDispatcher};
use webrender_traits::{ExternalImageId, ExternalImageType, ImageData, ImageFormat, RenderApiSender};
use webrender_traits::{DeviceIntRect, DevicePoint, DeviceIntPoint, DeviceIntSize, DeviceUintSize};
use webrender_traits::{DeviceIntRect, DeviceUintRect, DevicePoint, DeviceIntPoint, DeviceIntSize, DeviceUintSize};
use webrender_traits::{ImageDescriptor, BlobImageRenderer};
use webrender_traits::{channel, FontRenderMode};
use webrender_traits::VRCompositorHandler;
@ -83,6 +84,18 @@ const GPU_TAG_PRIM_BORDER_EDGE: GpuProfileTag = GpuProfileTag { label: "BorderEd
const GPU_TAG_PRIM_CACHE_IMAGE: GpuProfileTag = GpuProfileTag { label: "CacheImage", color: debug_colors::SILVER };
const GPU_TAG_BLUR: GpuProfileTag = GpuProfileTag { label: "Blur", color: debug_colors::VIOLET };
#[derive(Clone, Debug, PartialEq)]
pub enum GraphicsApi {
OpenGL,
}
#[derive(Clone, Debug)]
pub struct GraphicsApiInfo {
pub kind: GraphicsApi,
pub renderer: String,
pub version: String,
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub enum ImageBufferKind {
Texture2D = 0,
@ -502,6 +515,12 @@ impl GpuDataTextures {
}
}
#[derive(Clone, Debug, PartialEq)]
pub enum ReadPixelsFormat {
Rgba8,
Bgra8,
}
/// The renderer is responsible for submitting to the GPU the work prepared by the
/// RenderBackend.
pub struct Renderer {
@ -1136,12 +1155,16 @@ impl Renderer {
Ok((renderer, sender))
}
fn get_yuv_shader_index(buffer_kind: ImageBufferKind, format: YuvFormat, color_space: YuvColorSpace) -> usize {
((buffer_kind as usize) * YUV_FORMATS.len() + (format as usize)) * YUV_COLOR_SPACES.len() + (color_space as usize)
pub fn get_graphics_api_info(&self) -> GraphicsApiInfo {
GraphicsApiInfo {
kind: GraphicsApi::OpenGL,
version: self.device.gl().get_string(gl::VERSION),
renderer: self.device.gl().get_string(gl::RENDERER),
}
}
pub fn gl(&self) -> &gl::Gl {
self.device.gl()
fn get_yuv_shader_index(buffer_kind: ImageBufferKind, format: YuvFormat, color_space: YuvColorSpace) -> usize {
((buffer_kind as usize) * YUV_FORMATS.len() + (format as usize)) * YUV_COLOR_SPACES.len() + (color_space as usize)
}
/// Sets the new RenderNotifier.
@ -1505,8 +1528,12 @@ impl Renderer {
let transform_kind = batch.key.flags.transform_kind();
let needs_clipping = batch.key.flags.needs_clipping();
debug_assert!(!needs_clipping ||
batch.key.blend_mode == BlendMode::Alpha ||
batch.key.blend_mode == BlendMode::PremultipliedAlpha);
match batch.key.blend_mode {
BlendMode::Alpha |
BlendMode::PremultipliedAlpha |
BlendMode::Subpixel(..) => true,
BlendMode::None => false,
});
let (marker, shader) = match batch.key.kind {
AlphaBatchKind::Composite => {
@ -1586,7 +1613,7 @@ impl Renderer {
// composites can't be grouped together because
// they may overlap and affect each other.
debug_assert!(batch.instances.len() == 1);
let instance = &batch.instances[0];
let instance = CompositePrimitiveInstance::from(&batch.instances[0]);
// TODO(gw): This code branch is all a bit hacky. We rely
// on pulling specific values from the render target data
@ -1599,9 +1626,9 @@ impl Renderer {
// composite operation in this batch.
let cache_texture_dimensions = self.device.get_texture_dimensions(cache_texture);
let backdrop = &render_task_data[instance.task_index as usize];
let readback = &render_task_data[instance.user_data[0] as usize];
let source = &render_task_data[instance.user_data[1] as usize];
let backdrop = &render_task_data[instance.task_index.0 as usize];
let readback = &render_task_data[instance.backdrop_task_index.0 as usize];
let source = &render_task_data[instance.src_task_index.0 as usize];
// Bind the FBO to blit the backdrop to.
// Called per-instance in case the layer (and therefore FBO)
@ -2144,6 +2171,31 @@ impl Renderer {
}
}
pub fn read_pixels_rgba8(&self, rect: DeviceUintRect) -> Vec<u8> {
let mut pixels = vec![0u8; (4 * rect.size.width * rect.size.height) as usize];
self.read_pixels_into(rect, ReadPixelsFormat::Rgba8, &mut pixels);
pixels
}
pub fn read_pixels_into(&self,
rect: DeviceUintRect,
format: ReadPixelsFormat,
output: &mut [u8]) {
let (gl_format, gl_type, size) = match format {
ReadPixelsFormat::Rgba8 => (gl::RGBA, gl::UNSIGNED_BYTE, 4),
ReadPixelsFormat::Bgra8 => (get_gl_format_bgra(self.device.gl()), gl::UNSIGNED_BYTE, 4),
};
assert_eq!(output.len(), (size * rect.size.width * rect.size.height) as usize);
self.device.gl().flush();
self.device.gl().read_pixels_into_buffer(rect.origin.x as gl::GLint,
rect.origin.y as gl::GLint,
rect.size.width as gl::GLsizei,
rect.size.height as gl::GLsizei,
gl_format,
gl_type,
output);
}
// De-initialize the Renderer safely, assuming the GL is still alive and active.
pub fn deinit(mut self) {
//Note: this is a fake frame, only needed because texture deletion is require to happen inside a frame

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

@ -8,7 +8,7 @@ use freelist::{FreeList, FreeListItem, FreeListItemId};
use internal_types::{TextureUpdate, TextureUpdateOp};
use internal_types::{CacheTextureId, RenderTargetMode, TextureUpdateList, RectUv};
use profiler::TextureCacheProfileCounters;
use std::cmp::{self, Ordering};
use std::cmp;
use std::collections::HashMap;
use std::collections::hash_map::Entry;
use std::hash::BuildHasherDefault;
@ -50,6 +50,12 @@ const COALESCING_TIMEOUT_CHECKING_INTERVAL: usize = 256;
pub type TextureCacheItemId = FreeListItemId;
enum CoalescingStatus {
Changed,
Unchanged,
Timeout,
}
/// A texture allocator using the guillotine algorithm with the rectangle merge improvement. See
/// sections 2.2 and 2.2.5 in "A Thousand Ways to Pack the Bin - A Practical Approach to Two-
/// Dimensional Rectangle Bin Packing":
@ -62,6 +68,7 @@ pub struct TexturePage {
texture_id: CacheTextureId,
texture_size: DeviceUintSize,
free_list: FreeRectList,
coalesce_vec: Vec<DeviceUintRect>,
allocations: u32,
dirty: bool,
}
@ -72,6 +79,7 @@ impl TexturePage {
texture_id: texture_id,
texture_size: texture_size,
free_list: FreeRectList::new(),
coalesce_vec: Vec::new(),
allocations: 0,
dirty: false,
};
@ -117,6 +125,9 @@ impl TexturePage {
pub fn allocate(&mut self,
requested_dimensions: &DeviceUintSize) -> Option<DeviceUintPoint> {
if requested_dimensions.width == 0 || requested_dimensions.height == 0 {
return Some(DeviceUintPoint::new(0, 0))
}
let index = match self.find_index_of_best_rect(requested_dimensions) {
None => return None,
Some(index) => index,
@ -173,7 +184,66 @@ impl TexturePage {
Some(chosen_rect.origin)
}
#[inline(never)]
fn coalesce_impl<F, U>(rects: &mut [DeviceUintRect], deadline: u64, fun_key: F, fun_union: U)
-> CoalescingStatus where
F: Fn(&DeviceUintRect) -> (u32, u32),
U: Fn(&mut DeviceUintRect, &mut DeviceUintRect) -> usize,
{
let mut num_changed = 0;
rects.sort_by_key(&fun_key);
for work_index in 0..rects.len() {
if work_index % COALESCING_TIMEOUT_CHECKING_INTERVAL == 0 &&
time::precise_time_ns() >= deadline {
return CoalescingStatus::Timeout
}
let (left, candidates) = rects.split_at_mut(work_index + 1);
let mut item = left.last_mut().unwrap();
if util::rect_is_empty(item) {
continue
}
let key = fun_key(item);
for candidate in candidates.iter_mut()
.take_while(|r| key == fun_key(r)) {
num_changed += fun_union(item, candidate);
}
}
if num_changed > 0 {
CoalescingStatus::Changed
} else {
CoalescingStatus::Unchanged
}
}
/// Combine rects that have the same width and are adjacent.
fn coalesce_horisontal(rects: &mut [DeviceUintRect], deadline: u64) -> CoalescingStatus {
Self::coalesce_impl(rects, deadline,
|item| (item.size.width, item.origin.x),
|item, candidate| {
if item.origin.y == candidate.max_y() || item.max_y() == candidate.origin.y {
*item = item.union(candidate);
candidate.size.width = 0;
1
} else { 0 }
})
}
/// Combine rects that have the same height and are adjacent.
fn coalesce_vertical(rects: &mut [DeviceUintRect], deadline: u64) -> CoalescingStatus {
Self::coalesce_impl(rects, deadline,
|item| (item.size.height, item.origin.y),
|item, candidate| {
if item.origin.x == candidate.max_x() || item.max_x() == candidate.origin.x {
*item = item.union(candidate);
candidate.size.height = 0;
1
} else { 0 }
})
}
pub fn coalesce(&mut self) -> bool {
if !self.dirty {
return false
@ -181,84 +251,33 @@ impl TexturePage {
// Iterate to a fixed point or until a timeout is reached.
let deadline = time::precise_time_ns() + COALESCING_TIMEOUT;
let mut free_list = mem::replace(&mut self.free_list, FreeRectList::new()).into_vec();
self.free_list.copy_to_vec(&mut self.coalesce_vec);
let mut changed = false;
// Combine rects that have the same width and are adjacent.
let mut new_free_list = Vec::new();
free_list.sort_by(|a, b| {
match a.size.width.cmp(&b.size.width) {
Ordering::Equal => a.origin.x.cmp(&b.origin.x),
ordering => ordering,
}
});
for work_index in 0..free_list.len() {
if work_index % COALESCING_TIMEOUT_CHECKING_INTERVAL == 0 &&
time::precise_time_ns() >= deadline {
self.free_list = FreeRectList::from_slice(&free_list[..]);
self.dirty = true;
//Note: we might want to consider try to use the last sorted order first
// but the elements get shuffled around a bit anyway during the bin placement
match Self::coalesce_horisontal(&mut self.coalesce_vec, deadline) {
CoalescingStatus::Changed => changed = true,
CoalescingStatus::Unchanged => (),
CoalescingStatus::Timeout => {
self.free_list.init_from_slice(&self.coalesce_vec);
return true
}
if free_list[work_index].size.width == 0 {
continue
}
for candidate_index in (work_index + 1)..free_list.len() {
if free_list[work_index].size.width != free_list[candidate_index].size.width ||
free_list[work_index].origin.x != free_list[candidate_index].origin.x {
break
}
if free_list[work_index].origin.y == free_list[candidate_index].max_y() ||
free_list[work_index].max_y() == free_list[candidate_index].origin.y {
changed = true;
free_list[work_index] =
free_list[work_index].union(&free_list[candidate_index]);
free_list[candidate_index].size.width = 0
}
new_free_list.push(free_list[work_index])
}
new_free_list.push(free_list[work_index])
}
free_list = new_free_list;
// Combine rects that have the same height and are adjacent.
let mut new_free_list = Vec::new();
free_list.sort_by(|a, b| {
match a.size.height.cmp(&b.size.height) {
Ordering::Equal => a.origin.y.cmp(&b.origin.y),
ordering => ordering,
}
});
for work_index in 0..free_list.len() {
if work_index % COALESCING_TIMEOUT_CHECKING_INTERVAL == 0 &&
time::precise_time_ns() >= deadline {
self.free_list = FreeRectList::from_slice(&free_list[..]);
self.dirty = true;
match Self::coalesce_vertical(&mut self.coalesce_vec, deadline) {
CoalescingStatus::Changed => changed = true,
CoalescingStatus::Unchanged => (),
CoalescingStatus::Timeout => {
self.free_list.init_from_slice(&self.coalesce_vec);
return true
}
if free_list[work_index].size.height == 0 {
continue
}
for candidate_index in (work_index + 1)..free_list.len() {
if free_list[work_index].size.height !=
free_list[candidate_index].size.height ||
free_list[work_index].origin.y != free_list[candidate_index].origin.y {
break
}
if free_list[work_index].origin.x == free_list[candidate_index].max_x() ||
free_list[work_index].max_x() == free_list[candidate_index].origin.x {
changed = true;
free_list[work_index] =
free_list[work_index].union(&free_list[candidate_index]);
free_list[candidate_index].size.height = 0
}
}
new_free_list.push(free_list[work_index])
}
free_list = new_free_list;
self.free_list = FreeRectList::from_slice(&free_list[..]);
if changed {
self.free_list.init_from_slice(&self.coalesce_vec);
}
self.dirty = changed;
changed
}
@ -273,6 +292,9 @@ impl TexturePage {
}
fn free(&mut self, rect: &DeviceUintRect) {
if util::rect_is_empty(rect) {
return
}
debug_assert!(self.allocations > 0);
self.allocations -= 1;
if self.allocations == 0 {
@ -312,6 +334,25 @@ impl TexturePage {
}
}
// testing functionality
impl TexturePage {
#[doc(hidden)]
pub fn new_dummy(size: DeviceUintSize) -> TexturePage {
Self::new(CacheTextureId(0), size)
}
#[doc(hidden)]
pub fn fill_from(&mut self, other: &TexturePage) {
self.dirty = true;
self.free_list.small.clear();
self.free_list.small.extend_from_slice(&other.free_list.small);
self.free_list.medium.clear();
self.free_list.medium.extend_from_slice(&other.free_list.medium);
self.free_list.large.clear();
self.free_list.large.extend_from_slice(&other.free_list.large);
}
}
/// A binning free list. Binning is important to avoid sifting through lots of small strips when
/// allocating many texture items.
struct FreeRectList {
@ -329,12 +370,15 @@ impl FreeRectList {
}
}
fn from_slice(vector: &[DeviceUintRect]) -> FreeRectList {
let mut free_list = FreeRectList::new();
for rect in vector {
free_list.push(rect)
fn init_from_slice(&mut self, rects: &[DeviceUintRect]) {
self.small.clear();
self.medium.clear();
self.large.clear();
for rect in rects {
if !util::rect_is_empty(rect) {
self.push(rect)
}
}
free_list
}
fn push(&mut self, rect: &DeviceUintRect) {
@ -361,10 +405,11 @@ impl FreeRectList {
}
}
fn into_vec(mut self) -> Vec<DeviceUintRect> {
self.small.extend(self.medium.drain(..));
self.small.extend(self.large.drain(..));
self.small
fn copy_to_vec(&self, rects: &mut Vec<DeviceUintRect>) {
rects.clear();
rects.extend_from_slice(&self.small);
rects.extend_from_slice(&self.medium);
rects.extend_from_slice(&self.large);
}
}
@ -379,13 +424,14 @@ enum FreeListBin {
}
impl FreeListBin {
pub fn for_size(size: &DeviceUintSize) -> FreeListBin {
fn for_size(size: &DeviceUintSize) -> FreeListBin {
if size.width >= MINIMUM_LARGE_RECT_SIZE && size.height >= MINIMUM_LARGE_RECT_SIZE {
FreeListBin::Large
} else if size.width >= MINIMUM_MEDIUM_RECT_SIZE &&
size.height >= MINIMUM_MEDIUM_RECT_SIZE {
FreeListBin::Medium
} else {
debug_assert!(size.width > 0 && size.height > 0);
FreeListBin::Small
}
}

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

@ -314,16 +314,14 @@ impl AlphaRenderItem {
let amount = (amount * 65535.0).round() as i32;
let batch = batch_list.get_suitable_batch(&key, &stacking_context.screen_bounds);
batch.add_instance(PrimitiveInstance {
global_prim_id: -1,
prim_address: GpuStoreAddress(0),
task_index: task_index.0 as i32,
clip_task_index: -1,
layer_index: -1,
sub_index: filter_mode,
user_data: [src_task_index.0 as i32, amount],
z_sort_index: z,
});
let instance = CompositePrimitiveInstance::new(task_index,
src_task_index,
RenderTaskIndex(0),
filter_mode,
amount,
z);
batch.add_instance(PrimitiveInstance::from(instance));
}
AlphaRenderItem::HardwareComposite(stacking_context_index, src_id, composite_op, z) => {
let stacking_context = &ctx.stacking_context_store[stacking_context_index.0];
@ -333,16 +331,15 @@ impl AlphaRenderItem {
composite_op.to_blend_mode(),
BatchTextures::no_texture());
let batch = batch_list.get_suitable_batch(&key, &stacking_context.screen_bounds);
batch.add_instance(PrimitiveInstance {
global_prim_id: -1,
prim_address: GpuStoreAddress(0),
task_index: task_index.0 as i32,
clip_task_index: -1,
layer_index: -1,
sub_index: -1,
user_data: [src_task_index.0 as i32, 0],
z_sort_index: z,
});
let instance = CompositePrimitiveInstance::new(task_index,
src_task_index,
RenderTaskIndex(0),
0,
0,
z);
batch.add_instance(PrimitiveInstance::from(instance));
}
AlphaRenderItem::Composite(stacking_context_index,
backdrop_id,
@ -357,17 +354,15 @@ impl AlphaRenderItem {
let batch = batch_list.get_suitable_batch(&key, &stacking_context.screen_bounds);
let backdrop_task = render_tasks.get_task_index(&backdrop_id, child_pass_index);
let src_task_index = render_tasks.get_static_task_index(&src_id);
batch.add_instance(PrimitiveInstance {
global_prim_id: -1,
prim_address: GpuStoreAddress(0),
task_index: task_index.0 as i32,
clip_task_index: -1,
layer_index: -1,
sub_index: mode as u32 as i32,
user_data: [ backdrop_task.0 as i32,
src_task_index.0 as i32 ],
z_sort_index: z,
});
let instance = CompositePrimitiveInstance::new(task_index,
src_task_index,
backdrop_task,
mode as u32 as i32,
0,
z);
batch.add_instance(PrimitiveInstance::from(instance));
}
AlphaRenderItem::Primitive(clip_scroll_group_index_opt, prim_index, z) => {
let prim_metadata = ctx.prim_store.get_metadata(prim_index);
@ -375,9 +370,9 @@ impl AlphaRenderItem {
Some(group_index) => {
let group = &ctx.clip_scroll_group_store[group_index.0];
let bounding_rect = group.screen_bounding_rect.as_ref().unwrap();
(bounding_rect.0, group.packed_layer_index.0 as i32)
(bounding_rect.0, group.packed_layer_index)
},
None => (TransformedRectKind::AxisAligned, 0),
None => (TransformedRectKind::AxisAligned, PackedLayerIndex(0)),
};
let needs_clipping = prim_metadata.needs_clipping();
let mut flags = AlphaBatchKeyFlags::empty();
@ -398,24 +393,18 @@ impl AlphaRenderItem {
None => {
OPAQUE_TASK_INDEX
}
}.0 as i32;
let global_prim_id = prim_index.0 as i32;
let prim_address = prim_metadata.gpu_prim_index;
let task_index = task_index.0 as i32;
};
let needs_blending = !prim_metadata.is_opaque ||
needs_clipping ||
transform_kind == TransformedRectKind::Complex;
let blend_mode = ctx.prim_store.get_blend_mode(needs_blending, prim_metadata);
let base_instance = PrimitiveInstance {
task_index: task_index,
clip_task_index: clip_task_index,
layer_index: packed_layer_index,
global_prim_id: global_prim_id,
prim_address: prim_address,
sub_index: 0,
user_data: [0, 0],
z_sort_index: z,
};
let base_instance = SimplePrimitiveInstance::new(prim_index,
prim_metadata.gpu_prim_index,
task_index,
clip_task_index,
packed_layer_index,
z);
match prim_metadata.prim_kind {
PrimitiveKind::Border => {
@ -430,16 +419,13 @@ impl AlphaRenderItem {
match *instance_kind {
BorderCornerInstance::Single => {
batch.add_instance(base_instance.build(sub_index,
BorderCornerSide::Both as i32,
0));
BorderCornerSide::Both as i32,));
}
BorderCornerInstance::Double => {
batch.add_instance(base_instance.build(sub_index,
BorderCornerSide::First as i32,
0));
BorderCornerSide::First as i32));
batch.add_instance(base_instance.build(sub_index,
BorderCornerSide::Second as i32,
0));
BorderCornerSide::Second as i32));
}
}
}
@ -447,14 +433,14 @@ impl AlphaRenderItem {
batch_list.with_suitable_batch(&edge_key, item_bounding_rect, |batch| {
for border_segment in 0..4 {
batch.add_instance(base_instance.build(border_segment, 0, 0));
batch.add_instance(base_instance.build(border_segment, 0));
}
});
}
PrimitiveKind::Rectangle => {
let key = AlphaBatchKey::new(AlphaBatchKind::Rectangle, flags, blend_mode, textures);
let batch = batch_list.get_suitable_batch(&key, item_bounding_rect);
batch.add_instance(base_instance);
batch.add_instance(base_instance.build(0, 0));
}
PrimitiveKind::Image => {
let image_cpu = &ctx.prim_store.cpu_images[prim_metadata.cpu_prim_index.0];
@ -479,7 +465,7 @@ impl AlphaRenderItem {
let key = AlphaBatchKey::new(batch_kind, flags, blend_mode, textures);
let batch = batch_list.get_suitable_batch(&key, item_bounding_rect);
batch.add_instance(base_instance.build(0, image_cpu.resource_address.0, 0));
batch.add_instance(base_instance.build(image_cpu.resource_address.0, 0));
}
PrimitiveKind::TextRun => {
let text_cpu = &ctx.prim_store.cpu_text_runs[prim_metadata.cpu_prim_index.0];
@ -504,36 +490,33 @@ impl AlphaRenderItem {
};
for glyph_index in 0..prim_metadata.gpu_data_count {
let user_data0 = match batch_kind {
let user_data1 = match batch_kind {
AlphaBatchKind::TextRun => text_cpu.resource_address.0 + glyph_index,
AlphaBatchKind::CacheImage => cache_task_index,
_ => unreachable!(),
};
batch.add_instance(base_instance.build(prim_metadata.gpu_data_address.0 + glyph_index,
user_data0,
0));
user_data1));
}
}
PrimitiveKind::AlignedGradient => {
let key = AlphaBatchKey::new(AlphaBatchKind::AlignedGradient, flags, blend_mode, textures);
let batch = batch_list.get_suitable_batch(&key, item_bounding_rect);
for part_index in 0..(prim_metadata.gpu_data_count - 1) {
batch.add_instance(base_instance.build(prim_metadata.gpu_data_address.0 + part_index, 0, 0));
batch.add_instance(base_instance.build(prim_metadata.gpu_data_address.0 + part_index, 0));
}
}
PrimitiveKind::AngleGradient => {
let key = AlphaBatchKey::new(AlphaBatchKind::AngleGradient, flags, blend_mode, textures);
let batch = batch_list.get_suitable_batch(&key, item_bounding_rect);
batch.add_instance(base_instance.build(prim_metadata.gpu_data_address.0,
prim_metadata.gpu_data_count,
0));
}
PrimitiveKind::RadialGradient => {
let key = AlphaBatchKey::new(AlphaBatchKind::RadialGradient, flags, blend_mode, textures);
let batch = batch_list.get_suitable_batch(&key, item_bounding_rect);
batch.add_instance(base_instance.build(prim_metadata.gpu_data_address.0,
prim_metadata.gpu_data_count,
0));
}
PrimitiveKind::YuvImage => {
@ -571,8 +554,7 @@ impl AlphaRenderItem {
textures);
let batch = batch_list.get_suitable_batch(&key, item_bounding_rect);
batch.add_instance(base_instance.build(0,
image_yuv_cpu.yuv_resource_address.0,
batch.add_instance(base_instance.build(image_yuv_cpu.yuv_resource_address.0,
0));
}
PrimitiveKind::BoxShadow => {
@ -585,8 +567,7 @@ impl AlphaRenderItem {
for rect_index in 0..prim_metadata.gpu_data_count {
batch.add_instance(base_instance.build(prim_metadata.gpu_data_address.0 + rect_index,
cache_task_index.0 as i32,
0));
cache_task_index.0 as i32));
}
}
}
@ -599,16 +580,15 @@ impl AlphaRenderItem {
let stacking_context = &ctx.stacking_context_store[sc_index.0];
let batch = batch_list.get_suitable_batch(&key, &stacking_context.screen_bounds);
let source_task = render_tasks.get_task_index(&task_id, child_pass_index);
batch.add_instance(PrimitiveInstance {
global_prim_id: -1,
prim_address: gpu_address,
task_index: task_index.0 as i32,
clip_task_index: -1,
layer_index: -1, // not be used
sub_index: 0,
user_data: [ source_task.0 as i32, 0 ],
z_sort_index: z,
});
let instance = CompositePrimitiveInstance::new(task_index,
source_task,
RenderTaskIndex(0),
gpu_address.0,
0,
z);
batch.add_instance(PrimitiveInstance::from(instance));
}
}
}
@ -970,16 +950,13 @@ impl RenderTarget for ColorRenderTarget {
match prim_metadata.prim_kind {
PrimitiveKind::BoxShadow => {
self.box_shadow_cache_prims.push(PrimitiveInstance {
global_prim_id: prim_index.0 as i32,
prim_address: prim_metadata.gpu_prim_index,
task_index: render_tasks.get_task_index(&task.id, pass_index).0 as i32,
clip_task_index: 0,
layer_index: 0,
sub_index: 0,
user_data: [0; 2],
z_sort_index: 0, // z is disabled for rendering cache primitives
});
let instance = SimplePrimitiveInstance::new(prim_index,
prim_metadata.gpu_prim_index,
render_tasks.get_task_index(&task.id, pass_index),
RenderTaskIndex(0),
PackedLayerIndex(0),
0); // z is disabled for rendering cache primitives
self.box_shadow_cache_prims.push(instance.build(0, 0));
}
PrimitiveKind::TextRun => {
let text = &ctx.prim_store.cpu_text_runs[prim_metadata.cpu_prim_index.0];
@ -998,17 +975,16 @@ impl RenderTarget for ColorRenderTarget {
self.text_run_textures.colors[0] == textures.colors[0]);
self.text_run_textures = textures;
let instance = SimplePrimitiveInstance::new(prim_index,
prim_metadata.gpu_prim_index,
render_tasks.get_task_index(&task.id, pass_index),
RenderTaskIndex(0),
PackedLayerIndex(0),
0); // z is disabled for rendering cache primitives
for glyph_index in 0..prim_metadata.gpu_data_count {
self.text_run_cache_prims.push(PrimitiveInstance {
global_prim_id: prim_index.0 as i32,
prim_address: prim_metadata.gpu_prim_index,
task_index: render_tasks.get_task_index(&task.id, pass_index).0 as i32,
clip_task_index: 0,
layer_index: 0,
sub_index: prim_metadata.gpu_data_address.0 + glyph_index,
user_data: [ text.resource_address.0 + glyph_index, 0],
z_sort_index: 0, // z is disabled for rendering cache primitives
});
self.text_run_cache_prims.push(instance.build(prim_metadata.gpu_data_address.0 + glyph_index,
text.resource_address.0 + glyph_index));
}
}
_ => {
@ -1289,27 +1265,107 @@ pub struct CacheClipInstance {
segment: i32,
}
// 32 bytes per instance should be enough for anyone!
#[derive(Debug, Clone)]
pub struct PrimitiveInstance {
global_prim_id: i32,
prim_address: GpuStoreAddress,
pub task_index: i32,
clip_task_index: i32,
layer_index: i32,
sub_index: i32,
z_sort_index: i32,
pub user_data: [i32; 2],
data: [i32; 8],
}
impl PrimitiveInstance {
pub fn build(&self,
sub_index: i32,
user_data0: i32,
user_data1: i32) -> PrimitiveInstance {
struct SimplePrimitiveInstance {
pub global_prim_index: i32,
pub specific_prim_address: i32,
pub task_index: i32,
pub clip_task_index: i32,
pub layer_index: i32,
pub z_sort_index: i32,
}
impl SimplePrimitiveInstance {
fn new(prim_index: PrimitiveIndex,
specific_prim_address: GpuStoreAddress,
task_index: RenderTaskIndex,
clip_task_index: RenderTaskIndex,
layer_index: PackedLayerIndex,
z_sort_index: i32) -> SimplePrimitiveInstance {
SimplePrimitiveInstance {
global_prim_index: prim_index.0 as i32,
specific_prim_address: specific_prim_address.0 as i32,
task_index: task_index.0 as i32,
clip_task_index: clip_task_index.0 as i32,
layer_index: layer_index.0 as i32,
z_sort_index: z_sort_index,
}
}
fn build(&self, data0: i32, data1: i32) -> PrimitiveInstance {
PrimitiveInstance {
sub_index: sub_index,
user_data: [user_data0, user_data1],
..*self
data: [
self.global_prim_index,
self.specific_prim_address,
self.task_index,
self.clip_task_index,
self.layer_index,
self.z_sort_index,
data0,
data1,
]
}
}
}
pub struct CompositePrimitiveInstance {
pub task_index: RenderTaskIndex,
pub src_task_index: RenderTaskIndex,
pub backdrop_task_index: RenderTaskIndex,
pub data0: i32,
pub data1: i32,
pub z: i32,
}
impl CompositePrimitiveInstance {
fn new(task_index: RenderTaskIndex,
src_task_index: RenderTaskIndex,
backdrop_task_index: RenderTaskIndex,
data0: i32,
data1: i32,
z: i32) -> CompositePrimitiveInstance {
CompositePrimitiveInstance {
task_index: task_index,
src_task_index: src_task_index,
backdrop_task_index: backdrop_task_index,
data0: data0,
data1: data1,
z: z,
}
}
}
impl From<CompositePrimitiveInstance> for PrimitiveInstance {
fn from(instance: CompositePrimitiveInstance) -> PrimitiveInstance {
PrimitiveInstance {
data: [
instance.task_index.0 as i32,
instance.src_task_index.0 as i32,
instance.backdrop_task_index.0 as i32,
instance.z,
instance.data0,
instance.data1,
0,
0,
]
}
}
}
impl<'a> From<&'a PrimitiveInstance> for CompositePrimitiveInstance {
fn from(instance: &'a PrimitiveInstance) -> CompositePrimitiveInstance {
CompositePrimitiveInstance {
task_index: RenderTaskIndex(instance.data[0] as usize),
src_task_index: RenderTaskIndex(instance.data[1] as usize),
backdrop_task_index: RenderTaskIndex(instance.data[2] as usize),
z: instance.data[3],
data0: instance.data[4],
data1: instance.data[5],
}
}
}
@ -1457,7 +1513,6 @@ pub struct PackedLayer {
pub transform: LayerToWorldTransform,
pub inv_transform: WorldToLayerTransform,
pub local_clip_rect: LayerRect,
pub screen_vertices: [WorldPoint4D; 4],
}
impl Default for PackedLayer {
@ -1466,7 +1521,6 @@ impl Default for PackedLayer {
transform: LayerToWorldTransform::identity(),
inv_transform: WorldToLayerTransform::identity(),
local_clip_rect: LayerRect::zero(),
screen_vertices: [WorldPoint4D::zero(); 4],
}
}
}
@ -1488,7 +1542,6 @@ impl PackedLayer {
-> Option<(TransformedRectKind, DeviceIntRect)> {
let xf_rect = TransformedRect::new(&local_rect, &self.transform, device_pixel_ratio);
xf_rect.bounding_rect.intersection(screen_rect).map(|rect| {
self.screen_vertices = xf_rect.vertices.clone();
self.local_clip_rect = *local_rect;
(xf_rect.kind, rect)
})

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

@ -4,6 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "WebRenderAPI.h"
#include "LayersLogging.h"
#include "mozilla/webrender/RendererOGL.h"
#include "mozilla/gfx/gfxVars.h"
#include "mozilla/layers/CompositorThread.h"
@ -11,9 +12,14 @@
#include "mozilla/widget/CompositorWidget.h"
#include "mozilla/layers/SynchronousTask.h"
#define WRDL_LOG(...)
//#define WRDL_LOG(...) printf_stderr("WRDL: " __VA_ARGS__)
namespace mozilla {
namespace wr {
using layers::Stringify;
class NewRenderer : public RendererEvent
{
public:
@ -556,6 +562,8 @@ DisplayListBuilder::PushStackingContext(const WrRect& aBounds,
matrix = ToWrMatrix(*aTransform);
}
const WrMatrix* maybeTransform = aTransform ? &matrix : nullptr;
WRDL_LOG("PushStackingContext b=%s t=%s\n", Stringify(aBounds).c_str(),
aTransform ? Stringify(*aTransform).c_str() : "none");
wr_dp_push_stacking_context(mWrState, aBounds, aAnimationId, aOpacity,
maybeTransform, aMixBlendMode);
}
@ -573,6 +581,7 @@ DisplayListBuilder::PushStackingContext(const WrRect& aBounds,
void
DisplayListBuilder::PopStackingContext()
{
WRDL_LOG("PopStackingContext\n");
wr_dp_pop_stacking_context(mWrState);
}
@ -580,12 +589,14 @@ void
DisplayListBuilder::PushClip(const WrRect& aClipRect,
const WrImageMask* aMask)
{
WRDL_LOG("PushClip r=%s m=%p\n", Stringify(aClipRect).c_str(), aMask);
wr_dp_push_clip(mWrState, aClipRect, aMask);
}
void
DisplayListBuilder::PopClip()
{
WRDL_LOG("PopClip\n");
wr_dp_pop_clip(mWrState);
}
@ -602,12 +613,15 @@ DisplayListBuilder::PushScrollLayer(const layers::FrameMetrics::ViewID& aScrollI
const WrRect& aContentRect,
const WrRect& aClipRect)
{
WRDL_LOG("PushScrollLayer id=%" PRIu64 " co=%s cl=%s\n",
aScrollId, Stringify(aContentRect).c_str(), Stringify(aClipRect).c_str());
wr_dp_push_scroll_layer(mWrState, aScrollId, aContentRect, aClipRect);
}
void
DisplayListBuilder::PopScrollLayer()
{
WRDL_LOG("PopScrollLayer\n");
wr_dp_pop_scroll_layer(mWrState);
}
@ -616,6 +630,9 @@ DisplayListBuilder::PushRect(const WrRect& aBounds,
const WrClipRegionToken aClip,
const WrColor& aColor)
{
WRDL_LOG("PushRect b=%s c=%s\n",
Stringify(aBounds).c_str(),
Stringify(aColor).c_str());
wr_dp_push_rect(mWrState, aBounds, aClip, aColor);
}
@ -675,6 +692,8 @@ DisplayListBuilder::PushImage(const WrRect& aBounds,
wr::ImageRendering aFilter,
wr::ImageKey aImage)
{
WRDL_LOG("PushImage b=%s s=%s t=%s\n", Stringify(aBounds).c_str(),
Stringify(aStretchSize).c_str(), Stringify(aTileSpacing).c_str());
wr_dp_push_image(mWrState, aBounds, aClip, aStretchSize, aTileSpacing, aFilter, aImage);
}
@ -828,6 +847,7 @@ WrClipRegionToken
DisplayListBuilder::PushClipRegion(const WrRect& aMain,
const WrImageMask* aMask)
{
WRDL_LOG("PushClipRegion r=%s m=%p\n", Stringify(aMain).c_str(), aMask);
return wr_dp_push_clip_region(mWrState,
aMain,
nullptr, 0,
@ -839,6 +859,8 @@ DisplayListBuilder::PushClipRegion(const WrRect& aMain,
const nsTArray<WrComplexClipRegion>& aComplex,
const WrImageMask* aMask)
{
WRDL_LOG("PushClipRegion r=%s cl=%d m=%p\n", Stringify(aMain).c_str(),
(int)aComplex.Length(), aMask);
return wr_dp_push_clip_region(mWrState,
aMain,
aComplex.Elements(), aComplex.Length(),

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

@ -7,7 +7,7 @@ use std::collections::HashMap;
use gleam::gl;
use webrender_traits::*;
use webrender::renderer::{Renderer, RendererOptions};
use webrender::renderer::{ReadPixelsFormat, Renderer, RendererOptions};
use webrender::renderer::{ExternalImage, ExternalImageHandler, ExternalImageSource};
use webrender::{ApiRecordingReceiver, BinaryRecorder};
use app_units::Au;
@ -70,16 +70,6 @@ impl Into<WrExternalImageId> for ExternalImageId {
}
}
const GL_FORMAT_BGRA_GL: gl::GLuint = gl::BGRA;
const GL_FORMAT_BGRA_GLES: gl::GLuint = gl::BGRA_EXT;
fn get_gl_format_bgra(gl: &gl::Gl) -> gl::GLuint {
match gl.get_type() {
gl::GlType::Gl => GL_FORMAT_BGRA_GL,
gl::GlType::Gles => GL_FORMAT_BGRA_GLES,
}
}
fn make_slice<'a, T>(ptr: *const T, len: usize) -> &'a [T] {
if ptr.is_null() {
&[]
@ -790,17 +780,12 @@ pub unsafe extern "C" fn wr_renderer_readback(renderer: &mut WrRenderer,
buffer_size: usize) {
assert!(is_in_render_thread());
renderer.gl().flush();
let mut slice = make_slice_mut(dst_buffer, buffer_size);
renderer.gl()
.read_pixels_into_buffer(0,
0,
width as gl::GLsizei,
height as gl::GLsizei,
get_gl_format_bgra(renderer.gl()),
gl::UNSIGNED_BYTE,
slice);
renderer.read_pixels_into(DeviceUintRect::new(
DeviceUintPoint::new(0, 0),
DeviceUintSize::new(width, height)),
ReadPixelsFormat::Bgra8,
&mut slice);
}
#[no_mangle]

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

@ -1046,6 +1046,10 @@ description =
description =
[PWebRenderBridge::DPGetSnapshot]
description =
[PWebRenderBridge::SetAsyncScrollOffset]
description = test only
[PWebRenderBridge::SetAsyncZoom]
description = test only
[PVRManager::GetSensorState]
description =
[PHal::GetCurrentBatteryInformation]

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

@ -1013,11 +1013,10 @@ nsCSSGradientRenderer::BuildWebRenderParameters(float aOpacity,
aStops.SetLength(mStops.Length());
for(uint32_t i = 0; i < mStops.Length(); i++) {
Float alpha = mStops[i].mColor.a * aOpacity;
aStops[i].color.r = mStops[i].mColor.r * alpha;
aStops[i].color.g = mStops[i].mColor.g * alpha;
aStops[i].color.b = mStops[i].mColor.b * alpha;
aStops[i].color.a = alpha;
aStops[i].color.r = mStops[i].mColor.r;
aStops[i].color.g = mStops[i].mColor.g;
aStops[i].color.b = mStops[i].mColor.b;
aStops[i].color.a = mStops[i].mColor.a * aOpacity;
aStops[i].offset = mStops[i].mPosition;
}

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

@ -5362,18 +5362,6 @@ nsDisplayBoxShadowInner::CanCreateWebRenderCommands(nsDisplayListBuilder* aBuild
return true;
}
for (uint32_t i = shadows->Length(); i > 0; --i) {
nsCSSShadowItem *shadowItem = shadows->ShadowAt(i - 1);
if (!shadowItem->mInset) {
continue;
}
if (shadowItem->mXOffset <= 0 || shadowItem->mYOffset <= 0) {
// Need to wait for WR to support clip out.
return false;
}
}
return true;
}

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

@ -11,7 +11,7 @@ random != boxshadow-blur-2.html boxshadow-blur-2-notref.html # fixedpoint divisi
== boxshadow-rounding.html boxshadow-rounding-ref.html
# One uses old path, one uses WR box shadow.
fails-if(Android) fuzzy-if(webrender,50,3310) == boxshadow-button.html boxshadow-button-ref.html
fuzzy-if(OSX==1010,1,24) fuzzy-if(d2d,16,908) fuzzy-if(webrender,19,1680) == boxshadow-large-border-radius.html boxshadow-large-border-radius-ref.html # Bug 1209649
fuzzy-if(OSX==1010,1,24) fuzzy-if(d2d,16,908) fuzzy-if(webrender,48,2040) == boxshadow-large-border-radius.html boxshadow-large-border-radius-ref.html # Bug 1209649
fails-if(Android) == boxshadow-fileupload.html boxshadow-fileupload-ref.html
fuzzy-if(skiaContent,13,28) == boxshadow-inner-basic.html boxshadow-inner-basic-ref.svg
@ -25,8 +25,8 @@ fuzzy(2,440) fuzzy-if(webrender,25,1300) == boxshadow-skiprect.html boxshadow-sk
== boxshadow-opacity.html boxshadow-opacity-ref.html
== boxshadow-color-rounding.html boxshadow-color-rounding-ref.html
== boxshadow-color-rounding-middle.html boxshadow-color-rounding-middle-ref.html
fuzzy(3,500) fuzzy-if(d2d,2,1080) == boxshadow-border-radius-int.html boxshadow-border-radius-int-ref.html
== boxshadow-inset-neg-spread.html about:blank
fuzzy(3,500) fuzzy-if(d2d,2,1080) fuzzy-if(webrender,12,1500) == boxshadow-border-radius-int.html boxshadow-border-radius-int-ref.html
fuzzy-if(webrender,1,4) == boxshadow-inset-neg-spread.html about:blank
== boxshadow-inset-neg-spread2.html boxshadow-inset-neg-spread2-ref.html
fuzzy(26,3610) fuzzy-if(d2d,26,5910) fuzzy-if(webrender,43,200) == boxshadow-rotated.html boxshadow-rotated-ref.html # Bug 1211264
== boxshadow-inset-large-border-radius.html boxshadow-inset-large-border-radius-ref.html

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

@ -1,7 +1,7 @@
default-preferences pref(layout.css.box-decoration-break.enabled,true)
== box-decoration-break-1.html box-decoration-break-1-ref.html
fuzzy(1,20) fuzzy-if(skiaContent,1,700) == box-decoration-break-with-inset-box-shadow-1.html box-decoration-break-with-inset-box-shadow-1-ref.html
fuzzy(1,20) fuzzy-if(skiaContent,1,700) fuzzy-if(webrender,5,450) == box-decoration-break-with-inset-box-shadow-1.html box-decoration-break-with-inset-box-shadow-1-ref.html
fuzzy(16,460) fuzzy-if(Android,10,3673) fuzzy-if(skiaContent,57,374) == box-decoration-break-with-outset-box-shadow-1.html box-decoration-break-with-outset-box-shadow-1-ref.html
random-if(!gtkWidget) HTTP(..) == box-decoration-break-border-image.html box-decoration-break-border-image-ref.html
== box-decoration-break-block-border-padding.html box-decoration-break-block-border-padding-ref.html