Use utility framebuffer in ViewDoneWritingSimulatorWorkaround

This code needs a FBO to bind the texture.

Fixes invalid results when running under simulator.

PiperOrigin-RevId: 499241867
This commit is contained in:
Camillo Lugaresi 2023-01-03 09:34:21 -08:00 committed by Copybara-Service
parent 9252a025e5
commit 2f4bb5d545

View File

@ -74,42 +74,51 @@ GlTextureView GpuBufferStorageCvPixelBuffer::GetReadView(
static void ViewDoneWritingSimulatorWorkaround(CVPixelBufferRef pixel_buffer, static void ViewDoneWritingSimulatorWorkaround(CVPixelBufferRef pixel_buffer,
const GlTextureView& view) { const GlTextureView& view) {
CHECK(pixel_buffer); CHECK(pixel_buffer);
CVReturn err = CVPixelBufferLockBaseAddress(pixel_buffer, 0); auto ctx = GlContext::GetCurrent().get();
CHECK(err == kCVReturnSuccess) if (!ctx) ctx = view.gl_context();
<< "CVPixelBufferLockBaseAddress failed: " << err; ctx->Run([pixel_buffer, &view, ctx] {
OSType pixel_format = CVPixelBufferGetPixelFormatType(pixel_buffer); CVReturn err = CVPixelBufferLockBaseAddress(pixel_buffer, 0);
size_t bytes_per_row = CVPixelBufferGetBytesPerRow(pixel_buffer); CHECK(err == kCVReturnSuccess)
uint8_t* pixel_ptr = << "CVPixelBufferLockBaseAddress failed: " << err;
static_cast<uint8_t*>(CVPixelBufferGetBaseAddress(pixel_buffer)); OSType pixel_format = CVPixelBufferGetPixelFormatType(pixel_buffer);
if (pixel_format == kCVPixelFormatType_32BGRA) { size_t bytes_per_row = CVPixelBufferGetBytesPerRow(pixel_buffer);
// TODO: restore previous framebuffer? Move this to helper so we uint8_t* pixel_ptr =
// can use BindFramebuffer? static_cast<uint8_t*>(CVPixelBufferGetBaseAddress(pixel_buffer));
glViewport(0, 0, view.width(), view.height()); if (pixel_format == kCVPixelFormatType_32BGRA) {
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, view.target(), glBindFramebuffer(GL_FRAMEBUFFER, kUtilityFramebuffer.Get(*ctx));
view.name(), 0); glViewport(0, 0, view.width(), view.height());
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
view.target(), view.name(), 0);
size_t contiguous_bytes_per_row = view.width() * 4; size_t contiguous_bytes_per_row = view.width() * 4;
if (bytes_per_row == contiguous_bytes_per_row) { if (bytes_per_row == contiguous_bytes_per_row) {
glReadPixels(0, 0, view.width(), view.height(), GL_BGRA, GL_UNSIGNED_BYTE, glReadPixels(0, 0, view.width(), view.height(), GL_BGRA,
pixel_ptr); GL_UNSIGNED_BYTE, pixel_ptr);
} else { } else {
std::vector<uint8_t> contiguous_buffer(contiguous_bytes_per_row * // TODO: use GL_PACK settings for row length. We can expect
view.height()); // GLES 3.0 on iOS now.
uint8_t* temp_ptr = contiguous_buffer.data(); std::vector<uint8_t> contiguous_buffer(contiguous_bytes_per_row *
glReadPixels(0, 0, view.width(), view.height(), GL_BGRA, GL_UNSIGNED_BYTE, view.height());
temp_ptr); uint8_t* temp_ptr = contiguous_buffer.data();
for (int i = 0; i < view.height(); ++i) { glReadPixels(0, 0, view.width(), view.height(), GL_BGRA,
memcpy(pixel_ptr, temp_ptr, contiguous_bytes_per_row); GL_UNSIGNED_BYTE, temp_ptr);
temp_ptr += contiguous_bytes_per_row; for (int i = 0; i < view.height(); ++i) {
pixel_ptr += bytes_per_row; memcpy(pixel_ptr, temp_ptr, contiguous_bytes_per_row);
temp_ptr += contiguous_bytes_per_row;
pixel_ptr += bytes_per_row;
}
} }
// TODO: restore previous framebuffer?
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
view.target(), 0, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
} else {
LOG(ERROR) << "unsupported pixel format: " << pixel_format;
} }
} else { err = CVPixelBufferUnlockBaseAddress(pixel_buffer, 0);
LOG(ERROR) << "unsupported pixel format: " << pixel_format; CHECK(err == kCVReturnSuccess)
} << "CVPixelBufferUnlockBaseAddress failed: " << err;
err = CVPixelBufferUnlockBaseAddress(pixel_buffer, 0); });
CHECK(err == kCVReturnSuccess)
<< "CVPixelBufferUnlockBaseAddress failed: " << err;
} }
#endif // TARGET_IPHONE_SIMULATOR #endif // TARGET_IPHONE_SIMULATOR