author | JerryShih <hshih@mozilla.com> |
Fri, 19 May 2017 00:25:42 +0800 | |
changeset 359349 | f5be98afef66e3b83e3e369822b44077cda34afa |
parent 359348 | 6a240376afe79df182fdd7a302f2c1c6eddea6e1 |
child 359350 | 9157ff3fa189f74ca96df6661570bdd879b1f979 |
push id | 31852 |
push user | kwierso@gmail.com |
push date | Fri, 19 May 2017 21:47:27 +0000 |
treeherder | mozilla-central@979f11deabd0 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | nical |
bugs | 1364922 |
milestone | 55.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/gfx/layers/wr/WebRenderBridgeParent.cpp +++ b/gfx/layers/wr/WebRenderBridgeParent.cpp @@ -438,51 +438,96 @@ WebRenderBridgeParent::ProcessWebRenderC { mCompositableHolder->SetCompositionTime(TimeStamp::Now()); for (InfallibleTArray<WebRenderParentCommand>::index_type i = 0; i < aCommands.Length(); ++i) { const WebRenderParentCommand& cmd = aCommands[i]; switch (cmd.type()) { case WebRenderParentCommand::TOpAddExternalImage: { const OpAddExternalImage& op = cmd.get_OpAddExternalImage(); - wr::ImageKey key = op.key(); + Range<const wr::ImageKey> keys(&op.key(), 1); MOZ_ASSERT(mExternalImageIds.Get(wr::AsUint64(op.externalImageId())).get()); - MOZ_ASSERT(!mActiveKeys.Get(wr::AsUint64(key), nullptr)); - mActiveKeys.Put(wr::AsUint64(key), key); + MOZ_ASSERT(!mActiveKeys.Get(wr::AsUint64(keys[0]), nullptr)); + mActiveKeys.Put(wr::AsUint64(keys[0]), keys[0]); RefPtr<WebRenderImageHost> host = mExternalImageIds.Get(wr::AsUint64(op.externalImageId())); if (!host) { NS_ERROR("CompositableHost does not exist"); break; } // XXX select Texture for video in CompositeToTarget(). TextureHost* texture = host->GetAsTextureHostForComposite(); if (!texture) { NS_ERROR("TextureHost does not exist"); break; } WebRenderTextureHost* wrTexture = texture->AsWebRenderTextureHost(); if (wrTexture) { - wrTexture->AddWRImage(mApi, key, wrTexture->GetExternalImageKey()); + wrTexture->AddWRImage(mApi, keys, wrTexture->GetExternalImageKey()); break; } RefPtr<DataSourceSurface> dSurf = host->GetAsSurface(); if (!dSurf) { break; } DataSourceSurface::MappedSurface map; if (!dSurf->Map(gfx::DataSourceSurface::MapType::READ, &map)) { break; } IntSize size = dSurf->GetSize(); wr::ImageDescriptor descriptor(size, map.mStride, dSurf->GetFormat()); auto slice = Range<uint8_t>(map.mData, size.height * map.mStride); - mApi->AddImage(key, descriptor, slice); + mApi->AddImage(keys[0], descriptor, slice); + + dSurf->Unmap(); + break; + } + case WebRenderParentCommand::TOpAddExternalVideoImage: { + const OpAddExternalVideoImage& op = cmd.get_OpAddExternalVideoImage(); + MOZ_ASSERT(mExternalImageIds.Get(wr::AsUint64(op.externalImageId())).get()); + MOZ_ASSERT(op.keys().Length() > 0); + Range<const wr::ImageKey> keys(&(op.keys())[0], op.keys().Length()); + for (auto key : keys) { + MOZ_ASSERT(!mActiveKeys.Get(wr::AsUint64(key), nullptr)); + mActiveKeys.Put(wr::AsUint64(key), key); + } + + RefPtr<WebRenderImageHost> host = mExternalImageIds.Get(wr::AsUint64(op.externalImageId())); + if (!host) { + NS_ERROR("CompositableHost does not exist"); + break; + } + // XXX select Texture for video in CompositeToTarget(). + TextureHost* texture = host->GetAsTextureHostForComposite(); + if (!texture) { + NS_ERROR("TextureHost does not exist"); + break; + } + WebRenderTextureHost* wrTexture = texture->AsWebRenderTextureHost(); + if (wrTexture) { + wrTexture->AddWRImage(mApi, keys, wrTexture->GetExternalImageKey()); + break; + } + + MOZ_ASSERT(keys.length() == 1); + RefPtr<DataSourceSurface> dSurf = host->GetAsSurface(); + if (!dSurf) { + break; + } + DataSourceSurface::MappedSurface map; + if (!dSurf->Map(gfx::DataSourceSurface::MapType::READ, &map)) { + break; + } + + IntSize size = dSurf->GetSize(); + wr::ImageDescriptor descriptor(size, map.mStride, dSurf->GetFormat()); + auto slice = Range<uint8_t>(map.mData, size.height * map.mStride); + mApi->AddImage(keys[0], descriptor, slice); dSurf->Unmap(); break; } case WebRenderParentCommand::TCompositableOperation: { if (!ReceiveCompositableUpdate(cmd.get_CompositableOperation())) { NS_ERROR("ReceiveCompositableUpdate failed"); }
--- a/gfx/layers/wr/WebRenderImageLayer.cpp +++ b/gfx/layers/wr/WebRenderImageLayer.cpp @@ -27,19 +27,24 @@ WebRenderImageLayer::WebRenderImageLayer { MOZ_COUNT_CTOR(WebRenderImageLayer); } WebRenderImageLayer::~WebRenderImageLayer() { MOZ_COUNT_DTOR(WebRenderImageLayer); mPipelineIdRequest.DisconnectIfExists(); + + for (auto key : mVideoKeys) { + WrManager()->AddImageKeyForDiscard(key); + } if (mKey.isSome()) { WrManager()->AddImageKeyForDiscard(mKey.value()); } + if (mExternalImageId.isSome()) { WrBridge()->DeallocExternalImageId(mExternalImageId.ref()); } } CompositableType WebRenderImageLayer::GetImageClientType() { @@ -81,16 +86,27 @@ void WebRenderImageLayer::ClearCachedResources() { if (mImageClient) { mImageClient->ClearCachedResources(); } } void +WebRenderImageLayer::AddWRVideoImage(size_t aChannelNumber) +{ + for (size_t i = 0; i < aChannelNumber; ++i) { + WrImageKey key = GetImageKey(); + WrManager()->AddImageKeyForDiscard(key); + mVideoKeys.AppendElement(key); + } + WrBridge()->AddWebRenderParentCommand(OpAddExternalVideoImage(mExternalImageId.value(), mVideoKeys)); +} + +void WebRenderImageLayer::RenderLayer(wr::DisplayListBuilder& aBuilder, const StackingContextHelper& aSc) { if (!mContainer) { return; } CompositableType type = GetImageClientType(); @@ -143,33 +159,50 @@ WebRenderImageLayer::RenderLayer(wr::Dis // XXX Not good for async ImageContainer case. AutoLockImage autoLock(mContainer); Image* image = autoLock.GetImage(); if (!image) { return; } gfx::IntSize size = image->GetSize(); - if (GetImageClientType() == CompositableType::IMAGE_BRIDGE) { - // Always allocate key - WrImageKey key = GetImageKey(); - WrBridge()->AddWebRenderParentCommand(OpAddExternalImage(mExternalImageId.value(), key)); - WrManager()->AddImageKeyForDiscard(key); - mKey = Some(key); - } else { + if (GetImageClientType() != CompositableType::IMAGE_BRIDGE) { // Handle CompositableType::IMAGE case MOZ_ASSERT(mImageClient->AsImageClientSingle()); mKey = UpdateImageKey(mImageClient->AsImageClientSingle(), mContainer, mKey, mExternalImageId.ref()); - } + if (mKey.isNothing()) { + return; + } + } else { + // Always allocate key. + mVideoKeys.Clear(); - if (mKey.isNothing()) { - return; + // XXX (Jerry): Remove the hardcode image format setting. +#if defined(XP_WIN) + // Use libyuv to convert the buffer to rgba format. So, use 1 image key here. + AddWRVideoImage(1); +#elif defined(XP_MACOSX) + if (gfx::gfxVars::CanUseHardwareVideoDecoding()) { + // Use the hardware MacIOSurface with YCbCr interleaved format. It uses 1 + // image key. + AddWRVideoImage(1); + } else { + // Use libyuv. + AddWRVideoImage(1); + } +#elif defined(MOZ_WIDGET_GTK) + // Use libyuv. + AddWRVideoImage(1); +#elif defined(ANDROID) + // Use libyuv. + AddWRVideoImage(1); +#endif } ScrollingLayersHelper scroller(this, aBuilder, aSc); StackingContextHelper sc(aSc, aBuilder, this); LayerRect rect(0, 0, size.width, size.height); if (mScaleMode != ScaleMode::SCALE_NONE) { NS_ASSERTION(mScaleMode == ScaleMode::STRETCH, @@ -195,31 +228,36 @@ WebRenderImageLayer::RenderLayer(wr::Dis if (GetImageClientType() != CompositableType::IMAGE_BRIDGE) { aBuilder.PushImage(sc.ToRelativeWrRect(rect), clip, filter, mKey.value()); } else { // XXX (Jerry): Remove the hardcode image format setting. The format of // textureClient could change from time to time. So, we just set the most // usable format here. #if defined(XP_WIN) // Use libyuv to convert the buffer to rgba format. - aBuilder.PushImage(sc.ToRelativeWrRect(rect), clip, filter, mKey.value()); + MOZ_ASSERT(mVideoKeys.Length() == 1); + aBuilder.PushImage(sc.ToRelativeWrRect(rect), clip, filter, mVideoKeys[0]); #elif defined(XP_MACOSX) if (gfx::gfxVars::CanUseHardwareVideoDecoding()) { // Use the hardware MacIOSurface with YCbCr interleaved format. - aBuilder.PushYCbCrInterleavedImage(sc.ToRelativeWrRect(rect), clip, mKey.value(), WrYuvColorSpace::Rec601); + MOZ_ASSERT(mVideoKeys.Length() == 1); + aBuilder.PushYCbCrInterleavedImage(sc.ToRelativeWrRect(rect), clip, mVideoKeys[0], WrYuvColorSpace::Rec601); } else { // Use libyuv to convert the buffer to rgba format. - aBuilder.PushImage(sc.ToRelativeWrRect(rect), clip, filter, mKey.value()); + MOZ_ASSERT(mVideoKeys.Length() == 1); + aBuilder.PushImage(sc.ToRelativeWrRect(rect), clip, filter, mVideoKeys[0]); } #elif defined(MOZ_WIDGET_GTK) // Use libyuv to convert the buffer to rgba format. - aBuilder.PushImage(sc.ToRelativeWrRect(rect), clip, filter, mKey.value()); + MOZ_ASSERT(mVideoKeys.Length() == 1); + aBuilder.PushImage(sc.ToRelativeWrRect(rect), clip, filter, mVideoKeys[0]); #elif defined(ANDROID) // Use libyuv to convert the buffer to rgba format. - aBuilder.PushImage(sc.ToRelativeWrRect(rect), clip, filter, mKey.value()); + MOZ_ASSERT(mVideoKeys.Length() == 1); + aBuilder.PushImage(sc.ToRelativeWrRect(rect), clip, filter, mVideoKeys[0]); #endif } } Maybe<WrImageMask> WebRenderImageLayer::RenderMaskLayer(const gfx::Matrix4x4& aTransform) { if (!mContainer) {
--- a/gfx/layers/wr/WebRenderImageLayer.h +++ b/gfx/layers/wr/WebRenderImageLayer.h @@ -31,27 +31,32 @@ public: Layer* GetLayer() override { return this; } void RenderLayer(wr::DisplayListBuilder& aBuilder, const StackingContextHelper& aSc) override; Maybe<WrImageMask> RenderMaskLayer(const gfx::Matrix4x4& aTransform) override; protected: CompositableType GetImageClientType(); + 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; + // The regular single channel image. Maybe<wr::ImageKey> mKey; RefPtr<ImageClient> mImageClient; CompositableType mImageClientTypeContainer; Maybe<wr::PipelineId> mPipelineId; MozPromiseRequestHolder<PipelineIdPromise> mPipelineIdRequest; }; } // namespace layers