Bug 1376855 - Support nsDisplayVideo in layers free mode. r=kats,sotaro

MozReview-Commit-ID: HyelfkHokrw

--HG--
extra : rebase_source : 02cccf4b0029d98c453a4a59a2d1416548976af7
This commit is contained in:
Morris Tseng 2017-06-28 15:12:25 -07:00
Родитель 506acb1953
Коммит 3ebdf834e1
1 изменённых файлов: 59 добавлений и 0 удалений

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

@ -12,6 +12,7 @@
#include "nsGkAtoms.h"
#include "mozilla/dom/HTMLVideoElement.h"
#include "mozilla/layers/WebRenderLayerManager.h"
#include "nsIDOMHTMLImageElement.h"
#include "nsDisplayList.h"
#include "nsGenericHTMLElement.h"
@ -432,6 +433,64 @@ public:
NS_DISPLAY_DECL_NAME("Video", TYPE_VIDEO)
virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
const mozilla::layers::StackingContextHelper& aSc,
nsTArray<mozilla::layers::WebRenderParentCommand>& aParentCommands,
mozilla::layers::WebRenderLayerManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder) override
{
nsRect area = Frame()->GetContentRectRelativeToSelf() + ToReferenceFrame();
HTMLVideoElement* element = static_cast<HTMLVideoElement*>(Frame()->GetContent());
nsIntSize videoSizeInPx;
if (NS_FAILED(element->GetVideoSize(&videoSizeInPx)) || area.IsEmpty()) {
return false;
}
RefPtr<ImageContainer> container = element->GetImageContainer();
if (!container) {
return false;
}
// Retrieve the size of the decoded video frame, before being scaled
// by pixel aspect ratio.
mozilla::gfx::IntSize frameSize = container->GetCurrentSize();
if (frameSize.width == 0 || frameSize.height == 0) {
// No image, or zero-sized image. Don't render.
return true;
}
// Convert video size from pixel units into app units, to get an aspect-ratio
// (which has to be represented as a nsSize) and an IntrinsicSize that we
// can pass to ComputeObjectRenderRect.
nsSize aspectRatio(nsPresContext::CSSPixelsToAppUnits(videoSizeInPx.width),
nsPresContext::CSSPixelsToAppUnits(videoSizeInPx.height));
IntrinsicSize intrinsicSize;
intrinsicSize.width.SetCoordValue(aspectRatio.width);
intrinsicSize.height.SetCoordValue(aspectRatio.height);
nsRect dest = nsLayoutUtils::ComputeObjectDestRect(area,
intrinsicSize,
aspectRatio,
Frame()->StylePosition());
gfxRect destGFXRect = Frame()->PresContext()->AppUnitsToGfxUnits(dest);
destGFXRect.Round();
if (destGFXRect.IsEmpty()) {
return false;
}
VideoInfo::Rotation rotationDeg = element->RotationDegrees();
IntSize scaleHint(static_cast<int32_t>(destGFXRect.Width()),
static_cast<int32_t>(destGFXRect.Height()));
// scaleHint is set regardless of rotation, so swap w/h if needed.
SwapScaleWidthHeightForRotation(scaleHint, rotationDeg);
container->SetScaleHint(scaleHint);
LayerRect rect(destGFXRect.x, destGFXRect.y, destGFXRect.width, destGFXRect.height);
return aManager->PushImage(this, container, aBuilder, aSc, rect);
}
// It would be great if we could override GetOpaqueRegion to return nonempty here,
// but it's probably not safe to do so in general. Video frames are
// updated asynchronously from decoder threads, and it's possible that