This patch corrects a few different issues related to recycling MacIOSurface objects. 1) When recycling a surface, we must check that the cached surfaces match all of the requested parameters, not just the size. If we do not, we should just flush the whole cache immediately since they should all be created with the same parameters. 2) Allocations can fail, and we should check for failing to get a surface from the allocator and fall back if so. 3) Locking can fail, and we should check that return value at all of the call sites. This may help resolve a number of otherwise difficult to understand crash signatures. It may also solve display corruption issues in rare cases where the parameters that changed were roughly equivalent such that everything appears to work, but they differ enough to change the presentation. Differential Revision: https://phabricator.services.mozilla.com/D222205
89 lines
2.9 KiB
C++
89 lines
2.9 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#ifndef GFX_MACIOSURFACEIMAGE_H
|
|
#define GFX_MACIOSURFACEIMAGE_H
|
|
|
|
#include "ImageContainer.h"
|
|
#include "mozilla/gfx/MacIOSurface.h"
|
|
#include "mozilla/gfx/Point.h"
|
|
#include "mozilla/layers/TextureClient.h"
|
|
|
|
namespace mozilla {
|
|
|
|
namespace layers {
|
|
|
|
class MacIOSurfaceImage : public Image {
|
|
public:
|
|
explicit MacIOSurfaceImage(MacIOSurface* aSurface)
|
|
: Image(nullptr, ImageFormat::MAC_IOSURFACE), mSurface(aSurface) {
|
|
if (aSurface) {
|
|
mPictureRect = gfx::IntRect(
|
|
gfx::IntPoint{}, gfx::IntSize(aSurface->GetDevicePixelWidth(0),
|
|
aSurface->GetDevicePixelHeight(0)));
|
|
}
|
|
}
|
|
|
|
bool SetData(ImageContainer* aContainer, const PlanarYCbCrData& aData);
|
|
|
|
MacIOSurface* GetSurface() { return mSurface; }
|
|
|
|
gfx::IntSize GetSize() const override {
|
|
return gfx::IntSize::Truncate(mSurface->GetDevicePixelWidth(),
|
|
mSurface->GetDevicePixelHeight());
|
|
}
|
|
|
|
already_AddRefed<gfx::SourceSurface> GetAsSourceSurface() override;
|
|
|
|
nsresult BuildSurfaceDescriptorBuffer(
|
|
SurfaceDescriptorBuffer& aSdBuffer, BuildSdbFlags aFlags,
|
|
const std::function<MemoryOrShmem(uint32_t)>& aAllocate) override;
|
|
|
|
TextureClient* GetTextureClient(KnowsCompositor* aKnowsCompositor) override;
|
|
|
|
MacIOSurfaceImage* AsMacIOSurfaceImage() override { return this; }
|
|
|
|
gfx::IntRect GetPictureRect() const override { return mPictureRect; }
|
|
|
|
gfx::ColorDepth GetColorDepth() const override;
|
|
|
|
private:
|
|
RefPtr<MacIOSurface> mSurface;
|
|
RefPtr<TextureClient> mTextureClient;
|
|
gfx::IntRect mPictureRect;
|
|
};
|
|
|
|
class MacIOSurfaceRecycleAllocator {
|
|
public:
|
|
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MacIOSurfaceRecycleAllocator)
|
|
|
|
already_AddRefed<MacIOSurface> Allocate(
|
|
const gfx::IntSize aYSize, const gfx::IntSize& aCbCrSize,
|
|
gfx::ChromaSubsampling aChromaSubsampling,
|
|
gfx::YUVColorSpace aYUVColorSpace,
|
|
gfx::TransferFunction aTransferFunction, gfx::ColorRange aColorRange,
|
|
gfx::ColorDepth aColorDepth);
|
|
|
|
private:
|
|
~MacIOSurfaceRecycleAllocator() = default;
|
|
|
|
nsTArray<CFTypeRefPtr<IOSurfaceRef>> mSurfaces;
|
|
|
|
// Cached parameters used for allocations stored in mSurfaces.
|
|
gfx::IntSize mYSize;
|
|
gfx::IntSize mCbCrSize;
|
|
gfx::ChromaSubsampling mChromaSubsampling = gfx::ChromaSubsampling::FULL;
|
|
gfx::YUVColorSpace mYUVColorSpace = gfx::YUVColorSpace::BT709;
|
|
gfx::TransferFunction mTransferFunction = gfx::TransferFunction::BT709;
|
|
gfx::ColorRange mColorRange = gfx::ColorRange::FULL;
|
|
gfx::ColorDepth mColorDepth = gfx::ColorDepth::COLOR_8;
|
|
};
|
|
|
|
} // namespace layers
|
|
} // namespace mozilla
|
|
|
|
#endif // GFX_SHAREDTEXTUREIMAGE_H
|