tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

NativeLayerRemoteMac.mm (8893B)


      1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 * This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 #include "mozilla/layers/NativeLayerRemoteMac.h"
      7 
      8 #include <algorithm>
      9 #include <utility>
     10 
     11 #include "CFTypeRefPtr.h"
     12 #include "gfxUtils.h"
     13 #include "GLBlitHelper.h"
     14 #ifdef XP_MACOSX
     15 #  include "GLContextCGL.h"
     16 #else
     17 #  include "GLContextEAGL.h"
     18 #endif
     19 #include "GLContextProvider.h"
     20 #include "MozFramebuffer.h"
     21 #include "mozilla/gfx/Swizzle.h"
     22 #include "mozilla/glean/GfxMetrics.h"
     23 #include "mozilla/webrender/RenderMacIOSurfaceTextureHost.h"
     24 #include "NativeLayerCA.h"
     25 #include "ScopedGLHelpers.h"
     26 
     27 namespace mozilla {
     28 namespace layers {
     29 
     30 using gfx::IntPoint;
     31 using gfx::IntRect;
     32 using gfx::IntRegion;
     33 using gfx::IntSize;
     34 using gfx::Matrix4x4;
     35 
     36 NativeLayerRemoteMac::NativeLayerRemoteMac(
     37    const IntSize& aSize, bool aIsOpaque,
     38    SurfacePoolHandleCA* aSurfacePoolHandle)
     39    : mIsOpaque(aIsOpaque) {
     40  // We need a surface handler for this type of layer.
     41  mSurfaceHandler.emplace(aSize, aSurfacePoolHandle);
     42 }
     43 
     44 NativeLayerRemoteMac::NativeLayerRemoteMac(bool aIsOpaque)
     45    : mIsOpaque(aIsOpaque) {}
     46 
     47 NativeLayerRemoteMac::NativeLayerRemoteMac(gfx::DeviceColor aColor)
     48    : mColor(Some(aColor)), mIsOpaque(aColor.a >= 1.0f) {}
     49 
     50 NativeLayerRemoteMac::~NativeLayerRemoteMac() {
     51  if (mCommandQueue) {
     52    mCommandQueue->AppendCommand(mozilla::layers::CommandLayerDestroyed(
     53        reinterpret_cast<uint64_t>(this)));
     54  }
     55 }
     56 
     57 void NativeLayerRemoteMac::AttachExternalImage(
     58    wr::RenderTextureHost* aExternalImage) {
     59  MOZ_ASSERT(XRE_IsGPUProcess());
     60  MOZ_ASSERT(!mSurfaceHandler);
     61 
     62  wr::RenderMacIOSurfaceTextureHost* texture =
     63      aExternalImage->AsRenderMacIOSurfaceTextureHost();
     64  MOZ_ASSERT(texture);
     65 
     66  auto externalImage = texture->GetSurface()->GetIOSurfaceRef();
     67  mExternalImage = externalImage;
     68 
     69  auto texSize = texture->GetSize(0);
     70  mSize = texSize;
     71 
     72  auto displayRect = IntRect(IntPoint{}, mSize);
     73  bool changedDisplayRect = !mDisplayRect.IsEqualInterior(displayRect);
     74  mDisplayRect = displayRect;
     75 
     76  bool isDRM = aExternalImage->IsFromDRMSource();
     77  bool changedIsDRM = mIsDRM != isDRM;
     78  mIsDRM = isDRM;
     79 
     80  bool isHDR = false;
     81  MacIOSurface* macIOSurface = texture->GetSurface();
     82  if (macIOSurface->GetYUVColorSpace() == gfx::YUVColorSpace::BT2020 &&
     83      StaticPrefs::gfx_color_management_hdr_video_assume_rec2020_uses_pq()) {
     84    // BT2020 colorSpace is a signifier of HDR.
     85    isHDR = true;
     86  }
     87 
     88  if (macIOSurface->GetColorDepth() == gfx::ColorDepth::COLOR_10) {
     89    // 10-bit color is a signifier of HDR.
     90    isHDR = true;
     91  }
     92  mIsHDR = isHDR && StaticPrefs::gfx_color_management_hdr_video();
     93 
     94  mDirtyLayerInfo |= changedDisplayRect;
     95  mSnapshotLayer.mMutatedFrontSurface = true;
     96  mSnapshotLayer.mMutatedSize |= changedDisplayRect;
     97  mSnapshotLayer.mMutatedDisplayRect |= changedDisplayRect;
     98  mSnapshotLayer.mMutatedIsDRM |= changedIsDRM;
     99  mDirtyChangedSurface = true;
    100 }
    101 
    102 GpuFence* NativeLayerRemoteMac::GetGpuFence() { return nullptr; }
    103 
    104 IntSize NativeLayerRemoteMac::GetSize() {
    105  if (mSurfaceHandler) {
    106    return mSurfaceHandler->Size();
    107  }
    108  return mSize;
    109 }
    110 
    111 void NativeLayerRemoteMac::SetPosition(const IntPoint& aPosition) {
    112  if (mPosition != aPosition) {
    113    mDirtyLayerInfo = true;
    114    mSnapshotLayer.mMutatedPosition = true;
    115    mPosition = aPosition;
    116  }
    117 }
    118 
    119 IntPoint NativeLayerRemoteMac::GetPosition() { return mPosition; }
    120 
    121 void NativeLayerRemoteMac::SetTransform(const Matrix4x4& aTransform) {
    122  MOZ_ASSERT(aTransform.IsRectilinear());
    123 
    124  if (mTransform != aTransform) {
    125    mDirtyLayerInfo = true;
    126    mSnapshotLayer.mMutatedTransform = true;
    127    mTransform = aTransform;
    128  }
    129 }
    130 
    131 void NativeLayerRemoteMac::SetSamplingFilter(
    132    gfx::SamplingFilter aSamplingFilter) {
    133  if (mSamplingFilter != aSamplingFilter) {
    134    mDirtyLayerInfo = true;
    135    mSnapshotLayer.mMutatedSamplingFilter = true;
    136    mSamplingFilter = aSamplingFilter;
    137  }
    138 }
    139 
    140 gfx::SamplingFilter NativeLayerRemoteMac::SamplingFilter() {
    141  return mSamplingFilter;
    142 }
    143 
    144 Matrix4x4 NativeLayerRemoteMac::GetTransform() { return mTransform; }
    145 
    146 IntRect NativeLayerRemoteMac::GetRect() {
    147  IntSize size = mSize;
    148  if (mSurfaceHandler) {
    149    size = mSurfaceHandler->Size();
    150  }
    151  return IntRect(mPosition, size);
    152 }
    153 
    154 bool NativeLayerRemoteMac::IsOpaque() { return mIsOpaque; }
    155 
    156 void NativeLayerRemoteMac::SetClipRect(const Maybe<gfx::IntRect>& aClipRect) {
    157  if (mClipRect != aClipRect) {
    158    mDirtyLayerInfo = true;
    159    mClipRect = aClipRect;
    160  }
    161 }
    162 
    163 Maybe<gfx::IntRect> NativeLayerRemoteMac::ClipRect() { return mClipRect; }
    164 
    165 void NativeLayerRemoteMac::SetRoundedClipRect(
    166    const Maybe<gfx::RoundedRect>& aRoundedClipRect) {
    167  if (mRoundedClipRect != aRoundedClipRect) {
    168    mDirtyLayerInfo = true;
    169    mSnapshotLayer.mMutatedRoundedClipRect = true;
    170    mRoundedClipRect = aRoundedClipRect;
    171  }
    172 }
    173 
    174 Maybe<gfx::RoundedRect> NativeLayerRemoteMac::RoundedClipRect() {
    175  return mRoundedClipRect;
    176 }
    177 
    178 gfx::IntRect NativeLayerRemoteMac::CurrentSurfaceDisplayRect() {
    179  if (mSurfaceHandler) {
    180    return mSurfaceHandler->DisplayRect();
    181  }
    182  return mDisplayRect;
    183 }
    184 
    185 void NativeLayerRemoteMac::SetSurfaceIsFlipped(bool aIsFlipped) {
    186  if (SurfaceIsFlipped() != aIsFlipped) {
    187    mDirtyLayerInfo = true;
    188    mSnapshotLayer.mMutatedSurfaceIsFlipped = true;
    189    if (mSurfaceHandler) {
    190      mSurfaceHandler->SetSurfaceIsFlipped(aIsFlipped);
    191    } else {
    192      mSurfaceIsFlipped = aIsFlipped;
    193    }
    194  }
    195 }
    196 
    197 bool NativeLayerRemoteMac::SurfaceIsFlipped() {
    198  if (mSurfaceHandler) {
    199    return mSurfaceHandler->SurfaceIsFlipped();
    200  }
    201  return mSurfaceIsFlipped;
    202 }
    203 
    204 RefPtr<gfx::DrawTarget> NativeLayerRemoteMac::NextSurfaceAsDrawTarget(
    205    const IntRect& aDisplayRect, const IntRegion& aUpdateRegion,
    206    gfx::BackendType aBackendType) {
    207  MOZ_ASSERT(mSurfaceHandler);
    208  return mSurfaceHandler->NextSurfaceAsDrawTarget(aDisplayRect, aUpdateRegion,
    209                                                  aBackendType);
    210 }
    211 
    212 Maybe<GLuint> NativeLayerRemoteMac::NextSurfaceAsFramebuffer(
    213    const IntRect& aDisplayRect, const IntRegion& aUpdateRegion,
    214    bool aNeedsDepth) {
    215  MOZ_ASSERT(mSurfaceHandler);
    216  return mSurfaceHandler->NextSurfaceAsFramebuffer(aDisplayRect, aUpdateRegion,
    217                                                   aNeedsDepth);
    218 }
    219 
    220 Maybe<SurfaceWithInvalidRegion> NativeLayerRemoteMac::FrontSurface() {
    221  if (mSurfaceHandler) {
    222    return mSurfaceHandler->FrontSurface();
    223  }
    224  if (mExternalImage) {
    225    return Some(SurfaceWithInvalidRegion{mExternalImage, GetRect()});
    226  }
    227  return Nothing();
    228 }
    229 
    230 void NativeLayerRemoteMac::NotifySurfaceReady() {
    231  MOZ_ASSERT(mSurfaceHandler);
    232 
    233  // When we call the surface handler NotifySurfaceReady(), we get a
    234  // return value indicating if the display rect has changed. Set our
    235  // dirty flag (covering all non-surface changes) if that is true.
    236  bool changedDisplayRect = mSurfaceHandler->NotifySurfaceReady();
    237  mDirtyLayerInfo |= changedDisplayRect;
    238  mDirtyChangedSurface = true;
    239  mSnapshotLayer.mMutatedFrontSurface = true;
    240 }
    241 
    242 void NativeLayerRemoteMac::DiscardBackbuffers() {
    243  MOZ_ASSERT(mSurfaceHandler);
    244  mSurfaceHandler->DiscardBackbuffers();
    245 }
    246 
    247 void NativeLayerRemoteMac::FlushDirtyLayerInfoToCommandQueue() {
    248  auto ID = reinterpret_cast<uint64_t>(this);
    249 
    250  if (mDirtyChangedSurface) {
    251    IOSurfacePort surfacePort;
    252    auto surfaceWithInvalidRegion = FrontSurface();
    253    if (surfaceWithInvalidRegion) {
    254      surfacePort =
    255          IOSurfacePort::FromSurface(surfaceWithInvalidRegion->mSurface);
    256    }
    257 
    258    mCommandQueue->AppendCommand(mozilla::layers::CommandChangedSurface(
    259        ID, std::move(surfacePort), IsDRM(), IsHDR(), GetSize()));
    260    mDirtyChangedSurface = false;
    261  }
    262 
    263  if (mDirtyLayerInfo) {
    264    mCommandQueue->AppendCommand(mozilla::layers::CommandLayerInfo(
    265        ID, GetPosition(), CurrentSurfaceDisplayRect(), ClipRect(),
    266        RoundedClipRect(), GetTransform(),
    267        static_cast<int8_t>(SamplingFilter()), SurfaceIsFlipped()));
    268    mDirtyLayerInfo = false;
    269  }
    270 }
    271 
    272 void NativeLayerRemoteMac::UpdateSnapshotLayer() {
    273  CFTypeRefPtr<IOSurfaceRef> surface;
    274  if (auto frontSurface = FrontSurface()) {
    275    surface = frontSurface->mSurface;
    276  }
    277 
    278  IntRect rect = GetRect();
    279  IntRect displayRect = CurrentSurfaceDisplayRect();
    280 
    281  bool specializeVideo = false;
    282  bool isVideo = false;
    283  mSnapshotLayer.ApplyChanges(
    284      NativeLayerCAUpdateType::All, rect.Size(), mIsOpaque, rect.TopLeft(),
    285      mTransform, displayRect, mClipRect, mRoundedClipRect, mBackingScale,
    286      mSurfaceIsFlipped, mSamplingFilter, specializeVideo, surface, mColor,
    287      mIsDRM, isVideo);
    288 }
    289 
    290 CALayer* NativeLayerRemoteMac::CALayerForSnapshot() {
    291  return mSnapshotLayer.UnderlyingCALayer();
    292 }
    293 
    294 }  // namespace layers
    295 }  // namespace mozilla