зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
506acb1953
Коммит
3ebdf834e1
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче