2017-06-29 01:03:27 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
#include "WebRenderUserData.h"
|
2017-08-03 08:55:13 +03:00
|
|
|
|
|
|
|
#include "mozilla/layers/ImageClient.h"
|
|
|
|
#include "mozilla/layers/WebRenderBridgeChild.h"
|
|
|
|
#include "mozilla/layers/WebRenderLayerManager.h"
|
|
|
|
#include "mozilla/layers/WebRenderMessages.h"
|
2017-07-05 19:29:41 +03:00
|
|
|
#include "nsDisplayListInvalidation.h"
|
2017-08-03 08:55:14 +03:00
|
|
|
#include "WebRenderCanvasRenderer.h"
|
2017-06-29 01:03:27 +03:00
|
|
|
|
|
|
|
namespace mozilla {
|
|
|
|
namespace layers {
|
|
|
|
|
2017-08-03 06:20:53 +03:00
|
|
|
WebRenderUserData::WebRenderUserData(WebRenderLayerManager* aWRManager)
|
|
|
|
: mWRManager(aWRManager)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
WebRenderUserData::~WebRenderUserData()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2017-08-18 10:21:20 +03:00
|
|
|
bool
|
|
|
|
WebRenderUserData::IsDataValid(WebRenderLayerManager* aManager)
|
|
|
|
{
|
|
|
|
return aManager == mWRManager;
|
|
|
|
}
|
|
|
|
|
2017-06-29 01:03:27 +03:00
|
|
|
WebRenderBridgeChild*
|
|
|
|
WebRenderUserData::WrBridge() const
|
|
|
|
{
|
|
|
|
return mWRManager->WrBridge();
|
|
|
|
}
|
|
|
|
|
|
|
|
WebRenderImageData::WebRenderImageData(WebRenderLayerManager* aWRManager)
|
|
|
|
: WebRenderUserData(aWRManager)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
WebRenderImageData::~WebRenderImageData()
|
|
|
|
{
|
|
|
|
if (mKey) {
|
|
|
|
mWRManager->AddImageKeyForDiscard(mKey.value());
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mExternalImageId) {
|
|
|
|
WrBridge()->DeallocExternalImageId(mExternalImageId.ref());
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mPipelineId) {
|
2017-08-03 08:55:13 +03:00
|
|
|
WrBridge()->RemovePipelineIdForCompositable(mPipelineId.ref());
|
2017-06-29 01:03:27 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Maybe<wr::ImageKey>
|
2017-07-05 19:29:41 +03:00
|
|
|
WebRenderImageData::UpdateImageKey(ImageContainer* aContainer, bool aForceUpdate)
|
2017-06-29 01:03:27 +03:00
|
|
|
{
|
|
|
|
CreateImageClientIfNeeded();
|
|
|
|
CreateExternalImageIfNeeded();
|
|
|
|
|
2017-08-31 12:30:36 +03:00
|
|
|
if (mContainer != aContainer) {
|
|
|
|
mContainer = aContainer;
|
|
|
|
}
|
|
|
|
|
2017-06-29 01:03:27 +03:00
|
|
|
if (!mImageClient || !mExternalImageId) {
|
|
|
|
return Nothing();
|
|
|
|
}
|
|
|
|
|
|
|
|
MOZ_ASSERT(mImageClient->AsImageClientSingle());
|
|
|
|
MOZ_ASSERT(aContainer);
|
|
|
|
|
|
|
|
ImageClientSingle* imageClient = mImageClient->AsImageClientSingle();
|
|
|
|
uint32_t oldCounter = imageClient->GetLastUpdateGenerationCounter();
|
|
|
|
|
|
|
|
bool ret = imageClient->UpdateImage(aContainer, /* unused */0);
|
|
|
|
if (!ret || imageClient->IsEmpty()) {
|
|
|
|
// Delete old key
|
|
|
|
if (mKey) {
|
|
|
|
mWRManager->AddImageKeyForDiscard(mKey.value());
|
|
|
|
mKey = Nothing();
|
|
|
|
}
|
|
|
|
return Nothing();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Reuse old key if generation is not updated.
|
2017-07-05 19:29:41 +03:00
|
|
|
if (!aForceUpdate && oldCounter == imageClient->GetLastUpdateGenerationCounter() && mKey) {
|
2017-06-29 01:03:27 +03:00
|
|
|
return mKey;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Delete old key, we are generating a new key.
|
|
|
|
if (mKey) {
|
|
|
|
mWRManager->AddImageKeyForDiscard(mKey.value());
|
|
|
|
}
|
|
|
|
|
2017-06-28 02:20:36 +03:00
|
|
|
wr::WrImageKey key = WrBridge()->GetNextImageKey();
|
2017-06-29 01:03:27 +03:00
|
|
|
mWRManager->WrBridge()->AddWebRenderParentCommand(OpAddExternalImage(mExternalImageId.value(), key));
|
|
|
|
mKey = Some(key);
|
|
|
|
|
|
|
|
return mKey;
|
|
|
|
}
|
|
|
|
|
2017-07-05 19:29:41 +03:00
|
|
|
already_AddRefed<ImageClient>
|
|
|
|
WebRenderImageData::GetImageClient()
|
|
|
|
{
|
|
|
|
RefPtr<ImageClient> imageClient = mImageClient;
|
|
|
|
return imageClient.forget();
|
|
|
|
}
|
|
|
|
|
2017-06-29 01:03:27 +03:00
|
|
|
void
|
|
|
|
WebRenderImageData::CreateAsyncImageWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
|
|
|
|
ImageContainer* aContainer,
|
|
|
|
const StackingContextHelper& aSc,
|
|
|
|
const LayerRect& aBounds,
|
|
|
|
const LayerRect& aSCBounds,
|
2017-08-03 08:55:13 +03:00
|
|
|
const gfx::Matrix4x4& aSCTransform,
|
|
|
|
const gfx::MaybeIntSize& aScaleToSize,
|
2017-07-19 10:28:58 +03:00
|
|
|
const wr::ImageRendering& aFilter,
|
|
|
|
const wr::MixBlendMode& aMixBlendMode)
|
2017-06-29 01:03:27 +03:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(aContainer->IsAsync());
|
|
|
|
if (!mPipelineId) {
|
|
|
|
// Alloc async image pipeline id.
|
|
|
|
mPipelineId = Some(WrBridge()->GetCompositorBridgeChild()->GetNextPipelineId());
|
|
|
|
WrBridge()->AddPipelineIdForAsyncCompositable(mPipelineId.ref(),
|
|
|
|
aContainer->GetAsyncContainerHandle());
|
|
|
|
}
|
|
|
|
MOZ_ASSERT(!mImageClient);
|
|
|
|
MOZ_ASSERT(!mExternalImageId);
|
|
|
|
|
|
|
|
// Push IFrame for async image pipeline.
|
|
|
|
//
|
|
|
|
// We don't push a stacking context for this async image pipeline here.
|
|
|
|
// Instead, we do it inside the iframe that hosts the image. As a result,
|
|
|
|
// a bunch of the calculations normally done as part of that stacking
|
|
|
|
// context need to be done manually and pushed over to the parent side,
|
|
|
|
// where it will be done when we build the display list for the iframe.
|
2017-07-25 11:54:36 +03:00
|
|
|
// That happens in AsyncImagePipelineManager.
|
2017-07-19 01:32:46 +03:00
|
|
|
wr::LayoutRect r = aSc.ToRelativeLayoutRect(aBounds);
|
2017-07-10 14:22:39 +03:00
|
|
|
aBuilder.PushIFrame(r, mPipelineId.ref());
|
2017-06-29 01:03:27 +03:00
|
|
|
|
|
|
|
WrBridge()->AddWebRenderParentCommand(OpUpdateAsyncImagePipeline(mPipelineId.value(),
|
|
|
|
aSCBounds,
|
|
|
|
aSCTransform,
|
|
|
|
aScaleToSize,
|
|
|
|
aFilter,
|
|
|
|
aMixBlendMode));
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
WebRenderImageData::CreateImageClientIfNeeded()
|
|
|
|
{
|
|
|
|
if (!mImageClient) {
|
|
|
|
mImageClient = ImageClient::CreateImageClient(CompositableType::IMAGE,
|
|
|
|
WrBridge(),
|
|
|
|
TextureFlags::DEFAULT);
|
|
|
|
if (!mImageClient) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
mImageClient->Connect();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
WebRenderImageData::CreateExternalImageIfNeeded()
|
|
|
|
{
|
|
|
|
if (!mExternalImageId) {
|
|
|
|
mExternalImageId = Some(WrBridge()->AllocExternalImageIdForCompositable(mImageClient));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-24 09:43:55 +03:00
|
|
|
WebRenderFallbackData::WebRenderFallbackData(WebRenderLayerManager* aWRManager)
|
|
|
|
: WebRenderImageData(aWRManager)
|
|
|
|
, mInvalid(false)
|
2017-07-05 19:29:41 +03:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2017-07-24 09:43:55 +03:00
|
|
|
WebRenderFallbackData::~WebRenderFallbackData()
|
2017-07-05 19:29:41 +03:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
nsAutoPtr<nsDisplayItemGeometry>
|
|
|
|
WebRenderFallbackData::GetGeometry()
|
|
|
|
{
|
|
|
|
return mGeometry;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
WebRenderFallbackData::SetGeometry(nsAutoPtr<nsDisplayItemGeometry> aGeometry)
|
|
|
|
{
|
|
|
|
mGeometry = aGeometry;
|
|
|
|
}
|
|
|
|
|
2017-07-21 09:21:47 +03:00
|
|
|
WebRenderAnimationData::WebRenderAnimationData(WebRenderLayerManager* aWRManager)
|
|
|
|
: WebRenderUserData(aWRManager),
|
|
|
|
mAnimationInfo(aWRManager)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2017-08-03 08:55:14 +03:00
|
|
|
WebRenderCanvasData::WebRenderCanvasData(WebRenderLayerManager* aWRManager)
|
|
|
|
: WebRenderUserData(aWRManager)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
WebRenderCanvasData::~WebRenderCanvasData()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
WebRenderCanvasRendererAsync*
|
|
|
|
WebRenderCanvasData::GetCanvasRenderer()
|
|
|
|
{
|
|
|
|
if (!mCanvasRenderer) {
|
|
|
|
mCanvasRenderer = MakeUnique<WebRenderCanvasRendererAsync>(mWRManager);
|
|
|
|
}
|
|
|
|
|
|
|
|
return mCanvasRenderer.get();
|
|
|
|
}
|
|
|
|
|
2017-06-29 01:03:27 +03:00
|
|
|
} // namespace layers
|
|
|
|
} // namespace mozilla
|