зеркало из https://github.com/mozilla/gecko-dev.git
Bug 987311 - 3/6 - Make TextureFlags a typed enum, final manual changes - r=nical
This commit is contained in:
Родитель
45875b18ee
Коммит
49dd7d0c3f
|
@ -75,7 +75,7 @@ SharedSurface_Gralloc::Create(GLContext* prodGL,
|
|||
allocator,
|
||||
gfx::ImageFormatToSurfaceFormat(format),
|
||||
gfx::BackendType::NONE, // we don't need to use it with a DrawTarget
|
||||
TEXTURE_FLAGS_DEFAULT);
|
||||
layers::TextureFlags::DEFAULT);
|
||||
|
||||
if (!grallocTC->AllocateForGLRendering(size)) {
|
||||
return nullptr;
|
||||
|
|
|
@ -323,6 +323,13 @@ struct ParamTraits<mozilla::gfx::ColorSpace>
|
|||
mozilla::gfx::ColorSpace::Max>
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct ParamTraits<mozilla::layers::TextureFlags>
|
||||
: public BitFlagsTypedEnumSerializer<
|
||||
mozilla::layers::TextureFlags,
|
||||
mozilla::layers::TextureFlags::ALL_BITS>
|
||||
{};
|
||||
|
||||
/*
|
||||
template <>
|
||||
struct ParamTraits<mozilla::PixelFormat>
|
||||
|
|
|
@ -205,7 +205,7 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual TemporaryRef<DataTextureSource> CreateDataTextureSource(TextureFlags aFlags = 0) = 0;
|
||||
virtual TemporaryRef<DataTextureSource> CreateDataTextureSource(TextureFlags aFlags = TextureFlags::NO_FLAGS) = 0;
|
||||
virtual bool Initialize() = 0;
|
||||
virtual void Destroy() = 0;
|
||||
|
||||
|
|
|
@ -28,7 +28,8 @@ const SurfaceDescriptorType SURFACEDESCRIPTOR_UNKNOWN = 0;
|
|||
*
|
||||
* XXX - switch to all caps constant names which seems to be the standard in gecko
|
||||
*/
|
||||
MOZ_BEGIN_ENUM_CLASS(TextureFlags)
|
||||
MOZ_BEGIN_ENUM_CLASS(TextureFlags, uint32_t)
|
||||
NO_FLAGS = 0,
|
||||
// Use nearest-neighbour texture filtering (as opposed to linear filtering).
|
||||
USE_NEAREST_FILTER = 1 << 0,
|
||||
// The texture should be flipped around the y-axis when composited.
|
||||
|
@ -51,39 +52,41 @@ MOZ_BEGIN_ENUM_CLASS(TextureFlags)
|
|||
// (for example, with GL), a BGRA shader should be used.
|
||||
RB_SWAPPED = 1 << 6,
|
||||
|
||||
FRONT = 1 << 12,
|
||||
FRONT = 1 << 7,
|
||||
// A texture host on white for component alpha
|
||||
ON_WHITE = 1 << 13,
|
||||
ON_WHITE = 1 << 8,
|
||||
// A texture host on black for component alpha
|
||||
ON_BLACK = 1 << 14,
|
||||
ON_BLACK = 1 << 9,
|
||||
// A texture host that supports tiling
|
||||
TILE = 1 << 15,
|
||||
TILE = 1 << 10,
|
||||
// A texture should be recycled when no longer in used
|
||||
RECYCLE = 1 << 16,
|
||||
RECYCLE = 1 << 11,
|
||||
// Texture contents should be initialized
|
||||
// from the previous texture.
|
||||
COPY_PREVIOUS = 1 << 24,
|
||||
COPY_PREVIOUS = 1 << 12,
|
||||
// Who is responsible for deallocating the shared data.
|
||||
// if DEALLOCATE_CLIENT is set, the shared data is deallocated on the
|
||||
// client side and requires some extra synchronizaion to ensure race-free
|
||||
// deallocation.
|
||||
// The default behaviour is to deallocate on the host side.
|
||||
DEALLOCATE_CLIENT = 1 << 25,
|
||||
DEALLOCATE_CLIENT = 1 << 13,
|
||||
// After being shared ith the compositor side, an immutable texture is never
|
||||
// modified, it can only be read. It is safe to not Lock/Unlock immutable
|
||||
// textures.
|
||||
IMMUTABLE = 1 << 27,
|
||||
IMMUTABLE = 1 << 14,
|
||||
// The contents of the texture must be uploaded or copied immediately
|
||||
// during the transaction, because the producer may want to write
|
||||
// to it again.
|
||||
IMMEDIATE_UPLOAD = 1 << 28,
|
||||
IMMEDIATE_UPLOAD = 1 << 15,
|
||||
// The texture is going to be used as part of a double
|
||||
// buffered pair, and so we can guarantee that the producer/consumer
|
||||
// won't be racing to access its contents.
|
||||
DOUBLE_BUFFERED = 1 << 29,
|
||||
DOUBLE_BUFFERED = 1 << 16,
|
||||
// We've previously tried a texture and it didn't work for some reason. If there
|
||||
// is a fallback available, try that.
|
||||
ALLOC_FALLBACK = 1 << 31,
|
||||
ALLOC_FALLBACK = 1 << 17,
|
||||
// OR union of all valid bits
|
||||
ALL_BITS = (1 << 18) - 1,
|
||||
// the default flags
|
||||
DEFAULT = FRONT
|
||||
MOZ_END_ENUM_CLASS(TextureFlags)
|
||||
|
@ -229,13 +232,13 @@ struct TextureInfo
|
|||
TextureInfo()
|
||||
: mCompositableType(BUFFER_UNKNOWN)
|
||||
, mDeprecatedTextureHostFlags(0)
|
||||
, mTextureFlags(0)
|
||||
, mTextureFlags(TextureFlags::NO_FLAGS)
|
||||
{}
|
||||
|
||||
TextureInfo(CompositableType aType)
|
||||
: mCompositableType(aType)
|
||||
, mDeprecatedTextureHostFlags(0)
|
||||
, mTextureFlags(0)
|
||||
, mTextureFlags(TextureFlags::NO_FLAGS)
|
||||
{}
|
||||
|
||||
bool operator==(const TextureInfo& aOther) const
|
||||
|
|
|
@ -180,13 +180,13 @@ AppendToString(nsACString& s, TextureFlags flags,
|
|||
const char* pfx, const char* sfx)
|
||||
{
|
||||
s += pfx;
|
||||
if (!flags) {
|
||||
if (flags == TextureFlags::NO_FLAGS) {
|
||||
s += "NoFlags";
|
||||
} else {
|
||||
|
||||
#define AppendFlag(test) \
|
||||
{ \
|
||||
if (flags & test) { \
|
||||
if (!!(flags & test)) { \
|
||||
if (previous) { \
|
||||
s += "|"; \
|
||||
} \
|
||||
|
|
|
@ -65,7 +65,7 @@ public:
|
|||
const gfx::IntPoint &aSourcePoint) MOZ_OVERRIDE;
|
||||
|
||||
virtual TemporaryRef<DataTextureSource>
|
||||
CreateDataTextureSource(TextureFlags aFlags = 0) MOZ_OVERRIDE;
|
||||
CreateDataTextureSource(TextureFlags aFlags = TextureFlags::NO_FLAGS) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool SupportsEffect(EffectTypes aEffect) MOZ_OVERRIDE;
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ CanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
|
|||
: gfxContentType::COLOR_ALPHA;
|
||||
gfxImageFormat format
|
||||
= gfxPlatform::GetPlatform()->OptimalFormatForContent(contentType);
|
||||
uint32_t flags = TextureFlags::DEFAULT;
|
||||
TextureFlags flags = TextureFlags::DEFAULT;
|
||||
if (mTextureFlags & TextureFlags::NEEDS_Y_FLIP) {
|
||||
flags |= TextureFlags::NEEDS_Y_FLIP;
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ protected:
|
|||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositableClient)
|
||||
|
||||
CompositableClient(CompositableForwarder* aForwarder, TextureFlags aFlags = 0);
|
||||
CompositableClient(CompositableForwarder* aForwarder, TextureFlags aFlags = TextureFlags::NO_FLAGS);
|
||||
|
||||
virtual TextureInfo GetTextureInfo() const = 0;
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace layers {
|
|||
|
||||
static TextureFlags TextureFlagsForRotatedContentBufferFlags(uint32_t aBufferFlags)
|
||||
{
|
||||
TextureFlags result = 0;
|
||||
TextureFlags result = TextureFlags::NO_FLAGS;
|
||||
|
||||
if (aBufferFlags & RotatedContentBuffer::BUFFER_COMPONENT_ALPHA) {
|
||||
result |= TextureFlags::COMPONENT_ALPHA;
|
||||
|
@ -53,7 +53,6 @@ static TextureFlags TextureFlagsForRotatedContentBufferFlags(uint32_t aBufferFla
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* static */ TemporaryRef<ContentClient>
|
||||
ContentClient::CreateContentClient(CompositableForwarder* aForwarder)
|
||||
{
|
||||
|
@ -572,6 +571,18 @@ FillSurface(DrawTarget* aDT, const nsIntRegion& aRegion,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
ContentClientIncremental::NotifyBufferCreated(ContentType aType, TextureFlags aFlags)
|
||||
{
|
||||
mTextureInfo.mTextureFlags = aFlags;
|
||||
mContentType = aType;
|
||||
|
||||
mForwarder->CreatedIncrementalBuffer(this,
|
||||
mTextureInfo,
|
||||
mBufferRect);
|
||||
|
||||
}
|
||||
|
||||
RotatedContentBuffer::PaintState
|
||||
ContentClientIncremental::BeginPaintBuffer(ThebesLayer* aLayer,
|
||||
uint32_t aFlags)
|
||||
|
@ -685,7 +696,10 @@ ContentClientIncremental::BeginPaintBuffer(ThebesLayer* aLayer,
|
|||
nsIntRect drawBounds = result.mRegionToDraw.GetBounds();
|
||||
bool createdBuffer = false;
|
||||
|
||||
uint32_t bufferFlags = canHaveRotation ? TextureFlags::ALLOW_REPEAT : 0;
|
||||
TextureFlags bufferFlags = TextureFlags::NO_FLAGS;
|
||||
if (canHaveRotation) {
|
||||
bufferFlags |= TextureFlags::ALLOW_REPEAT;
|
||||
}
|
||||
if (mode == SurfaceMode::SURFACE_COMPONENT_ALPHA) {
|
||||
bufferFlags |= TextureFlags::COMPONENT_ALPHA;
|
||||
}
|
||||
|
|
|
@ -274,7 +274,7 @@ protected:
|
|||
virtual void DestroyFrontBuffer() {}
|
||||
|
||||
bool CreateAndAllocateTextureClient(RefPtr<TextureClient>& aClient,
|
||||
TextureFlags aFlags = 0);
|
||||
TextureFlags aFlags = TextureFlags::NO_FLAGS);
|
||||
|
||||
virtual void AbortTextureClientCreation()
|
||||
{
|
||||
|
@ -443,16 +443,7 @@ private:
|
|||
BUFFER_WHITE
|
||||
};
|
||||
|
||||
void NotifyBufferCreated(ContentType aType, uint32_t aFlags)
|
||||
{
|
||||
mTextureInfo.mTextureFlags = aFlags & ~TextureFlags::DEALLOCATE_CLIENT;
|
||||
mContentType = aType;
|
||||
|
||||
mForwarder->CreatedIncrementalBuffer(this,
|
||||
mTextureInfo,
|
||||
mBufferRect);
|
||||
|
||||
}
|
||||
void NotifyBufferCreated(ContentType aType, TextureFlags aFlags);
|
||||
|
||||
TemporaryRef<gfx::DrawTarget> GetUpdateSurface(BufferType aType,
|
||||
const nsIntRegion& aUpdateRegion);
|
||||
|
|
|
@ -275,7 +275,7 @@ public:
|
|||
* modified, it can only be read. It is safe to not Lock/Unlock immutable
|
||||
* textures.
|
||||
*/
|
||||
bool IsImmutable() const { return mFlags & TextureFlags::IMMUTABLE; }
|
||||
bool IsImmutable() const { return !!(mFlags & TextureFlags::IMMUTABLE); }
|
||||
|
||||
void MarkImmutable() { AddFlags(TextureFlags::IMMUTABLE); }
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ public:
|
|||
GetTextureFactoryIdentifier() MOZ_OVERRIDE;
|
||||
|
||||
virtual TemporaryRef<DataTextureSource>
|
||||
CreateDataTextureSource(TextureFlags aFlags = 0) MOZ_OVERRIDE;
|
||||
CreateDataTextureSource(TextureFlags aFlags = TextureFlags::NO_FLAGS) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool CanUseCanvasLayerForSize(const gfx::IntSize& aSize) MOZ_OVERRIDE;
|
||||
virtual int32_t GetMaxTextureSize() const MOZ_FINAL;
|
||||
|
|
|
@ -77,7 +77,7 @@ DataTextureSourceD3D11::DataTextureSourceD3D11(SurfaceFormat aFormat,
|
|||
ID3D11Texture2D* aTexture)
|
||||
: mCompositor(aCompositor)
|
||||
, mFormat(aFormat)
|
||||
, mFlags(0)
|
||||
, mFlags(TextureFlags::NO_FLAGS)
|
||||
, mCurrentTile(0)
|
||||
, mIsTiled(false)
|
||||
, mIterating(false)
|
||||
|
|
|
@ -123,7 +123,7 @@ public:
|
|||
}
|
||||
|
||||
virtual TemporaryRef<DataTextureSource>
|
||||
CreateDataTextureSource(TextureFlags aFlags = 0) MOZ_OVERRIDE;
|
||||
CreateDataTextureSource(TextureFlags aFlags = TextureFlags::NO_FLAGS) MOZ_OVERRIDE;
|
||||
private:
|
||||
// ensure mSize is up to date with respect to mWidget
|
||||
void EnsureSize();
|
||||
|
|
|
@ -648,7 +648,7 @@ TemporaryRef<ImageClient>
|
|||
ImageBridgeChild::CreateImageClientNow(CompositableType aType)
|
||||
{
|
||||
RefPtr<ImageClient> client
|
||||
= ImageClient::CreateImageClient(aType, this, 0);
|
||||
= ImageClient::CreateImageClient(aType, this, TextureFlags::NO_FLAGS);
|
||||
MOZ_ASSERT(client, "failed to create ImageClient");
|
||||
if (client) {
|
||||
client->Connect();
|
||||
|
|
|
@ -13,6 +13,7 @@ include ProtocolTypes;
|
|||
include "mozilla/GfxMessageUtils.h";
|
||||
|
||||
using struct mozilla::layers::TextureInfo from "mozilla/layers/CompositorTypes.h";
|
||||
using mozilla::layers::TextureFlags from "mozilla/layers/CompositorTypes.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
@ -51,7 +52,7 @@ parent:
|
|||
sync Stop();
|
||||
|
||||
sync PCompositable(TextureInfo aInfo) returns (uint64_t id);
|
||||
async PTexture(SurfaceDescriptor aSharedData, uint32_t aTextureFlags);
|
||||
async PTexture(SurfaceDescriptor aSharedData, TextureFlags aTextureFlags);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ include "mozilla/GfxMessageUtils.h";
|
|||
|
||||
using struct mozilla::layers::TextureInfo from "mozilla/layers/CompositorTypes.h";
|
||||
using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
|
||||
using mozilla::layers::TextureFlags from "mozilla/layers/CompositorTypes.h";
|
||||
|
||||
/**
|
||||
* The layers protocol is spoken between thread contexts that manage
|
||||
|
@ -74,7 +75,7 @@ parent:
|
|||
returns (MaybeMagicGrallocBufferHandle handle);
|
||||
async PLayer();
|
||||
async PCompositable(TextureInfo aTextureInfo);
|
||||
async PTexture(SurfaceDescriptor aSharedData, uint32_t aTextureFlags);
|
||||
async PTexture(SurfaceDescriptor aSharedData, TextureFlags aTextureFlags);
|
||||
|
||||
// The isFirstPaint flag can be used to indicate that this is the first update
|
||||
// for a particular document.
|
||||
|
|
|
@ -168,7 +168,7 @@ public:
|
|||
virtual ~CompositorOGL();
|
||||
|
||||
virtual TemporaryRef<DataTextureSource>
|
||||
CreateDataTextureSource(TextureFlags aFlags = 0) MOZ_OVERRIDE;
|
||||
CreateDataTextureSource(TextureFlags aFlags = TextureFlags::NO_FLAGS) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool Initialize() MOZ_OVERRIDE;
|
||||
|
||||
|
|
|
@ -19,8 +19,9 @@ using namespace android;
|
|||
|
||||
static gfx::SurfaceFormat
|
||||
SurfaceFormatForAndroidPixelFormat(android::PixelFormat aFormat,
|
||||
bool swapRB = false)
|
||||
TextureFlags aFlags)
|
||||
{
|
||||
bool swapRB = bool(aFlags & TextureFlags::RB_SWAPPED);
|
||||
switch (aFormat) {
|
||||
case android::PIXEL_FORMAT_BGRA_8888:
|
||||
return swapRB ? gfx::SurfaceFormat::R8G8B8A8 : gfx::SurfaceFormat::B8G8R8A8;
|
||||
|
@ -290,7 +291,7 @@ GrallocTextureHostOGL::GrallocTextureHostOGL(TextureFlags aFlags,
|
|||
if (graphicBuffer) {
|
||||
format =
|
||||
SurfaceFormatForAndroidPixelFormat(graphicBuffer->getPixelFormat(),
|
||||
aFlags & TextureFlags::RB_SWAPPED);
|
||||
aFlags);
|
||||
}
|
||||
mTextureSource = new GrallocTextureSourceOGL(nullptr,
|
||||
graphicBuffer,
|
||||
|
|
|
@ -116,10 +116,10 @@ FlagsToGLFlags(TextureFlags aFlags)
|
|||
return static_cast<gl::TextureImage::Flags>(result);
|
||||
}
|
||||
|
||||
GLenum
|
||||
WrapMode(gl::GLContext *aGl, bool aAllowRepeat)
|
||||
static GLenum
|
||||
WrapMode(gl::GLContext *aGl, TextureFlags aFlags)
|
||||
{
|
||||
if (aAllowRepeat &&
|
||||
if ((aFlags & TextureFlags::ALLOW_REPEAT) &&
|
||||
(aGl->IsExtensionSupported(GLContext::ARB_texture_non_power_of_two) ||
|
||||
aGl->IsExtensionSupported(GLContext::OES_texture_npot))) {
|
||||
return LOCAL_GL_REPEAT;
|
||||
|
@ -232,7 +232,7 @@ TextureImageTextureSourceOGL::Update(gfx::DataSourceSurface* aSurface,
|
|||
if (mFlags & TextureFlags::DISALLOW_BIGIMAGE) {
|
||||
mTexImage = CreateBasicTextureImage(mGL, size,
|
||||
gfx::ContentForFormat(aSurface->GetFormat()),
|
||||
WrapMode(mGL, mFlags & TextureFlags::ALLOW_REPEAT),
|
||||
WrapMode(mGL, mFlags),
|
||||
FlagsToGLFlags(mFlags),
|
||||
SurfaceFormatToImageFormat(aSurface->GetFormat()));
|
||||
} else {
|
||||
|
@ -243,7 +243,7 @@ TextureImageTextureSourceOGL::Update(gfx::DataSourceSurface* aSurface,
|
|||
mTexImage = CreateTextureImage(mGL,
|
||||
size,
|
||||
gfx::ContentForFormat(aSurface->GetFormat()),
|
||||
WrapMode(mGL, mFlags & TextureFlags::ALLOW_REPEAT),
|
||||
WrapMode(mGL, mFlags),
|
||||
FlagsToGLFlags(mFlags),
|
||||
SurfaceFormatToImageFormat(aSurface->GetFormat()));
|
||||
}
|
||||
|
@ -268,7 +268,7 @@ TextureImageTextureSourceOGL::EnsureBuffer(const nsIntSize& aSize,
|
|||
mTexImage = CreateTextureImage(mGL,
|
||||
aSize.ToIntSize(),
|
||||
aContentType,
|
||||
WrapMode(mGL, mFlags & TextureFlags::ALLOW_REPEAT),
|
||||
WrapMode(mGL, mFlags),
|
||||
FlagsToGLFlags(mFlags));
|
||||
}
|
||||
mTexImage->Resize(aSize.ToIntSize());
|
||||
|
|
|
@ -270,7 +270,7 @@ TEST(Layers, TextureSerialization) {
|
|||
= new MemoryTextureClient(nullptr,
|
||||
mozilla::gfx::ImageFormatToSurfaceFormat(surface->Format()),
|
||||
gfx::BackendType::CAIRO,
|
||||
TEXTURE_DEALLOCATE_CLIENT);
|
||||
TextureFlags::DEALLOCATE_CLIENT);
|
||||
|
||||
TestTextureClientSurface(client, surface);
|
||||
|
||||
|
@ -307,7 +307,7 @@ TEST(Layers, TextureYCbCrSerialization) {
|
|||
= new MemoryTextureClient(nullptr,
|
||||
mozilla::gfx::SurfaceFormat::YUV,
|
||||
gfx::BackendType::CAIRO,
|
||||
TEXTURE_DEALLOCATE_CLIENT);
|
||||
TextureFlags::DEALLOCATE_CLIENT);
|
||||
|
||||
TestTextureClientYCbCr(client, clientData);
|
||||
|
||||
|
|
|
@ -439,7 +439,7 @@ status_t GonkBufferQueue::dequeueBuffer(int *outBuf, sp<Fence>* outFence,
|
|||
new GrallocTextureClientOGL(ImageBridgeChild::GetSingleton(),
|
||||
gfx::SurfaceFormat::UNKNOWN,
|
||||
gfx::BackendType::NONE,
|
||||
TEXTURE_DEALLOCATE_CLIENT);
|
||||
TextureFlags::DEALLOCATE_CLIENT);
|
||||
usage |= GraphicBuffer::USAGE_HW_TEXTURE;
|
||||
bool result = textureClient->AllocateGralloc(IntSize(w, h), format, usage);
|
||||
sp<GraphicBuffer> graphicBuffer = textureClient->GetGraphicBuffer();
|
||||
|
|
|
@ -467,7 +467,7 @@ status_t GonkBufferQueue::dequeueBuffer(int *outBuf, sp<Fence>* outFence, bool a
|
|||
new GrallocTextureClientOGL(ImageBridgeChild::GetSingleton(),
|
||||
gfx::SurfaceFormat::UNKNOWN,
|
||||
gfx::BackendType::NONE,
|
||||
TEXTURE_DEALLOCATE_CLIENT);
|
||||
TextureFlags::DEALLOCATE_CLIENT);
|
||||
usage |= GraphicBuffer::USAGE_HW_TEXTURE;
|
||||
bool result = textureClient->AllocateGralloc(IntSize(w, h), format, usage);
|
||||
sp<GraphicBuffer> graphicBuffer = textureClient->GetGraphicBuffer();
|
||||
|
|
|
@ -341,7 +341,7 @@ status_t GonkNativeWindow::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
|
|||
new GrallocTextureClientOGL(ImageBridgeChild::GetSingleton(),
|
||||
gfx::SurfaceFormat::UNKNOWN,
|
||||
gfx::BackendType::NONE,
|
||||
TEXTURE_DEALLOCATE_CLIENT);
|
||||
TextureFlags::DEALLOCATE_CLIENT);
|
||||
usage |= GraphicBuffer::USAGE_HW_TEXTURE;
|
||||
bool result = textureClient->AllocateGralloc(IntSize(w, h), format, usage);
|
||||
sp<GraphicBuffer> graphicBuffer = textureClient->GetGraphicBuffer();
|
||||
|
|
Загрузка…
Ссылка в новой задаче