Bug 1494403 - Separate the Blob related apis. r=jrmuizel

This commit contains the Gecko-side changes from WebRender PR#3277:
 - Dedicated DirtyRect type.
 - Separate the blob image APIs from regular image ones.

Differential Revision: https://phabricator.services.mozilla.com/D12463

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Nicolas Silva 2018-11-23 23:33:49 +00:00
parent 68f4347fa8
commit 2fa6078f12
18 changed files with 262 additions and 114 deletions

View File

@ -22,6 +22,7 @@ using mozilla::wr::MaybeFontInstancePlatformOptions from "mozilla/webrender/WebR
using mozilla::wr::FontInstanceKey from "mozilla/webrender/WebRenderTypes.h";
using mozilla::wr::FontKey from "mozilla/webrender/WebRenderTypes.h";
using mozilla::wr::ImageKey from "mozilla/webrender/WebRenderTypes.h";
using mozilla::wr::BlobImageKey from "mozilla/webrender/WebRenderTypes.h";
using mozilla::wr::PipelineId from "mozilla/webrender/WebRenderTypes.h";
using mozilla::gfx::MaybeIntSize from "mozilla/gfx/Point.h";
using mozilla::LayoutDeviceRect from "Units.h";
@ -117,7 +118,7 @@ struct OpAddBlobImage {
ImageDescriptor descriptor;
OffsetRange bytes;
uint16_t tiling;
ImageKey key;
BlobImageKey key;
};
struct OpUpdateImage {
@ -129,13 +130,13 @@ struct OpUpdateImage {
struct OpUpdateBlobImage {
ImageDescriptor descriptor;
OffsetRange bytes;
ImageKey key;
BlobImageKey key;
ImageIntRect dirtyRect;
};
struct OpSetImageVisibleArea {
ImageIntRect area;
ImageKey key;
BlobImageKey key;
};
struct OpUpdateExternalImage {
@ -148,6 +149,10 @@ struct OpDeleteImage {
ImageKey key;
};
struct OpDeleteBlobImage {
BlobImageKey key;
};
struct OpAddRawFont {
OffsetRange bytes;
uint32_t fontIndex;
@ -184,6 +189,7 @@ union OpUpdateResource {
OpUpdateBlobImage;
OpSetImageVisibleArea;
OpDeleteImage;
OpDeleteBlobImage;
OpAddRawFont;
OpAddFontDescriptor;
OpDeleteFont;

View File

@ -300,7 +300,7 @@ IpcResourceUpdateQueue::AddImage(ImageKey key, const ImageDescriptor& aDescripto
}
bool
IpcResourceUpdateQueue::AddBlobImage(ImageKey key, const ImageDescriptor& aDescriptor,
IpcResourceUpdateQueue::AddBlobImage(BlobImageKey key, const ImageDescriptor& aDescriptor,
Range<uint8_t> aBytes)
{
MOZ_RELEASE_ASSERT(aDescriptor.width > 0 && aDescriptor.height > 0);
@ -344,7 +344,7 @@ IpcResourceUpdateQueue::UpdateImageBuffer(ImageKey aKey,
}
bool
IpcResourceUpdateQueue::UpdateBlobImage(ImageKey aKey,
IpcResourceUpdateQueue::UpdateBlobImage(BlobImageKey aKey,
const ImageDescriptor& aDescriptor,
Range<uint8_t> aBytes,
ImageIntRect aDirtyRect)
@ -366,8 +366,8 @@ IpcResourceUpdateQueue::UpdateExternalImage(wr::ExternalImageId aExtId,
}
void
IpcResourceUpdateQueue::SetImageVisibleArea(ImageKey aKey,
const ImageIntRect& aArea)
IpcResourceUpdateQueue::SetBlobImageVisibleArea(wr::BlobImageKey aKey,
const ImageIntRect& aArea)
{
mUpdates.AppendElement(layers::OpSetImageVisibleArea(aArea, aKey));
}
@ -378,6 +378,12 @@ IpcResourceUpdateQueue::DeleteImage(ImageKey aKey)
mUpdates.AppendElement(layers::OpDeleteImage(aKey));
}
void
IpcResourceUpdateQueue::DeleteBlobImage(BlobImageKey aKey)
{
mUpdates.AppendElement(layers::OpDeleteBlobImage(aKey));
}
bool
IpcResourceUpdateQueue::AddRawFont(wr::FontKey aKey, Range<uint8_t> aBytes, uint32_t aIndex)
{

View File

@ -91,7 +91,7 @@ public:
const ImageDescriptor& aDescriptor,
Range<uint8_t> aBytes);
bool AddBlobImage(wr::ImageKey aKey,
bool AddBlobImage(wr::BlobImageKey aKey,
const ImageDescriptor& aDescriptor,
Range<uint8_t> aBytes);
@ -106,7 +106,7 @@ public:
const ImageDescriptor& aDescriptor,
Range<uint8_t> aBytes);
bool UpdateBlobImage(wr::ImageKey aKey,
bool UpdateBlobImage(wr::BlobImageKey aKey,
const ImageDescriptor& aDescriptor,
Range<uint8_t> aBytes,
ImageIntRect aDirtyRect);
@ -115,10 +115,12 @@ public:
ImageKey aKey,
ImageIntRect aDirtyRect);
void SetImageVisibleArea(ImageKey aKey, const ImageIntRect& aArea);
void SetBlobImageVisibleArea(BlobImageKey aKey, const ImageIntRect& aArea);
void DeleteImage(wr::ImageKey aKey);
void DeleteBlobImage(wr::BlobImageKey aKey);
bool AddRawFont(wr::FontKey aKey, Range<uint8_t> aBytes, uint32_t aIndex);
bool AddFontDescriptor(wr::FontKey aKey, Range<uint8_t> aBytes, uint32_t aIndex);

View File

@ -461,7 +461,7 @@ WebRenderBridgeParent::UpdateResources(const nsTArray<OpUpdateResource>& aResour
if (!reader.Read(op.bytes(), bytes)) {
return false;
}
aUpdates.UpdateBlobImage(op.key(), op.descriptor(), bytes, wr::ToDeviceIntRect(op.dirtyRect()));
aUpdates.UpdateBlobImage(op.key(), op.descriptor(), bytes, wr::ToLayoutIntRect(op.dirtyRect()));
break;
}
case OpUpdateResource::TOpSetImageVisibleArea: {
@ -534,6 +534,11 @@ WebRenderBridgeParent::UpdateResources(const nsTArray<OpUpdateResource>& aResour
DeleteImage(op.key(), aUpdates);
break;
}
case OpUpdateResource::TOpDeleteBlobImage: {
const auto& op = cmd.get_OpDeleteBlobImage();
aUpdates.DeleteBlobImage(op.key());
break;
}
case OpUpdateResource::TOpDeleteFont: {
const auto& op = cmd.get_OpDeleteFont();
aUpdates.DeleteFont(op.key());

View File

@ -341,7 +341,7 @@ struct DIGroup
// The current bounds of the blob image, relative to
// the top-left of the mLayerBounds.
IntRect mImageBounds;
Maybe<wr::ImageKey> mKey;
Maybe<wr::BlobImageKey> mKey;
std::vector<RefPtr<SourceSurface>> mExternalSurfaces;
std::vector<RefPtr<ScaledFont>> mFonts;
@ -378,7 +378,7 @@ struct DIGroup
{
if (mKey) {
MOZ_RELEASE_ASSERT(aForce || mInvalidRect.IsEmpty());
aManager->AddImageKeyForDiscard(mKey.value());
aManager->AddBlobImageKeyForDiscard(mKey.value());
mKey = Nothing();
}
mFonts.clear();
@ -634,7 +634,7 @@ struct DIGroup
GP("Not repainting group because it's empty\n");
GP("End EndGroup\n");
if (mKey) {
aResources.SetImageVisibleArea(
aResources.SetBlobImageVisibleArea(
mKey.value(),
ViewAs<ImagePixel>(mPaintRect, PixelCastJustification::LayerIsImage));
PushImage(aBuilder, bounds);
@ -688,8 +688,8 @@ struct DIGroup
if (!mKey) {
if (!hasItems) // we don't want to send a new image that doesn't have any items in it
return;
wr::ImageKey key = aWrManager->WrBridge()->GetNextImageKey();
GP("No previous key making new one %d\n", key.mHandle);
wr::BlobImageKey key = wr::BlobImageKey { aWrManager->WrBridge()->GetNextImageKey() };
GP("No previous key making new one %d\n", key._0.mHandle);
wr::ImageDescriptor descriptor(dtSize, 0, dt->GetFormat(), opacity);
MOZ_RELEASE_ASSERT(bytes.length() > sizeof(size_t));
if (!aResources.AddBlobImage(key, descriptor, bytes)) {
@ -708,7 +708,7 @@ struct DIGroup
}
mFonts = std::move(fonts);
mInvalidRect.SetEmpty();
aResources.SetImageVisibleArea(
aResources.SetBlobImageVisibleArea(
mKey.value(),
ViewAs<ImagePixel>(mPaintRect, PixelCastJustification::LayerIsImage));
PushImage(aBuilder, bounds);
@ -733,7 +733,7 @@ struct DIGroup
aBuilder.SetHitTestInfo(mScrollId, hitInfo);
aBuilder.PushImage(dest, dest, !backfaceHidden,
wr::ToImageRendering(sampleFilter),
mKey.value());
wr::AsImageKey(mKey.value()));
aBuilder.ClearHitTestInfo();
}
@ -1602,13 +1602,13 @@ WebRenderCommandBuilder::PopOverrideForASR(const ActiveScrolledRoot* aASR)
Maybe<wr::ImageKey>
WebRenderCommandBuilder::CreateImageKey(nsDisplayItem* aItem,
ImageContainer* aContainer,
mozilla::wr::DisplayListBuilder& aBuilder,
mozilla::wr::IpcResourceUpdateQueue& aResources,
mozilla::wr::ImageRendering aRendering,
const StackingContextHelper& aSc,
gfx::IntSize& aSize,
const Maybe<LayoutDeviceRect>& aAsyncImageBounds)
ImageContainer* aContainer,
mozilla::wr::DisplayListBuilder& aBuilder,
mozilla::wr::IpcResourceUpdateQueue& aResources,
mozilla::wr::ImageRendering aRendering,
const StackingContextHelper& aSc,
gfx::IntSize& aSize,
const Maybe<LayoutDeviceRect>& aAsyncImageBounds)
{
RefPtr<WebRenderImageData> imageData = CreateOrRecycleWebRenderUserData<WebRenderImageData>(aItem);
MOZ_ASSERT(imageData);
@ -1953,7 +1953,7 @@ WebRenderCommandBuilder::GenerateFallbackData(nsDisplayItem* aItem,
needPaint = !invalidRegion.IsEmpty();
}
if (needPaint || !fallbackData->GetKey()) {
if (needPaint || !fallbackData->GetImageKey()) {
nsAutoPtr<nsDisplayItemGeometry> newGeometry;
newGeometry = aItem->AllocateGeometry(aDisplayListBuilder);
fallbackData->SetGeometry(std::move(newGeometry));
@ -1996,17 +1996,17 @@ WebRenderCommandBuilder::GenerateFallbackData(nsDisplayItem* aItem,
if (isInvalidated) {
Range<uint8_t> bytes((uint8_t *)recorder->mOutputStream.mData, recorder->mOutputStream.mLength);
wr::ImageKey key = mManager->WrBridge()->GetNextImageKey();
wr::BlobImageKey key = wr::BlobImageKey { mManager->WrBridge()->GetNextImageKey() };
wr::ImageDescriptor descriptor(dtSize.ToUnknownSize(), 0, dt->GetFormat(), opacity);
if (!aResources.AddBlobImage(key, descriptor, bytes)) {
return nullptr;
}
fallbackData->SetKey(key);
fallbackData->SetBlobImageKey(key);
fallbackData->SetFonts(fonts);
} else {
// If there is no invalidation region and we don't have a image key,
// it means we don't need to push image for the item.
if (!fallbackData->GetKey().isSome()) {
if (!fallbackData->GetBlobImageKey().isSome()) {
return nullptr;
}
}
@ -2040,7 +2040,7 @@ WebRenderCommandBuilder::GenerateFallbackData(nsDisplayItem* aItem,
} else {
// If there is no invalidation region and we don't have a image key,
// it means we don't need to push image for the item.
if (!fallbackData->GetKey().isSome()) {
if (!fallbackData->GetImageKey().isSome()) {
return nullptr;
}
}
@ -2061,7 +2061,7 @@ WebRenderCommandBuilder::GenerateFallbackData(nsDisplayItem* aItem,
// Update current bounds to fallback data
fallbackData->SetBounds(paintBounds);
MOZ_ASSERT(fallbackData->GetKey());
MOZ_ASSERT(fallbackData->GetImageKey());
return fallbackData.forget();
}
@ -2083,7 +2083,7 @@ WebRenderCommandBuilder::BuildWrMaskImage(nsDisplayItem* aItem,
}
wr::WrImageMask imageMask;
imageMask.image = fallbackData->GetKey().value();
imageMask.image = fallbackData->GetImageKey().value();
imageMask.rect = wr::ToRoundedLayoutRect(imageRect);
imageMask.repeat = false;
return Some(imageMask);
@ -2110,7 +2110,7 @@ WebRenderCommandBuilder::PushItemAsImage(nsDisplayItem* aItem,
dest,
!aItem->BackfaceIsHidden(),
wr::ToImageRendering(sampleFilter),
fallbackData->GetKey().value());
fallbackData->GetImageKey().value());
return true;
}

View File

@ -108,7 +108,7 @@ WebRenderLayerManager::DoDestroy(bool aIsSync)
if (WrBridge()) {
// Just clear ImageKeys, they are deleted during WebRenderAPI destruction.
mImageKeysToDelete.Clear();
DiscardLocalImages();
// CompositorAnimations are cleared by WebRenderBridgeParent.
mDiscardedCompositorAnimationsIds.Clear();
WrBridge()->Destroy(aIsSync);
@ -369,11 +369,7 @@ WebRenderLayerManager::EndTransactionWithoutLayer(nsDisplayList* aDisplayList,
mAsyncResourceUpdates.reset();
}
for (const auto& key : mImageKeysToDelete) {
resourceUpdates.DeleteImage(key);
}
mImageKeysToDelete.Clear();
DiscardImagesInTransaction(resourceUpdates);
WrBridge()->RemoveExpiredFontKeys(resourceUpdates);
// Skip the synchronization for buffer since we also skip the painting during
@ -482,14 +478,30 @@ WebRenderLayerManager::AddImageKeyForDiscard(wr::ImageKey key)
mImageKeysToDelete.AppendElement(key);
}
void
WebRenderLayerManager::AddBlobImageKeyForDiscard(wr::BlobImageKey key)
{
mBlobImageKeysToDelete.AppendElement(key);
}
void
WebRenderLayerManager::DiscardImagesInTransaction(wr::IpcResourceUpdateQueue& aResources)
{
for (const auto& key : mImageKeysToDelete) {
aResources.DeleteImage(key);
}
for (const auto& key : mBlobImageKeysToDelete) {
aResources.DeleteBlobImage(key);
}
mImageKeysToDelete.Clear();
mBlobImageKeysToDelete.Clear();
}
void
WebRenderLayerManager::DiscardImages()
{
wr::IpcResourceUpdateQueue resources(WrBridge());
for (const auto& key : mImageKeysToDelete) {
resources.DeleteImage(key);
}
mImageKeysToDelete.Clear();
DiscardImagesInTransaction(resources);
WrBridge()->UpdateResources(resources);
}
@ -532,6 +544,7 @@ WebRenderLayerManager::DiscardLocalImages()
// This is useful in empty / failed transactions where we created
// image keys but didn't tell the parent about them yet.
mImageKeysToDelete.Clear();
mBlobImageKeysToDelete.Clear();
}
void

View File

@ -134,7 +134,9 @@ public:
// adds an imagekey to a list of keys that will be discarded on the next
// transaction or destruction
void AddImageKeyForDiscard(wr::ImageKey);
void AddBlobImageKeyForDiscard(wr::BlobImageKey);
void DiscardImages();
void DiscardImagesInTransaction(wr::IpcResourceUpdateQueue& aResourceUpdates);
void DiscardLocalImages();
wr::IpcResourceUpdateQueue& AsyncResourceUpdates();
@ -189,6 +191,7 @@ private:
private:
nsIWidget* MOZ_NON_OWNING_REF mWidget;
nsTArray<wr::ImageKey> mImageKeysToDelete;
nsTArray<wr::BlobImageKey> mBlobImageKeysToDelete;
// Set of compositor animation ids for which there are active animations (as
// of the last transaction) on the compositor side.

View File

@ -75,6 +75,12 @@ struct ParamTraits<mozilla::wr::ImageKey>
{
};
template<>
struct ParamTraits<mozilla::wr::BlobImageKey>
: public PlainOldDataSerializer<mozilla::wr::BlobImageKey>
{
};
template<>
struct ParamTraits<mozilla::wr::FontKey>
: public PlainOldDataSerializer<mozilla::wr::FontKey>

View File

@ -217,15 +217,6 @@ WebRenderImageData::UpdateImageKey(ImageContainer* aContainer,
return mKey;
}
void
WebRenderImageData::SetKey(const wr::ImageKey& aKey)
{
MOZ_ASSERT_IF(mKey, mKey.value() != aKey);
ClearImageKey();
mKey = Some(aKey);
mOwnsKey = true;
}
already_AddRefed<ImageClient>
WebRenderImageData::GetImageClient()
{
@ -319,6 +310,35 @@ WebRenderFallbackData::SetGeometry(nsAutoPtr<nsDisplayItemGeometry> aGeometry)
mGeometry = aGeometry;
}
void
WebRenderFallbackData::SetBlobImageKey(const wr::BlobImageKey& aKey)
{
ClearImageKey();
mBlobKey = Some(aKey);
mOwnsKey = true;
}
Maybe<wr::ImageKey>
WebRenderFallbackData::GetImageKey()
{
if (mBlobKey) {
return Some(wr::AsImageKey(mBlobKey.value()));
}
return mKey;
}
void
WebRenderFallbackData::ClearImageKey()
{
if (mBlobKey && mOwnsKey) {
mWRManager->AddBlobImageKeyForDiscard(mBlobKey.value());
}
mBlobKey.reset();
WebRenderImageData::ClearImageKey();
}
WebRenderAnimationData::WebRenderAnimationData(WebRenderLayerManager* aWRManager, nsDisplayItem* aItem)
: WebRenderUserData(aWRManager, aItem)
{

View File

@ -116,6 +116,8 @@ struct WebRenderUserDataKey {
typedef nsRefPtrHashtable<nsGenericHashKey<mozilla::layers::WebRenderUserDataKey>, WebRenderUserData> WebRenderUserDataTable;
/// Holds some data used to share TextureClient/ImageClient with the parent
/// process except if used with blob images (watch your step).
class WebRenderImageData : public WebRenderUserData
{
public:
@ -125,8 +127,8 @@ public:
virtual WebRenderImageData* AsImageData() override { return this; }
virtual UserDataType GetType() override { return UserDataType::eImage; }
static UserDataType Type() { return UserDataType::eImage; }
Maybe<wr::ImageKey> GetKey() { return mKey; }
void SetKey(const wr::ImageKey& aKey);
virtual Maybe<wr::ImageKey> GetImageKey() { return mKey; }
void SetImageKey(const wr::ImageKey& aKey);
already_AddRefed<ImageClient> GetImageClient();
Maybe<wr::ImageKey> UpdateImageKey(ImageContainer* aContainer,
@ -154,7 +156,7 @@ public:
bool IsAsyncAnimatedImage() const;
protected:
void ClearImageKey();
virtual void ClearImageKey();
RefPtr<TextureClient> mTextureOfImage;
Maybe<wr::ImageKey> mKey;
@ -164,6 +166,14 @@ protected:
bool mOwnsKey;
};
/// Used for fallback rendering.
///
/// In most cases this uses blob images but it can also render on the content side directly into
/// a texture.
///
/// TODO(nical) It would be much better to separate the two use cases into separate classes and
/// not have the blob image related code inherit from WebRenderImageData (the current code only
/// works if we carefully use a subset of the parent code).
class WebRenderFallbackData : public WebRenderImageData
{
public:
@ -182,10 +192,16 @@ public:
gfx::Size GetScale() { return mScale; }
bool IsInvalid() { return mInvalid; }
void SetFonts(const std::vector<RefPtr<gfx::ScaledFont>>& aFonts) { mFonts = aFonts; }
Maybe<wr::BlobImageKey> GetBlobImageKey() { return mBlobKey; }
virtual Maybe<wr::ImageKey> GetImageKey() override;
void SetBlobImageKey(const wr::BlobImageKey& aKey);
RefPtr<BasicLayerManager> mBasicLayerManager;
std::vector<RefPtr<gfx::SourceSurface>> mExternalSurfaces;
protected:
virtual void ClearImageKey() override;
Maybe<wr::BlobImageKey> mBlobKey;
nsAutoPtr<nsDisplayItemGeometry> mGeometry;
nsRect mBounds;
bool mInvalid;

View File

@ -323,7 +323,7 @@ static bool Moz2DRenderCallback(const Range<const uint8_t> aBlob,
gfx::SurfaceFormat aFormat,
const uint16_t *aTileSize,
const mozilla::wr::TileOffset *aTileOffset,
const mozilla::wr::DeviceIntRect *aDirtyRect,
const mozilla::wr::LayoutIntRect *aDirtyRect,
Range<uint8_t> aOutput)
{
AUTO_PROFILER_TRACING("WebRender", "RasterizeSingleBlob");
@ -486,7 +486,7 @@ bool wr_moz2d_render_cb(const mozilla::wr::ByteSlice blob,
mozilla::wr::ImageFormat aFormat,
const uint16_t *aTileSize,
const mozilla::wr::TileOffset *aTileOffset,
const mozilla::wr::DeviceIntRect *aDirtyRect,
const mozilla::wr::LayoutIntRect *aDirtyRect,
mozilla::wr::MutByteSlice output)
{
return mozilla::wr::Moz2DRenderCallback(mozilla::wr::ByteSliceToRange(blob),

View File

@ -636,7 +636,7 @@ TransactionBuilder::AddImage(ImageKey key, const ImageDescriptor& aDescriptor,
}
void
TransactionBuilder::AddBlobImage(ImageKey key, const ImageDescriptor& aDescriptor,
TransactionBuilder::AddBlobImage(BlobImageKey key, const ImageDescriptor& aDescriptor,
wr::Vec<uint8_t>& aBytes)
{
wr_resource_updates_add_blob_image(mTxn,
@ -683,10 +683,10 @@ TransactionBuilder::UpdateImageBuffer(ImageKey aKey,
}
void
TransactionBuilder::UpdateBlobImage(ImageKey aKey,
TransactionBuilder::UpdateBlobImage(BlobImageKey aKey,
const ImageDescriptor& aDescriptor,
wr::Vec<uint8_t>& aBytes,
const wr::DeviceIntRect& aDirtyRect)
const wr::LayoutIntRect& aDirtyRect)
{
wr_resource_updates_update_blob_image(mTxn,
aKey,
@ -728,10 +728,10 @@ TransactionBuilder::UpdateExternalImageWithDirtyRect(ImageKey aKey,
}
void
TransactionBuilder::SetImageVisibleArea(ImageKey aKey,
TransactionBuilder::SetImageVisibleArea(BlobImageKey aKey,
const wr::DeviceIntRect& aArea)
{
wr_resource_updates_set_image_visible_area(mTxn, aKey, &aArea);
wr_resource_updates_set_blob_image_visible_area(mTxn, aKey, &aArea);
}
void
@ -740,6 +740,12 @@ TransactionBuilder::DeleteImage(ImageKey aKey)
wr_resource_updates_delete_image(mTxn, aKey);
}
void
TransactionBuilder::DeleteBlobImage(BlobImageKey aKey)
{
wr_resource_updates_delete_blob_image(mTxn, aKey);
}
void
TransactionBuilder::AddRawFont(wr::FontKey aKey, wr::Vec<uint8_t>& aBytes, uint32_t aIndex)
{

View File

@ -107,7 +107,7 @@ public:
const ImageDescriptor& aDescriptor,
wr::Vec<uint8_t>& aBytes);
void AddBlobImage(wr::ImageKey aKey,
void AddBlobImage(wr::BlobImageKey aKey,
const ImageDescriptor& aDescriptor,
wr::Vec<uint8_t>& aBytes);
@ -125,10 +125,10 @@ public:
const ImageDescriptor& aDescriptor,
wr::Vec<uint8_t>& aBytes);
void UpdateBlobImage(wr::ImageKey aKey,
void UpdateBlobImage(wr::BlobImageKey aKey,
const ImageDescriptor& aDescriptor,
wr::Vec<uint8_t>& aBytes,
const wr::DeviceIntRect& aDirtyRect);
const wr::LayoutIntRect& aDirtyRect);
void UpdateExternalImage(ImageKey aKey,
const ImageDescriptor& aDescriptor,
@ -143,10 +143,12 @@ public:
const wr::DeviceIntRect& aDirtyRect,
uint8_t aChannelIndex = 0);
void SetImageVisibleArea(ImageKey aKey, const wr::DeviceIntRect& aArea);
void SetImageVisibleArea(BlobImageKey aKey, const wr::DeviceIntRect& aArea);
void DeleteImage(wr::ImageKey aKey);
void DeleteBlobImage(wr::BlobImageKey aKey);
void AddRawFont(wr::FontKey aKey, wr::Vec<uint8_t>& aBytes, uint32_t aIndex);
void AddFontDescriptor(wr::FontKey aKey, wr::Vec<uint8_t>& aBytes, uint32_t aIndex);

View File

@ -363,6 +363,17 @@ static inline wr::DeviceIntRect ToDeviceIntRect(const mozilla::ImageIntRect& rec
return r;
}
// TODO: should be const LayoutDeviceIntRect instead of ImageIntRect
static inline wr::LayoutIntRect ToLayoutIntRect(const mozilla::ImageIntRect& rect)
{
wr::LayoutIntRect r;
r.origin.x = rect.X();
r.origin.y = rect.Y();
r.size.width = rect.Width();
r.size.height = rect.Height();
return r;
}
static inline wr::LayoutRect ToLayoutRect(const mozilla::LayoutDeviceIntRect& rect)
{
return ToLayoutRect(IntRectToRect(rect));

View File

@ -1420,14 +1420,14 @@ pub extern "C" fn wr_resource_updates_add_image(
#[no_mangle]
pub extern "C" fn wr_resource_updates_add_blob_image(
txn: &mut Transaction,
image_key: WrImageKey,
image_key: BlobImageKey,
descriptor: &WrImageDescriptor,
bytes: &mut WrVecU8,
) {
txn.add_image(
txn.add_blob_image(
image_key,
descriptor.into(),
ImageData::new_blob_image(bytes.flush_into_vec()),
Arc::new(bytes.flush_into_vec()),
if descriptor.format == ImageFormat::BGRA8 { Some(256) } else { None }
);
}
@ -1466,17 +1466,17 @@ pub extern "C" fn wr_resource_updates_update_image(
key,
descriptor.into(),
ImageData::new(bytes.flush_into_vec()),
None
&DirtyRect::All,
);
}
#[no_mangle]
pub extern "C" fn wr_resource_updates_set_image_visible_area(
pub extern "C" fn wr_resource_updates_set_blob_image_visible_area(
txn: &mut Transaction,
key: WrImageKey,
key: BlobImageKey,
area: &DeviceIntRect,
) {
txn.set_image_visible_area(key, *area);
txn.set_blob_image_visible_area(key, *area);
}
#[no_mangle]
@ -1498,7 +1498,7 @@ pub extern "C" fn wr_resource_updates_update_external_image(
image_type: image_type.to_wr(),
}
),
None
&DirtyRect::All,
);
}
@ -1522,23 +1522,23 @@ pub extern "C" fn wr_resource_updates_update_external_image_with_dirty_rect(
image_type: image_type.to_wr(),
}
),
Some(dirty_rect)
&DirtyRect::Partial(dirty_rect)
);
}
#[no_mangle]
pub extern "C" fn wr_resource_updates_update_blob_image(
txn: &mut Transaction,
image_key: WrImageKey,
image_key: BlobImageKey,
descriptor: &WrImageDescriptor,
bytes: &mut WrVecU8,
dirty_rect: DeviceIntRect,
dirty_rect: LayoutIntRect,
) {
txn.update_image(
txn.update_blob_image(
image_key,
descriptor.into(),
ImageData::new_blob_image(bytes.flush_into_vec()),
Some(dirty_rect)
Arc::new(bytes.flush_into_vec()),
&DirtyRect::Partial(dirty_rect)
);
}
@ -1550,6 +1550,14 @@ pub extern "C" fn wr_resource_updates_delete_image(
txn.delete_image(key);
}
#[no_mangle]
pub extern "C" fn wr_resource_updates_delete_blob_image(
txn: &mut Transaction,
key: BlobImageKey
) {
txn.delete_blob_image(key);
}
#[no_mangle]
pub extern "C" fn wr_api_send_transaction(
dh: &mut DocumentHandle,
@ -2680,7 +2688,7 @@ extern "C" {
format: ImageFormat,
tile_size: Option<&u16>,
tile_offset: Option<&TileOffset>,
dirty_rect: Option<&DeviceIntRect>,
dirty_rect: Option<&LayoutIntRect>,
output: MutByteSlice)
-> bool;
}

View File

@ -19,6 +19,7 @@ use std::mem;
use std::os::raw::{c_void, c_char};
use std::ptr;
use std::sync::Arc;
use std::i32;
use std;
#[cfg(target_os = "windows")]
@ -68,7 +69,7 @@ fn dump_index(blob: &[u8]) -> () {
/// Handles the interpretation and rasterization of gecko-based (moz2d) WR blob images.
pub struct Moz2dBlobImageHandler {
workers: Arc<ThreadPool>,
blob_commands: HashMap<ImageKey, BlobCommand>,
blob_commands: HashMap<BlobImageKey, BlobCommand>,
}
/// Transmute some bytes into a value.
@ -271,12 +272,6 @@ impl Box2d {
}
}
impl From<DeviceIntRect> for Box2d {
fn from(rect: DeviceIntRect) -> Self {
Box2d{ x1: rect.min_x(), y1: rect.min_y(), x2: rect.max_x(), y2: rect.max_y() }
}
}
/// Provides an API for looking up the display items in a blob image by bounds, yielding items
/// with equal bounds in their original relative ordering.
///
@ -441,7 +436,7 @@ struct BlobCommand {
request: BlobImageRequest,
descriptor: BlobImageDescriptor,
commands: Arc<BlobImageData>,
dirty_rect: Option<DeviceIntRect>,
dirty_rect: BlobDirtyRect,
tile_size: Option<TileSize>,
}
@ -450,7 +445,7 @@ struct Moz2dBlobRasterizer {
/// Pool of rasterizers.
workers: Arc<ThreadPool>,
/// Blobs to rasterize.
blob_commands: HashMap<ImageKey, BlobCommand>,
blob_commands: HashMap<BlobImageKey, BlobCommand>,
}
struct GeckoProfilerMarker {
@ -514,30 +509,36 @@ impl AsyncBlobImageRasterizer for Moz2dBlobRasterizer {
fn rasterize_blob(job: Job) -> (BlobImageRequest, BlobImageResult) {
let descriptor = job.descriptor;
let buf_size = (descriptor.size.width
* descriptor.size.height
let buf_size = (descriptor.rect.size.width
* descriptor.rect.size.height
* descriptor.format.bytes_per_pixel()) as usize;
let mut output = vec![0u8; buf_size];
let dirty_rect = match job.dirty_rect {
DirtyRect::Partial(rect) => Some(rect),
DirtyRect::All => None,
};
let result = unsafe {
if wr_moz2d_render_cb(
ByteSlice::new(&job.commands[..]),
descriptor.size.width,
descriptor.size.height,
descriptor.rect.size.width,
descriptor.rect.size.height,
descriptor.format,
job.tile_size.as_ref(),
job.request.tile.as_ref(),
job.dirty_rect.as_ref(),
dirty_rect.as_ref(),
MutByteSlice::new(output.as_mut_slice()),
) {
// We want the dirty rect local to the tile rather than the whole image.
// TODO(nical): move that up and avoid recomupting the tile bounds in the callback
let dirty_rect = job.dirty_rect.to_subrect_of(&descriptor.rect);
let tx: BlobToDeviceTranslation = (-descriptor.rect.origin.to_vector()).into();
let rasterized_rect = tx.transform_rect(&dirty_rect);
Ok(RasterizedBlobImage {
rasterized_rect: job.dirty_rect.unwrap_or(
DeviceIntRect {
origin: DeviceIntPoint::origin(),
size: descriptor.size,
}
),
rasterized_rect,
data: Arc::new(output),
})
} else {
@ -549,7 +550,7 @@ fn rasterize_blob(job: Job) -> (BlobImageRequest, BlobImageResult) {
}
impl BlobImageHandler for Moz2dBlobImageHandler {
fn add(&mut self, key: ImageKey, data: Arc<BlobImageData>, tile_size: Option<TileSize>) {
fn add(&mut self, key: BlobImageKey, data: Arc<BlobImageData>, tile_size: Option<TileSize>) {
{
let index = BlobReader::new(&data);
assert!(index.reader.has_more());
@ -557,18 +558,32 @@ impl BlobImageHandler for Moz2dBlobImageHandler {
self.blob_commands.insert(key, BlobCommand { data: Arc::clone(&data), tile_size });
}
fn update(&mut self, key: ImageKey, data: Arc<BlobImageData>, dirty_rect: Option<DeviceIntRect>) {
fn update(&mut self, key: BlobImageKey, data: Arc<BlobImageData>, dirty_rect: &BlobDirtyRect) {
match self.blob_commands.entry(key) {
hash_map::Entry::Occupied(mut e) => {
let command = e.get_mut();
command.data = Arc::new(merge_blob_images(&command.data, &data,
dirty_rect.unwrap().into()));
let dirty_rect = if let DirtyRect::Partial(rect) = *dirty_rect {
Box2d {
x1: rect.min_x(),
y1: rect.min_y(),
x2: rect.max_x(),
y2: rect.max_y(),
}
} else {
Box2d {
x1: i32::MIN,
y1: i32::MIN,
x2: i32::MAX,
y2: i32::MAX,
}
};
command.data = Arc::new(merge_blob_images(&command.data, &data, dirty_rect));
}
_ => { panic!("missing image key"); }
}
}
fn delete(&mut self, key: ImageKey) {
fn delete(&mut self, key: BlobImageKey) {
self.blob_commands.remove(&key);
}

View File

@ -137,4 +137,15 @@ extern "C" {
void record_telemetry_time(mozilla::wr::TelemetryProbe aProbe, uint64_t aTimeNs);
}
namespace mozilla {
namespace wr {
// Cast a blob image key into a regular image for use in
// a display item.
inline ImageKey AsImageKey(BlobImageKey aKey) { return aKey._0; }
} // namespace wr
} // namespace mozilla
#endif // WR_h

View File

@ -997,7 +997,7 @@ struct ByteSlice {
using TileOffset = TypedPoint2D<int32_t, TileCoordinate>;
using DeviceIntRect = TypedRect<int32_t, DevicePixel>;
using LayoutIntRect = TypedRect<int32_t, LayoutPixel>;
struct MutByteSlice {
uint8_t *buffer;
@ -1073,6 +1073,17 @@ struct WrExternalImageHandler {
}
};
// An opaque identifier describing a blob image registered with WebRender.
// This is used as a handle to reference blob images, and can be used as an
// image in display items.
struct BlobImageKey {
ImageKey _0;
bool operator==(const BlobImageKey& aOther) const {
return _0 == aOther._0;
}
};
struct WrImageDescriptor {
ImageFormat format;
int32_t width;
@ -1089,6 +1100,8 @@ struct WrImageDescriptor {
}
};
using DeviceIntRect = TypedRect<int32_t, DevicePixel>;
struct WrTransformProperty {
uint64_t id;
LayoutTransform transform;
@ -1619,7 +1632,7 @@ extern bool wr_moz2d_render_cb(ByteSlice aBlob,
ImageFormat aFormat,
const uint16_t *aTileSize,
const TileOffset *aTileOffset,
const DeviceIntRect *aDirtyRect,
const LayoutIntRect *aDirtyRect,
MutByteSlice aOutput);
extern void wr_notifier_external_event(WrWindowId aWindowId,
@ -1695,7 +1708,7 @@ WR_FUNC;
WR_INLINE
void wr_resource_updates_add_blob_image(Transaction *aTxn,
WrImageKey aImageKey,
BlobImageKey aImageKey,
const WrImageDescriptor *aDescriptor,
WrVecU8 *aBytes)
WR_FUNC;
@ -1744,6 +1757,11 @@ WR_INLINE
void wr_resource_updates_clear(Transaction *aTxn)
WR_FUNC;
WR_INLINE
void wr_resource_updates_delete_blob_image(Transaction *aTxn,
BlobImageKey aKey)
WR_FUNC;
WR_INLINE
void wr_resource_updates_delete_font(Transaction *aTxn,
WrFontKey aKey)
@ -1760,17 +1778,17 @@ void wr_resource_updates_delete_image(Transaction *aTxn,
WR_FUNC;
WR_INLINE
void wr_resource_updates_set_image_visible_area(Transaction *aTxn,
WrImageKey aKey,
const DeviceIntRect *aArea)
void wr_resource_updates_set_blob_image_visible_area(Transaction *aTxn,
BlobImageKey aKey,
const DeviceIntRect *aArea)
WR_FUNC;
WR_INLINE
void wr_resource_updates_update_blob_image(Transaction *aTxn,
WrImageKey aImageKey,
BlobImageKey aImageKey,
const WrImageDescriptor *aDescriptor,
WrVecU8 *aBytes,
DeviceIntRect aDirtyRect)
LayoutIntRect aDirtyRect)
WR_FUNC;
WR_INLINE