Refactor ImageHost to allow acquiring the current TextureSource without locking the underlying TextureHost. (bug 1365879 part 8, r=mattwoodrow)

This commit is contained in:
David Anderson 2017-06-20 01:17:18 -07:00
Родитель 8974aed87a
Коммит 737535e6d0
4 изменённых файлов: 114 добавлений и 41 удалений

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

@ -195,23 +195,12 @@ ImageHost::Composite(Compositor* aCompositor,
const nsIntRegion* aVisibleRegion,
const Maybe<gfx::Polygon>& aGeometry)
{
HostLayerManager* lm = GetLayerManager();
if (!lm) {
RenderInfo info;
if (!PrepareToRender(aCompositor, &info)) {
return;
}
int imageIndex = ChooseImageIndex();
if (imageIndex < 0) {
return;
}
if (uint32_t(imageIndex) + 1 < mImages.Length()) {
lm->CompositeUntil(mImages[imageIndex + 1].mTimeStamp + TimeDuration::FromMilliseconds(BIAS_TIME_MS));
}
TimedImage* img = &mImages[imageIndex];
img->mTextureHost->SetTextureSourceProvider(aCompositor);
SetCurrentTextureHost(img->mTextureHost);
TimedImage* img = info.img;
{
AutoLockCompositableHost autoLock(this);
@ -250,20 +239,6 @@ ImageHost::Composite(Compositor* aCompositor,
diagnosticFlags |= DiagnosticFlags::YCBCR;
}
if (mLastFrameID != img->mFrameID || mLastProducerID != img->mProducerID) {
if (mAsyncRef) {
ImageCompositeNotificationInfo info;
info.mImageBridgeProcessId = mAsyncRef.mProcessId;
info.mNotification = ImageCompositeNotification(
mAsyncRef.mHandle,
img->mTimeStamp, lm->GetCompositionTime(),
img->mFrameID, img->mProducerID);
static_cast<LayerManagerComposite*>(aLayer->GetLayerManager())->
AppendImageCompositeNotification(info);
}
mLastFrameID = img->mFrameID;
mLastProducerID = img->mProducerID;
}
aEffectChain.mPrimaryEffect = effect;
gfx::Rect pictureRect(0, 0, img->mPictureRect.width, img->mPictureRect.height);
BigImageIterator* it = mCurrentTextureSource->AsBigImageIterator();
@ -327,6 +302,67 @@ ImageHost::Composite(Compositor* aCompositor,
}
}
FinishRendering(info);
}
bool
ImageHost::PrepareToRender(TextureSourceProvider* aProvider, RenderInfo* aOutInfo)
{
HostLayerManager* lm = GetLayerManager();
if (!lm) {
return false;
}
int imageIndex = ChooseImageIndex();
if (imageIndex < 0) {
return false;
}
if (uint32_t(imageIndex) + 1 < mImages.Length()) {
lm->CompositeUntil(mImages[imageIndex + 1].mTimeStamp + TimeDuration::FromMilliseconds(BIAS_TIME_MS));
}
TimedImage* img = &mImages[imageIndex];
img->mTextureHost->SetTextureSourceProvider(aProvider);
SetCurrentTextureHost(img->mTextureHost);
aOutInfo->imageIndex = imageIndex;
aOutInfo->img = img;
aOutInfo->host = mCurrentTextureHost;
return true;
}
RefPtr<TextureSource>
ImageHost::AcquireTextureSource(const RenderInfo& aInfo)
{
MOZ_ASSERT(aInfo.host == mCurrentTextureHost);
if (!aInfo.host->AcquireTextureSource(mCurrentTextureSource)) {
return nullptr;
}
return mCurrentTextureSource.get();
}
void
ImageHost::FinishRendering(const RenderInfo& aInfo)
{
HostLayerManager* lm = GetLayerManager();
TimedImage* img = aInfo.img;
int imageIndex = aInfo.imageIndex;
if (mLastFrameID != img->mFrameID || mLastProducerID != img->mProducerID) {
if (mAsyncRef) {
ImageCompositeNotificationInfo info;
info.mImageBridgeProcessId = mAsyncRef.mProcessId;
info.mNotification = ImageCompositeNotification(
mAsyncRef.mHandle,
img->mTimeStamp, lm->GetCompositionTime(),
img->mFrameID, img->mProducerID);
lm->AppendImageCompositeNotification(info);
}
mLastFrameID = img->mFrameID;
mLastProducerID = img->mProducerID;
}
// Update mBias last. This can change which frame ChooseImage(Index) would
// return, and we don't want to do that until we've finished compositing
// since callers of ChooseImage(Index) assume the same image will be chosen

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

@ -90,6 +90,31 @@ public:
bool IsOpaque();
struct RenderInfo {
int imageIndex;
TimedImage* img;
RefPtr<TextureHost> host;
RenderInfo() : imageIndex(-1), img(nullptr)
{}
};
// Acquire rendering information for the current frame.
bool PrepareToRender(TextureSourceProvider* aProvider, RenderInfo* aOutInfo);
// Acquire the TextureSource for the currently prepared frame.
RefPtr<TextureSource> AcquireTextureSource(const RenderInfo& aInfo);
// Send ImageComposite notifications and update the ChooseImage bias.
void FinishRendering(const RenderInfo& aInfo);
// This should only be called inside a lock, or during rendering. It is
// infallible to enforce this.
TextureHost* CurrentTextureHost() const {
MOZ_ASSERT(mCurrentTextureHost);
return mCurrentTextureHost;
}
protected:
// ImageComposite
virtual TimeStamp GetCompositionTime() const override;

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

@ -1406,6 +1406,15 @@ LayerManagerComposite::AutoAddMaskEffect::~AutoAddMaskEffect()
mCompositable->RemoveMaskEffect();
}
bool
LayerManagerComposite::IsCompositingToScreen() const
{
if (!mCompositor) {
return true;
}
return !mCompositor->GetTargetContext();
}
LayerComposite::LayerComposite(LayerManagerComposite *aManager)
: HostLayer(aManager)
, mCompositeManager(aManager)

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

@ -132,6 +132,18 @@ public:
aNotifications->AppendElements(Move(mImageCompositeNotifications));
}
void AppendImageCompositeNotification(const ImageCompositeNotificationInfo& aNotification)
{
// Only send composite notifications when we're drawing to the screen,
// because that's what they mean.
// Also when we're not drawing to the screen, DidComposite will not be
// called to extract and send these notifications, so they might linger
// and contain stale ImageContainerParent pointers.
if (IsCompositingToScreen()) {
mImageCompositeNotifications.AppendElement(aNotification);
}
}
/**
* LayerManagerComposite provides sophisticated debug overlays
* that can request a next frame.
@ -164,6 +176,9 @@ public:
virtual bool AlwaysScheduleComposite() const {
return false;
}
virtual bool IsCompositingToScreen() const {
return false;
}
void RecordPaintTimes(const PaintTiming& aTiming);
void RecordUpdateTime(float aValue);
@ -290,6 +305,7 @@ public:
CreateOptimalMaskDrawTarget(const IntSize &aSize) override;
virtual const char* Name() const override { return ""; }
virtual bool IsCompositingToScreen() const override;
bool AlwaysScheduleComposite() const override;
@ -386,19 +402,6 @@ public:
bool AsyncPanZoomEnabled() const override;
public:
void AppendImageCompositeNotification(const ImageCompositeNotificationInfo& aNotification)
{
// Only send composite notifications when we're drawing to the screen,
// because that's what they mean.
// Also when we're not drawing to the screen, DidComposite will not be
// called to extract and send these notifications, so they might linger
// and contain stale ImageContainerParent pointers.
if (!mCompositor->GetTargetContext()) {
mImageCompositeNotifications.AppendElement(aNotification);
}
}
public:
virtual TextureFactoryIdentifier GetTextureFactoryIdentifier() override
{