Project import generated by Copybara.
GitOrigin-RevId: 796203faee20d7aae2876aac8ca5a1827dee4fe3
This commit is contained in:
+21
-2
@@ -80,8 +80,7 @@ GL_BASE_LINK_OPTS_OSS = GL_BASE_LINK_OPTS + select({
|
||||
"-lEGL",
|
||||
],
|
||||
"//mediapipe:android": [],
|
||||
"//mediapipe:apple": [],
|
||||
"//mediapipe:macos": [],
|
||||
"//mediapipe:ios": [],
|
||||
":disable_gpu": [],
|
||||
})
|
||||
|
||||
@@ -289,6 +288,25 @@ objc_library(
|
||||
],
|
||||
)
|
||||
|
||||
objc_library(
|
||||
name = "MPPMetalUtil",
|
||||
srcs = ["MPPMetalUtil.mm"],
|
||||
hdrs = ["MPPMetalUtil.h"],
|
||||
copts = [
|
||||
"-x objective-c++",
|
||||
"-Wno-shorten-64-to-32",
|
||||
],
|
||||
sdk_frameworks = [
|
||||
"CoreVideo",
|
||||
"Metal",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//mediapipe/objc:mediapipe_framework_ios",
|
||||
"@google_toolbox_for_mac//:GTM_Defines",
|
||||
],
|
||||
)
|
||||
|
||||
proto_library(
|
||||
name = "gl_context_options_proto",
|
||||
srcs = ["gl_context_options.proto"],
|
||||
@@ -499,6 +517,7 @@ cc_library(
|
||||
":gl_base",
|
||||
":gl_context",
|
||||
":gpu_buffer",
|
||||
":gpu_buffer_format",
|
||||
":gpu_buffer_multi_pool",
|
||||
":gpu_shared_data_internal",
|
||||
":gpu_service",
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
// 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.
|
||||
|
||||
#ifndef MEDIAPIPE_GPU_MPP_METAL_UTIL_H_
|
||||
#define MEDIAPIPE_GPU_MPP_METAL_UTIL_H_
|
||||
|
||||
#import <CoreVideo/CVMetalTextureCache.h>
|
||||
#import <CoreVideo/CoreVideo.h>
|
||||
#import <Metal/Metal.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface MPPMetalUtil : NSObject {
|
||||
}
|
||||
|
||||
/// Copies a Metal Buffer from source to destination.
|
||||
/// Uses blitCommandEncoder and assumes offset of 0.
|
||||
+ (void)blitMetalBufferTo:(id<MTLBuffer>)destination
|
||||
from:(id<MTLBuffer>)source
|
||||
blocking:(bool)blocking
|
||||
commandBuffer:(id<MTLCommandBuffer>)commandBuffer;
|
||||
|
||||
/// Copies a Metal Buffer from source to destination.
|
||||
/// Simple wrapper for blitCommandEncoder.
|
||||
/// Optionally block until operation is completed.
|
||||
+ (void)blitMetalBufferTo:(id<MTLBuffer>)destination
|
||||
destinationOffset:(int)destinationOffset
|
||||
from:(id<MTLBuffer>)source
|
||||
sourceOffset:(int)sourceOffset
|
||||
bytes:(size_t)bytes
|
||||
blocking:(bool)blocking
|
||||
commandBuffer:(id<MTLCommandBuffer>)commandBuffer;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
#endif // MEDIAPIPE_GPU_MPP_METAL_UTIL_H_
|
||||
@@ -0,0 +1,51 @@
|
||||
// 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 "mediapipe/gpu/MPPMetalUtil.h"
|
||||
|
||||
@implementation MPPMetalUtil
|
||||
|
||||
+ (void)blitMetalBufferTo:(id<MTLBuffer>)destination
|
||||
from:(id<MTLBuffer>)source
|
||||
blocking:(bool)blocking
|
||||
commandBuffer:(id<MTLCommandBuffer>)commandBuffer {
|
||||
size_t bytes = MIN(destination.length, source.length);
|
||||
[self blitMetalBufferTo:destination
|
||||
destinationOffset:0
|
||||
from:source
|
||||
sourceOffset:0
|
||||
bytes:bytes
|
||||
blocking:blocking
|
||||
commandBuffer:commandBuffer];
|
||||
}
|
||||
|
||||
+ (void)blitMetalBufferTo:(id<MTLBuffer>)destination
|
||||
destinationOffset:(int)destinationOffset
|
||||
from:(id<MTLBuffer>)source
|
||||
sourceOffset:(int)sourceOffset
|
||||
bytes:(size_t)bytes
|
||||
blocking:(bool)blocking
|
||||
commandBuffer:(id<MTLCommandBuffer>)commandBuffer {
|
||||
id<MTLBlitCommandEncoder> blit_command = [commandBuffer blitCommandEncoder];
|
||||
[blit_command copyFromBuffer:source
|
||||
sourceOffset:sourceOffset
|
||||
toBuffer:destination
|
||||
destinationOffset:destinationOffset
|
||||
size:bytes];
|
||||
[blit_command endEncoding];
|
||||
[commandBuffer commit];
|
||||
if (blocking) [commandBuffer waitUntilCompleted];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -73,7 +73,7 @@ class GlCalculatorHelperImpl {
|
||||
#endif // !MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER
|
||||
|
||||
// Sets default texture filtering parameters.
|
||||
void SetStandardTextureParams(GLenum target);
|
||||
void SetStandardTextureParams(GLenum target, GLint internal_format);
|
||||
|
||||
// Create the framebuffer for rendering.
|
||||
void CreateFramebuffer();
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
#include "mediapipe/gpu/gl_calculator_helper_impl.h"
|
||||
#include "mediapipe/gpu/gpu_buffer_format.h"
|
||||
#include "mediapipe/gpu/gpu_shared_data_internal.h"
|
||||
|
||||
namespace mediapipe {
|
||||
@@ -86,9 +87,21 @@ void GlCalculatorHelperImpl::BindFramebuffer(const GlTexture& dst) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void GlCalculatorHelperImpl::SetStandardTextureParams(GLenum target) {
|
||||
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
void GlCalculatorHelperImpl::SetStandardTextureParams(GLenum target,
|
||||
GLint internal_format) {
|
||||
GLint filter;
|
||||
switch (internal_format) {
|
||||
case GL_R32F:
|
||||
case GL_RGBA32F:
|
||||
// 32F (unlike 16f) textures do not support texture filtering
|
||||
// (According to OpenGL ES specification [TEXTURE IMAGE SPECIFICATION])
|
||||
filter = GL_NEAREST;
|
||||
break;
|
||||
default:
|
||||
filter = GL_LINEAR;
|
||||
}
|
||||
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, filter);
|
||||
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, filter);
|
||||
glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
@@ -136,7 +149,9 @@ GlTexture GlCalculatorHelperImpl::MapGlTextureBuffer(
|
||||
|
||||
// TODO: do the params need to be reset here??
|
||||
glBindTexture(texture.target(), texture.name());
|
||||
SetStandardTextureParams(texture.target());
|
||||
GlTextureInfo info =
|
||||
GlTextureInfoForGpuBufferFormat(texture_buffer->format(), texture.plane_);
|
||||
SetStandardTextureParams(texture.target(), info.gl_internal_format);
|
||||
glBindTexture(texture.target(), 0);
|
||||
|
||||
return texture;
|
||||
@@ -150,7 +165,9 @@ GlTextureBufferSharedPtr GlCalculatorHelperImpl::MakeGlTextureBuffer(
|
||||
GpuBufferFormatForImageFormat(image_frame.Format()),
|
||||
image_frame.PixelData());
|
||||
glBindTexture(GL_TEXTURE_2D, buffer->name_);
|
||||
SetStandardTextureParams(buffer->target_);
|
||||
GlTextureInfo info =
|
||||
GlTextureInfoForGpuBufferFormat(buffer->format_, /*plane=*/0);
|
||||
SetStandardTextureParams(buffer->target_, info.gl_internal_format);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
return buffer;
|
||||
|
||||
@@ -54,7 +54,7 @@ GlTexture GlCalculatorHelperImpl::CreateSourceTexture(
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, info.gl_internal_format, texture.width_,
|
||||
texture.height_, 0, info.gl_format, info.gl_type,
|
||||
image_frame.PixelData());
|
||||
SetStandardTextureParams(GL_TEXTURE_2D);
|
||||
SetStandardTextureParams(GL_TEXTURE_2D, info.gl_internal_format);
|
||||
return texture;
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ GlTexture GlCalculatorHelperImpl::MapGpuBuffer(
|
||||
#endif // TARGET_OS_OSX
|
||||
|
||||
glBindTexture(texture.target(), texture.name());
|
||||
SetStandardTextureParams(texture.target());
|
||||
SetStandardTextureParams(texture.target(), info.gl_internal_format);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
@@ -110,7 +110,13 @@ GlContext::StatusOrGlContext GlContext::Create(EGLContext share_context,
|
||||
eglChooseConfig(display_, config_attr, &config_, 1, &num_configs);
|
||||
if (!success) {
|
||||
return ::mediapipe::UnknownErrorBuilder(MEDIAPIPE_LOC)
|
||||
<< "eglChooseConfig() returned error " << eglGetError();
|
||||
<< "eglChooseConfig() returned error " << std::showbase << std::hex
|
||||
<< eglGetError();
|
||||
}
|
||||
if (!num_configs) {
|
||||
return ::mediapipe::UnknownErrorBuilder(MEDIAPIPE_LOC)
|
||||
<< "eglChooseConfig() returned no matching EGL configuration for "
|
||||
<< "RGBA8888 D16 ES" << gl_version << " request. ";
|
||||
}
|
||||
|
||||
const EGLint context_attr[] = {
|
||||
@@ -125,7 +131,8 @@ GlContext::StatusOrGlContext GlContext::Create(EGLContext share_context,
|
||||
int error = eglGetError();
|
||||
RET_CHECK(context_ != EGL_NO_CONTEXT)
|
||||
<< "Could not create GLES " << gl_version << " context; "
|
||||
<< "eglCreateContext() returned error " << error
|
||||
<< "eglCreateContext() returned error " << std::showbase << std::hex
|
||||
<< error
|
||||
<< (error == EGL_BAD_CONTEXT
|
||||
? ": external context uses a different version of OpenGL"
|
||||
: "");
|
||||
@@ -143,7 +150,8 @@ GlContext::StatusOrGlContext GlContext::Create(EGLContext share_context,
|
||||
|
||||
display_ = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
RET_CHECK(display_ != EGL_NO_DISPLAY)
|
||||
<< "eglGetDisplay() returned error " << eglGetError();
|
||||
<< "eglGetDisplay() returned error " << std::showbase << std::hex
|
||||
<< eglGetError();
|
||||
|
||||
EGLBoolean success = eglInitialize(display_, &major, &minor);
|
||||
RET_CHECK(success) << "Unable to initialize EGL";
|
||||
@@ -162,7 +170,8 @@ GlContext::StatusOrGlContext GlContext::Create(EGLContext share_context,
|
||||
|
||||
surface_ = eglCreatePbufferSurface(display_, config_, pbuffer_attr);
|
||||
RET_CHECK(surface_ != EGL_NO_SURFACE)
|
||||
<< "eglCreatePbufferSurface() returned error " << eglGetError();
|
||||
<< "eglCreatePbufferSurface() returned error " << std::showbase
|
||||
<< std::hex << eglGetError();
|
||||
|
||||
return ::mediapipe::OkStatus();
|
||||
}
|
||||
@@ -186,17 +195,21 @@ void GlContext::DestroyContext() {
|
||||
if (IsCurrent()) {
|
||||
if (!eglMakeCurrent(display_, EGL_NO_SURFACE, EGL_NO_SURFACE,
|
||||
EGL_NO_CONTEXT)) {
|
||||
LOG(ERROR) << "eglMakeCurrent() returned error " << eglGetError();
|
||||
LOG(ERROR) << "eglMakeCurrent() returned error " << std::showbase
|
||||
<< std::hex << eglGetError();
|
||||
}
|
||||
}
|
||||
if (surface_ != EGL_NO_SURFACE) {
|
||||
if (!eglDestroySurface(display_, surface_)) {
|
||||
LOG(ERROR) << "eglDestroySurface() returned error " << eglGetError();
|
||||
LOG(ERROR) << "eglDestroySurface() returned error " << std::showbase
|
||||
<< std::hex << eglGetError();
|
||||
}
|
||||
surface_ = EGL_NO_SURFACE;
|
||||
}
|
||||
if (context_ != EGL_NO_CONTEXT) {
|
||||
if (!eglDestroyContext(display_, context_)) {
|
||||
LOG(ERROR) << "eglDestroyContext() returned error " << eglGetError();
|
||||
LOG(ERROR) << "eglDestroyContext() returned error " << std::showbase
|
||||
<< std::hex << eglGetError();
|
||||
}
|
||||
context_ = EGL_NO_CONTEXT;
|
||||
}
|
||||
@@ -245,7 +258,8 @@ void GlContext::GetCurrentContextBinding(GlContext::ContextBinding* binding) {
|
||||
EGLBoolean success =
|
||||
eglMakeCurrent(display, new_binding.draw_surface,
|
||||
new_binding.read_surface, new_binding.context);
|
||||
RET_CHECK(success) << "eglMakeCurrent() returned error " << eglGetError();
|
||||
RET_CHECK(success) << "eglMakeCurrent() returned error " << std::showbase
|
||||
<< std::hex << eglGetError();
|
||||
return ::mediapipe::OkStatus();
|
||||
}
|
||||
|
||||
|
||||
@@ -77,7 +77,8 @@ bool GlTextureBuffer::CreateInternal(const void* data) {
|
||||
// TODO: maybe we do not actually have to wait for the
|
||||
// consumer sync here. Check docs.
|
||||
sync_token->WaitOnGpu();
|
||||
DCHECK(glIsTexture(name_to_delete));
|
||||
DLOG_IF(ERROR, !glIsTexture(name_to_delete))
|
||||
<< "Deleting invalid texture id: " << name_to_delete;
|
||||
glDeleteTextures(1, &name_to_delete);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
// 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.
|
||||
|
||||
#include "mediapipe/gpu/gpu_buffer.h"
|
||||
|
||||
#include "mediapipe/framework/port/gmock.h"
|
||||
#include "mediapipe/framework/port/gtest.h"
|
||||
#include "mediapipe/gpu/gpu_test_base.h"
|
||||
|
||||
namespace mediapipe {
|
||||
namespace {
|
||||
|
||||
class GpuBufferTest : public GpuTestBase {};
|
||||
|
||||
TEST_F(GpuBufferTest, BasicTest) {
|
||||
RunInGlContext([this] {
|
||||
GpuBuffer buffer = gpu_shared_.gpu_buffer_pool.GetBuffer(300, 200);
|
||||
EXPECT_EQ(buffer.width(), 300);
|
||||
EXPECT_EQ(buffer.height(), 200);
|
||||
EXPECT_TRUE(buffer);
|
||||
EXPECT_FALSE(buffer == nullptr);
|
||||
|
||||
GpuBuffer no_buffer;
|
||||
EXPECT_FALSE(no_buffer);
|
||||
EXPECT_TRUE(no_buffer == nullptr);
|
||||
|
||||
GpuBuffer buffer2 = buffer;
|
||||
EXPECT_EQ(buffer, buffer);
|
||||
EXPECT_EQ(buffer, buffer2);
|
||||
EXPECT_NE(buffer, no_buffer);
|
||||
|
||||
buffer = nullptr;
|
||||
EXPECT_TRUE(buffer == nullptr);
|
||||
EXPECT_TRUE(buffer == no_buffer);
|
||||
});
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
} // namespace mediapipe
|
||||
@@ -123,7 +123,7 @@ struct GpuSharedData {
|
||||
PlatformGlContext external_context) {
|
||||
auto status_or_resources = GpuResources::Create(external_context);
|
||||
MEDIAPIPE_CHECK_OK(status_or_resources.status())
|
||||
<< "could not create GpuResources";
|
||||
<< ": could not create GpuResources";
|
||||
return std::move(status_or_resources).ValueOrDie();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
// 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.
|
||||
|
||||
#ifndef MEDIAPIPE_GPU_GPU_TEST_BASE_H_
|
||||
#define MEDIAPIPE_GPU_GPU_TEST_BASE_H_
|
||||
|
||||
#include "mediapipe/framework/port/gmock.h"
|
||||
#include "mediapipe/framework/port/gtest.h"
|
||||
#include "mediapipe/gpu/gl_calculator_helper.h"
|
||||
#include "mediapipe/gpu/gpu_shared_data_internal.h"
|
||||
|
||||
namespace mediapipe {
|
||||
|
||||
class GpuTestBase : public ::testing::Test {
|
||||
protected:
|
||||
GpuTestBase() { helper_.InitializeForTest(&gpu_shared_); }
|
||||
|
||||
void RunInGlContext(std::function<void(void)> gl_func) {
|
||||
helper_.RunInGlContext(std::move(gl_func));
|
||||
}
|
||||
|
||||
GpuSharedData gpu_shared_;
|
||||
GlCalculatorHelper helper_;
|
||||
};
|
||||
|
||||
} // namespace mediapipe
|
||||
|
||||
#endif // MEDIAPIPE_GPU_GPU_TEST_BASE_H_
|
||||
Reference in New Issue
Block a user