Skip to content

Commit

Permalink
Remove the independent texture cache on iOS.
Browse files Browse the repository at this point in the history
  • Loading branch information
lvpengwei authored and domchen committed Jan 18, 2022
1 parent b5c1c29 commit 0fe6cb3
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 42 deletions.
6 changes: 3 additions & 3 deletions tgfx/src/gpu/opengl/eagl/EAGLHardwareTexture.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ namespace pag {
class EAGLHardwareTexture : public GLTexture {
public:
static std::shared_ptr<EAGLHardwareTexture> MakeFrom(Context* context,
CVPixelBufferRef pixelBuffer, bool adopted);
CVPixelBufferRef pixelBuffer, bool adopted);

explicit EAGLHardwareTexture(CVPixelBufferRef pixelBuffer);
EAGLHardwareTexture(CVPixelBufferRef pixelBuffer, bool adopted);

~EAGLHardwareTexture() override;
size_t memoryUsage() const override;
Expand All @@ -38,8 +38,8 @@ class EAGLHardwareTexture : public GLTexture {

private:
CVPixelBufferRef pixelBuffer = nullptr;
CVOpenGLESTextureCacheRef textureCache = nil;
CVOpenGLESTextureRef texture = nil;
bool adopted = false;

static void ComputeRecycleKey(BytesKey* recycleKey, CVPixelBufferRef pixelBuffer);
};
Expand Down
52 changes: 13 additions & 39 deletions tgfx/src/gpu/opengl/eagl/EAGLHardwareTexture.mm
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
static CVOpenGLESTextureRef GetTextureRef(Context* context, CVPixelBufferRef pixelBuffer,
CVOpenGLESTextureCacheRef textureCache,
unsigned* sizedFormat) {
if (textureCache == nil) {
return nil;
}
auto width = static_cast<int>(CVPixelBufferGetWidth(pixelBuffer));
auto height = static_cast<int>(CVPixelBufferGetHeight(pixelBuffer));
auto pixelFormat = CVPixelBufferGetPixelFormatType(pixelBuffer);
Expand All @@ -35,16 +38,16 @@ static CVOpenGLESTextureRef GetTextureRef(Context* context, CVPixelBufferRef pix
// 返回的 texture 对象是一个强引用计数为 1 的对象。
result = CVOpenGLESTextureCacheCreateTextureFromImage(
kCFAllocatorDefault, textureCache, pixelBuffer, NULL, /* texture attributes */
GL::TEXTURE_2D, format.internalFormatTexImage, /* opengl format */
GL::TEXTURE_2D, format.internalFormatTexImage, /* opengl format */
width, height, format.externalFormat, /* native iOS format */
GL::UNSIGNED_BYTE, 0, &texture);
} else {
*sizedFormat = GL::RGBA8;
// 返回的 texture 对象是一个强引用计数为 1 的对象。
result = CVOpenGLESTextureCacheCreateTextureFromImage(
kCFAllocatorDefault, textureCache, pixelBuffer, NULL, /* texture attributes */
GL::TEXTURE_2D, GL::RGBA, /* opengl format */
width, height, GL::BGRA, /* native iOS format */
GL::TEXTURE_2D, GL::RGBA, /* opengl format */
width, height, GL::BGRA, /* native iOS format */
GL::UNSIGNED_BYTE, 0, &texture);
}
if (result != kCVReturnSuccess && texture != nil) {
Expand All @@ -71,24 +74,9 @@ static CVOpenGLESTextureRef GetTextureRef(Context* context, CVPixelBufferRef pix
if (eaglDevice == nullptr) {
return nullptr;
}
CVOpenGLESTextureCacheRef textureCache = nil;
if (adopted) {
// use independent texture cache here, to prevent memory leaking when binding the same
// CVPixelBuffer to two different texture caches.
CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, NULL, eaglDevice->eaglContext(), NULL,
&textureCache);
} else {
textureCache = eaglDevice->getTextureCache();
}
if (textureCache == nil) {
return nullptr;
}
unsigned sizedFormat = 0;
auto texture = GetTextureRef(context, pixelBuffer, textureCache, &sizedFormat);
auto texture = GetTextureRef(context, pixelBuffer, eaglDevice->getTextureCache(), &sizedFormat);
if (texture == nil) {
if (adopted) {
CFRelease(textureCache);
}
return nullptr;
}
GLTextureInfo glInfo = {};
Expand All @@ -97,11 +85,10 @@ static CVOpenGLESTextureRef GetTextureRef(Context* context, CVPixelBufferRef pix
glInfo.format = sizedFormat;
auto oneComponent8 =
CVPixelBufferGetPixelFormatType(pixelBuffer) == kCVPixelFormatType_OneComponent8;
glTexture = Resource::Wrap(context, new EAGLHardwareTexture(pixelBuffer));
glTexture = Resource::Wrap(context, new EAGLHardwareTexture(pixelBuffer, adopted));
glTexture->sampler.glInfo = glInfo;
glTexture->sampler.config = oneComponent8 ? PixelConfig::ALPHA_8 : PixelConfig::RGBA_8888;
glTexture->texture = texture;
glTexture->textureCache = adopted ? textureCache : nil;
return glTexture;
}

Expand All @@ -114,10 +101,11 @@ static CVOpenGLESTextureRef GetTextureRef(Context* context, CVPixelBufferRef pix
recycleKey->write(pixelBuffer);
}

EAGLHardwareTexture::EAGLHardwareTexture(CVPixelBufferRef pixelBuffer)
EAGLHardwareTexture::EAGLHardwareTexture(CVPixelBufferRef pixelBuffer, bool adopted)
: GLTexture(static_cast<int>(CVPixelBufferGetWidth(pixelBuffer)),
static_cast<int>(CVPixelBufferGetHeight(pixelBuffer)), ImageOrigin::TopLeft),
pixelBuffer(pixelBuffer) {
pixelBuffer(pixelBuffer),
adopted(adopted) {
CFRetain(pixelBuffer);
}

Expand All @@ -126,9 +114,6 @@ static CVOpenGLESTextureRef GetTextureRef(Context* context, CVPixelBufferRef pix
if (texture) {
CFRelease(texture);
}
if (textureCache) {
CFRelease(textureCache);
}
}

size_t EAGLHardwareTexture::memoryUsage() const {
Expand All @@ -137,8 +122,7 @@ static CVOpenGLESTextureRef GetTextureRef(Context* context, CVPixelBufferRef pix
}

void EAGLHardwareTexture::computeRecycleKey(BytesKey* recycleKey) const {
if (textureCache == nil) {
// not adopted
if (!adopted) {
ComputeRecycleKey(recycleKey, pixelBuffer);
}
}
Expand All @@ -147,17 +131,7 @@ static CVOpenGLESTextureRef GetTextureRef(Context* context, CVPixelBufferRef pix
if (texture == nil) {
return;
}
auto cache = textureCache;
if (!cache) {
auto eaglDevice = static_cast<EAGLDevice*>(context->getDevice());
cache = eaglDevice->getTextureCache();
}
CFRelease(texture);
static_cast<EAGLDevice*>(context->getDevice())->releaseTexture(texture);
texture = nil;
CVOpenGLESTextureCacheFlush(cache, 0);
if (textureCache != nil) {
CFRelease(textureCache);
textureCache = nil;
}
}
}

0 comments on commit 0fe6cb3

Please sign in to comment.