mediapipe/mediapipe/objc/MPPLayerRenderer.m
MediaPipe Team b65c40b302 Internal change
PiperOrigin-RevId: 491441446
2022-11-28 14:17:23 -08:00

104 lines
3.5 KiB
Objective-C

// Copyright 2019 The MediaPipe Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#import "MPPLayerRenderer.h"
@implementation MPPLayerRenderer {
/// Used for rendering to a CAEAGLLayer.
MPPGLViewRenderer *_glRenderer;
/// Used for rendering.
GLuint framebuffer_;
GLuint renderbuffer_;
}
- (instancetype)init {
self = [super init];
if (self) {
_layer = [[CAEAGLLayer alloc] init];
// The default drawable properties are ok.
_layer.opaque = YES;
// Synchronizes presentation with CoreAnimation transactions.
// Avoids desync between GL and CA updates.
// TODO: should this be on by default? It's not on in GLKView,
// but if we add support for AVSampleBufferDisplayLayer we may want to
// make sure the behavior is similar.
if ([_layer respondsToSelector:@selector(setPresentsWithTransaction:)]) {
_layer.presentsWithTransaction = YES;
}
_layer.contentsScale = [[UIScreen mainScreen] scale];
_glRenderer = [[MPPGLViewRenderer alloc] init];
}
return self;
}
- (void)dealloc {
}
- (void)setupFrameBuffer {
[EAGLContext setCurrentContext:_glRenderer.glContext];
glDisable(GL_DEPTH_TEST);
glGenFramebuffers(1, &framebuffer_);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_);
glGenRenderbuffers(1, &renderbuffer_);
glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer_);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer_);
BOOL success __unused = [_glRenderer.glContext renderbufferStorage:GL_RENDERBUFFER
fromDrawable:_layer];
NSAssert(success, @"could not create renderbuffer storage for layer with bounds %@",
NSStringFromCGRect(_layer.bounds));
GLenum status __unused = glCheckFramebufferStatus(GL_FRAMEBUFFER);
NSAssert(status == GL_FRAMEBUFFER_COMPLETE,
@"failed to make complete framebuffer object %x", status);
}
- (void)renderPixelBuffer:(CVPixelBufferRef)pixelBuffer {
if (!framebuffer_) {
[self setupFrameBuffer];
}
GLfloat drawWidth = _layer.bounds.size.width * _layer.contentsScale;
GLfloat drawHeight = _layer.bounds.size.height * _layer.contentsScale;
[EAGLContext setCurrentContext:_glRenderer.glContext];
glViewport(0, 0, drawWidth, drawHeight);
[_glRenderer drawPixelBuffer:pixelBuffer width:drawWidth height:drawHeight];
BOOL success = [_glRenderer.glContext presentRenderbuffer:GL_RENDERBUFFER];
if (!success) NSLog(@"presentRenderbuffer failed");
}
- (MPPFrameRotation)frameRotationMode {
return _glRenderer.frameRotationMode;
}
- (void)setFrameRotationMode:(MPPFrameRotation)frameRotationMode {
_glRenderer.frameRotationMode = frameRotationMode;
}
- (MPPFrameScaleMode)frameScaleMode {
return _glRenderer.frameScaleMode;
}
- (void)setFrameScaleMode:(MPPFrameScaleMode)frameScaleMode {
_glRenderer.frameScaleMode = frameScaleMode;
}
- (BOOL)mirrored {
return _glRenderer.mirrored;
}
- (void)setMirrored:(BOOL)mirrored {
_glRenderer.mirrored = mirrored;
}
@end