-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Description
Consider a call to GrGLGpu::readOrTransferPixelsFrom with renderTarget == null.
This leads to bindSurfaceFBOForPixelOps being called, which binds a temporary framebuffer to the current OpenGL context and then binds a texture to that framebuffer. After GrGLGpu::readOrTransferPixelsFrom has read the pixels the function unbindSurfaceFBOForPixelOps is called, which unbinds the texture but does not revert the framebuffer change.
Thus, the next OpenGL rendering call tries to access the temporary (and incomplete) framebuffer. Hence rendering fails and the application seems to be hung.
Adding this->bindFramebuffer(fboTarget, 0); to the end of unbindSurfaceFBOForPixelOps fixes the problem. However, I am not sure if this is the right fix for this issue or the problem is how this gets called from Rasterizer::MakeSkiaGpuImage.
Here is a stack trace showing how GrGLGpu::bindSurfaceFBOForPixelOps gets called in my case:
* frame #0: 0x00007ffff6ac4d58 libflutter_linux_gtk.so`GrGLGpu::bindSurfaceFBOForPixelOps(this=0x00000000015e7bb0, surface=0x0000000002556160, mipLevel=0, fboTarget=36160, tempFBOTarget=kSrc_TempFBOTarget) at GrGLGpu.cpp:3085:31
frame #1: 0x00007ffff6ac0af9 libflutter_linux_gtk.so`GrGLGpu::readOrTransferPixelsFrom(this=0x00000000015e7bb0, surface=0x0000000002556160, rect=(fLeft = 0, fTop = 0, fRight = 1200, fBottom = 720), surfaceColorType=kRGBA_8888, dstColorType=kRGBA_8888, offsetOrPtr=0x00000000031582c0, rowWidthInPixels=1200) at GrGLGpu.cpp:2304:15
frame #2: 0x00007ffff6acabf1 libflutter_linux_gtk.so`GrGLGpu::onReadPixels(this=0x00000000015e7bb0, surface=0x0000000002556160, rect=(fLeft = 0, fTop = 0, fRight = 1200, fBottom = 720), surfaceColorType=kRGBA_8888, dstColorType=kRGBA_8888, buffer=0x00000000031582c0, rowBytes=4800) at GrGLGpu.cpp:2354:18
frame #3: 0x00007ffff6888a1d libflutter_linux_gtk.so`GrGpu::readPixels(this=0x00000000015e7bb0, surface=0x0000000002556160, rect=(fLeft = 0, fTop = 0, fRight = 1200, fBottom = 720), surfaceColorType=kRGBA_8888, dstColorType=kRGBA_8888, buffer=0x00000000031582c0, rowBytes=4800) at GrGpu.cpp:456:18
frame #4: 0x00007ffff6906d79 libflutter_linux_gtk.so`skgpu::v1::SurfaceContext::readPixels(this=0x00000000012a7160, dContext=0x000000000136c5f0, dst=GrPixmap @ 0x00007fffffffc870, pt=(fX = 0, fY = 0)) at SurfaceContext.cpp:255:37
frame #5: 0x00007ffff6a881d3 libflutter_linux_gtk.so`SkImage_GpuBase::getROPixels(this=0x0000000002550df0, dContext=0x000000000136c5f0, dst=0x00007fffffffcaf0, chint=kAllow_CachingHint) const at SkImage_GpuBase.cpp:147:20
frame #6: 0x00007ffff61ffc08 libflutter_linux_gtk.so`SkBitmapDevice::drawImageRect(this=0x00000000025b2200, image=0x0000000002550df0, src=0x0000000000000000, dst=0x00007fffffffcd78, sampling=0x00007fffffffcf68, paint=0x00007fffffffcdb0, constraint=kFast_SrcRectConstraint) at SkBitmapDevice.cpp:414:24
frame #7: 0x00007ffff623e7d0 libflutter_linux_gtk.so`SkCanvas::onDrawImage2(this=0x00000000012b0600, image=0x0000000002550df0, x=0, y=0, sampling=0x00007fffffffcf68, paint=0x0000000000000000) at SkCanvas.cpp:2336:28
frame #8: 0x00007ffff623ef5a libflutter_linux_gtk.so`SkCanvas::drawImage(this=0x00000000012b0600, image=0x0000000002550df0, x=0, y=0, sampling=0x00007fffffffcf68, paint=0x0000000000000000) at SkCanvas.cpp:2391:11
frame #9: 0x00007ffff6090321 libflutter_linux_gtk.so`SkCanvas::drawImage(this=0x00000000012b0600, image=0x00007fffffffcf80, x=0, y=0, sampling=0x00007fffffffcf68, paint=0x0000000000000000) at SkCanvas.h:1488:15
frame #10: 0x00007ffff610f9d2 libflutter_linux_gtk.so`flutter::DisplayListCanvasDispatcher::drawImage(this=0x00007fffffffd340, image=const sk_sp<flutter::DlImage> @ 0x00007fffffffcfc8, point=(fX = 0, fY = 0), sampling=kLinear, render_with_attributes=false) at display_list_canvas_dispatcher.cc:196:12
frame #11: 0x00007ffff60d6de4 libflutter_linux_gtk.so`flutter::DrawImageOp::dispatch(this=0x00000000025a6100, ctx=0x00007fffffffd020) const at display_list_ops.h:881:1
frame #12: 0x00007ffff60d3767 libflutter_linux_gtk.so`flutter::DisplayList::Dispatch(this=0x00007fffa0750970, dispatcher=0x00007fffffffd340, ptr="J\U00000010", end="", culler=0x00007ffff7f36220) const at display_list.cc:186:7
frame #13: 0x00007ffff60d2fa5 libflutter_linux_gtk.so`flutter::DisplayList::Dispatch(this=0x00007fffa0750970, ctx=0x00007fffffffd340) const at display_list.cc:139:3
frame #14: 0x00007ffff60d3dc9 libflutter_linux_gtk.so`flutter::DisplayList::RenderTo(this=0x00007fffa0750970, canvas=0x00000000012b0600, opacity=1) const at display_list.cc:315:5
frame #15: 0x00007ffff6f9ef03 libflutter_linux_gtk.so`flutter::(anonymous namespace)::MakeBitmapImage(display_list=0x00007fffffffdab8, image_info=0x00007fffa0629a68) at rasterizer.cc:276:17
frame #16: 0x00007ffff6f9ed0e libflutter_linux_gtk.so`flutter::Rasterizer::MakeSkiaGpuImage(this=0x00000000015d6180, display_list=sk_sp<flutter::DisplayList> @ 0x00007fffffffdab8, image_info=0x00007fffa0629a68) at rasterizer.cc:295:10
frame #17: 0x00007ffff73ac846 libflutter_linux_gtk.so`flutter::DlDeferredImageGPUSkia::ImageWrapper::SnapshotDisplayList(this=({...}, {...}))::$_0::operator()() const at display_list_deferred_image_gpu_skia.cc:181:42
frame #18: 0x00007ffff73ac675 libflutter_linux_gtk.so`decltype(__f=({...}, {...}))::$_0&>()()) std::_LIBCPP_ABI_NAMESPACE::__invoke[abi:v15000]<flutter::DlDeferredImageGPUSkia::ImageWrapper::SnapshotDisplayList(std::_LIBCPP_ABI_NAMESPACE::shared_ptr<flutter::LayerTree>)::$_0&>(flutter::DlDeferredImageGPUSkia::ImageWrapper::SnapshotDisplayList(std::_LIBCPP_ABI_NAMESPACE::shared_ptr<flutter::LayerTree>)::$_0&) at invoke.h:403:23
frame #19: 0x00007ffff73ac635 libflutter_linux_gtk.so`void std::_LIBCPP_ABI_NAMESPACE::__invoke_void_return_wrapper<void, true>::__call<flutter::DlDeferredImageGPUSkia::ImageWrapper::SnapshotDisplayList(__args=({...}, {...}))::$_0&>(flutter::DlDeferredImageGPUSkia::ImageWrapper::SnapshotDisplayList(std::_LIBCPP_ABI_NAMESPACE::shared_ptr<flutter::LayerTree>)::$_0&) at invoke.h:488:9
frame #20: 0x00007ffff73ac60d libflutter_linux_gtk.so`std::_LIBCPP_ABI_NAMESPACE::__function::__alloc_func<flutter::DlDeferredImageGPUSkia::ImageWrapper::SnapshotDisplayList(std::_LIBCPP_ABI_NAMESPACE::shared_ptr<flutter::LayerTree>)::$_0, std::_LIBCPP_ABI_NAMESPACE::allocator<flutter::DlDeferredImageGPUSkia::ImageWrapper::SnapshotDisplayList(std::_LIBCPP_ABI_NAMESPACE::shared_ptr<flutter::LayerTree>)::$_0>, void ()>::operator(this=0x00000000021478f8)[abi:v15000]() at function.h:185:16
frame #21: 0x00007ffff73abb69 libflutter_linux_gtk.so`std::_LIBCPP_ABI_NAMESPACE::__function::__func<flutter::DlDeferredImageGPUSkia::ImageWrapper::SnapshotDisplayList(std::_LIBCPP_ABI_NAMESPACE::shared_ptr<flutter::LayerTree>)::$_0, std::_LIBCPP_ABI_NAMESPACE::allocator<flutter::DlDeferredImageGPUSkia::ImageWrapper::SnapshotDisplayList(std::_LIBCPP_ABI_NAMESPACE::shared_ptr<flutter::LayerTree>)::$_0>, void ()>::operator(this=0x00000000021478f0)() at function.h:359:12
frame #22: 0x00007ffff5c3e022 libflutter_linux_gtk.so`std::_LIBCPP_ABI_NAMESPACE::__function::__value_func<void ()>::operator(this=0x00007fffffffdec0)[abi:v15000]() const at function.h:512:16
frame #23: 0x00007ffff5c3dfa5 libflutter_linux_gtk.so`std::_LIBCPP_ABI_NAMESPACE::function<void ()>::operator(this=0x00007fffffffdec0)() const at function.h:1187:12
frame #24: 0x00007ffff607f13a libflutter_linux_gtk.so`flutter::EmbedderTaskRunner::PostTask(this=0x000000000130db00, baton=877) at embedder_task_runner.cc:77:3
frame #25: 0x00007ffff6082c72 libflutter_linux_gtk.so`flutter::EmbedderThreadHost::PostTask(this=0x0000000001417590, runner=19979008, task=877) const at embedder_thread_host.cc:295:25
frame #26: 0x00007ffff6059e5c libflutter_linux_gtk.so`flutter::EmbedderEngine::RunTask(this=0x00000000015bf300, task=0x00007fffa06331a8) at embedder_engine.cc:245:24
frame #27: 0x00007ffff601468c libflutter_linux_gtk.so`::FlutterEngineRunTask(engine=0x00000000015bf300, task=0x00007fffa06331a8) at embedder.cc:2562:62
frame #28: 0x00007ffff5c0a041 libflutter_linux_gtk.so`::fl_engine_execute_task(self=0x00000000012dc010, task=0x00007fffa06331a8) at fl_engine.cc:869:3
frame #29: 0x00007ffff5c3394b libflutter_linux_gtk.so`fl_task_runner_process_expired_tasks_locked(self=0x00000000013318a0) at fl_task_runner.cc:57:5
frame #30: 0x00007ffff5c33b57 libflutter_linux_gtk.so`fl_task_runner_on_expired_timeout(data=0x00000000013318a0) at fl_task_runner.cc:79:3
frame #31: 0x00007ffff26c84c8 libglib-2.0.so.0`___lldb_unnamed_symbol2503 + 40
frame #32: 0x00007ffff26c7cbf libglib-2.0.so.0`g_main_context_dispatch + 415
frame #33: 0x00007ffff271d598 libglib-2.0.so.0`___lldb_unnamed_symbol2790 + 776
frame #34: 0x00007ffff26c4f40 libglib-2.0.so.0`g_main_context_iteration + 48
frame #35: 0x00007ffff28f394d libgio-2.0.so.0`g_application_run + 477
frame #36: 0x0000000000402561 xxx_app`main(argc=1, argv=0x00007fffffffe398) at main.cc:5:10
frame #37: 0x00007ffff216a510 libc.so.6`__libc_start_call_main + 128
frame #38: 0x00007ffff216a5c9 libc.so.6`__libc_start_main@@GLIBC_2.34 + 137
frame #39: 0x0000000000402445 xxx_app`_start + 37
Tested on master branch of Flutter engine and tool. I am using a custom texture widget via fl_texture_registrar_register_texture, thus I am probably triggering a code path that has not been used otherwise.