diff --git a/android/sharedCode/src/main/cpp/VROAVRecorderAndroid.cpp b/android/sharedCode/src/main/cpp/VROAVRecorderAndroid.cpp index 55565309e..a53378f6e 100644 --- a/android/sharedCode/src/main/cpp/VROAVRecorderAndroid.cpp +++ b/android/sharedCode/src/main/cpp/VROAVRecorderAndroid.cpp @@ -86,7 +86,16 @@ bool VROAVRecorderAndroid::onRenderedFrameTexture(std::shared_ptrsetViewport({0, 0, input->getWidth(), input->getHeight()}); driver->bindRenderTarget(_recorderDisplay, VRORenderTargetUnbindOp::Invalidate); - _recordingPostProcess->blit({ input->getTexture(0) }, driver); + + // In linear color mode (HDR enabled) the scene framebuffer holds linear RGB values; + // gamma-encode them before the encoder reads the surface, otherwise recorded video + // is noticeably darker than the live view. In non-linear mode the framebuffer is + // already sRGB-encoded and can be blit straight through. + if (driver->getColorRenderingMode() == VROColorRenderingMode::Linear) { + getGammaPostProcess(driver)->blit({ input->getTexture(0) }, driver); + } else { + _recordingPostProcess->blit({ input->getTexture(0) }, driver); + } } if (_scheduledScreenShot) { @@ -156,11 +165,16 @@ std::shared_ptr VROAVRecorderAndroid::bindScreenshotLDRTarget(i std::shared_ptr VROAVRecorderAndroid::getGammaPostProcess(std::shared_ptr driver) { if (!_gammaPostProcess) { - std::vector samplers = { "hdr_texture", "tone_mapping_mask" }; + // The sampler name in `samplers` must match the uniform name in the shader + // code below — VROImagePostProcess uses `samplers` to locate and bind the + // input texture(s) to the corresponding shader uniform(s). A name mismatch + // leaves the sampler unbound and the shader reads from texture unit 0 with + // no texture attached, producing a black frame. + std::vector samplers = { "hdr_texture" }; std::vector code = { "const highp float gamma = 2.2;", - "uniform sampler2D srgb_texture;", - "highp vec4 srgb_color = texture(srgb_texture, v_texcoord);", + "uniform sampler2D hdr_texture;", + "highp vec4 srgb_color = texture(hdr_texture, v_texcoord);", "highp vec3 gamma_color = pow(srgb_color.xyz, vec3(1.0 / gamma));", "frag_color = vec4(gamma_color, srgb_color.a);", }; diff --git a/android/sharedCode/src/main/cpp/arcore/VROARSessionARCore.cpp b/android/sharedCode/src/main/cpp/arcore/VROARSessionARCore.cpp index 522851679..d706eee4d 100644 --- a/android/sharedCode/src/main/cpp/arcore/VROARSessionARCore.cpp +++ b/android/sharedCode/src/main/cpp/arcore/VROARSessionARCore.cpp @@ -1637,6 +1637,7 @@ void VROARSessionARCore::checkVPSAvailability(double latitude, double longitude, // acquireNewAnchor. No VPS required — placed by GPS + compass + VIO. // AR placement math is delegated to RVCCAGeospatialProvider::computeArPosition() // (proprietary algorithm inside libreactvisioncca — not exposed in open-source virocore). +#if RVCCA_AVAILABLE static std::shared_ptr createLocalGPSAnchor( arcore::Session *session, const VROGeospatialPose &devicePose, @@ -1682,6 +1683,7 @@ static std::shared_ptr createLocalGPSAnchor( arSession->addAnchor(vAnchor); return geoAnchor; } +#endif // RVCCA_AVAILABLE void VROARSessionARCore::createGeospatialAnchor(double latitude, double longitude, double altitude, VROQuaternion quaternion, diff --git a/android/sharedCode/src/main/java/com/viro/core/internal/MediaRecorderSurface.java b/android/sharedCode/src/main/java/com/viro/core/internal/MediaRecorderSurface.java index e25f30071..6eda0a5b5 100644 --- a/android/sharedCode/src/main/java/com/viro/core/internal/MediaRecorderSurface.java +++ b/android/sharedCode/src/main/java/com/viro/core/internal/MediaRecorderSurface.java @@ -105,12 +105,14 @@ public boolean eglSetup() { return false; } - // Finally, create a window egl surface with the shared eglContext and mRecorderSurface. - final int EGL_GL_COLORSPACE_KHR = 0x309D; - final int EGL_GL_COLORSPACE_SRGB_KHR = 0x3089; + // Create a window egl surface with the shared eglContext and mRecorderSurface. + // Only EGL_NONE is passed — no EGL_GL_COLORSPACE_* attribute. On Tensor/Mali drivers, + // tagging the encoder-input surface as sRGB causes the driver to gamma-linearize + // every framebuffer write and the encoder to emit color_transfer=iec61966-2-1, + // producing mis-tagged pixels that no post-hoc remux can repair and throttling GPU + // throughput. With no colorspace attribute the encoder emits plain BT.709 SDR + // consistently across SoCs. final int[] surfaceAttribs = { - EGL_GL_COLORSPACE_KHR, - EGL_GL_COLORSPACE_SRGB_KHR, EGL14.EGL_NONE }; mEGLSurface = EGL14.eglCreateWindowSurface(mEGLDisplay, configs[0], mRecorderSurface,