gl_context_glx_unittest.cc 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "ui/gl/gl_context_glx.h"
  5. #include "base/memory/scoped_refptr.h"
  6. #include "testing/gtest/include/gtest/gtest.h"
  7. #include "ui/gfx/x/connection.h"
  8. #include "ui/gfx/x/future.h"
  9. #include "ui/gfx/x/xproto.h"
  10. #include "ui/gl/gl_bindings.h"
  11. #include "ui/gl/gl_surface_glx_x11.h"
  12. #include "ui/gl/init/gl_factory.h"
  13. #include "ui/gl/test/gl_image_test_support.h"
  14. namespace gl {
  15. #if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
  16. defined(THREAD_SANITIZER)
  17. // https://crbug.com/830653
  18. #define MAYBE_DoNotDestroyOnFailedMakeCurrent \
  19. DISABLED_DoNotDestroyOnFailedMakeCurrent
  20. #else
  21. #define MAYBE_DoNotDestroyOnFailedMakeCurrent DoNotDestroyOnFailedMakeCurrent
  22. #endif
  23. TEST(GLContextGLXTest, MAYBE_DoNotDestroyOnFailedMakeCurrent) {
  24. auto* connection = x11::Connection::Get();
  25. ASSERT_TRUE(connection && connection->Ready());
  26. auto xwindow = connection->GenerateId<x11::Window>();
  27. connection->CreateWindow({
  28. .wid = xwindow,
  29. .parent = connection->default_root(),
  30. .width = 10,
  31. .height = 10,
  32. .c_class = x11::WindowClass::InputOutput,
  33. .background_pixmap = x11::Pixmap::None,
  34. .override_redirect = x11::Bool32(true),
  35. });
  36. connection->MapWindow({xwindow});
  37. // Since this window is override-redirect, syncing is sufficient
  38. // to ensure the map is complete.
  39. connection->Sync();
  40. GLImageTestSupport::InitializeGL(absl::nullopt);
  41. auto surface = gl::InitializeGLSurface(base::MakeRefCounted<GLSurfaceGLXX11>(
  42. static_cast<gfx::AcceleratedWidget>(xwindow)));
  43. scoped_refptr<GLContext> context =
  44. gl::init::CreateGLContext(nullptr, surface.get(), GLContextAttribs());
  45. // Verify that MakeCurrent() is successful.
  46. ASSERT_TRUE(context->GetHandle());
  47. ASSERT_TRUE(context->MakeCurrent(surface.get()));
  48. EXPECT_TRUE(context->GetHandle());
  49. context->ReleaseCurrent(surface.get());
  50. connection->DestroyWindow({xwindow});
  51. // Since this window is override-redirect, syncing is sufficient
  52. // to ensure the window is destroyed and unmapped.
  53. connection->Sync();
  54. ASSERT_TRUE(connection->Ready());
  55. if (context->MakeCurrent(surface.get())) {
  56. // With some drivers, MakeCurrent() does not fail for an already-destroyed
  57. // window. In those cases, override the glx api to force MakeCurrent() to
  58. // fail.
  59. context->ReleaseCurrent(surface.get());
  60. auto real_fn = g_driver_glx.fn.glXMakeContextCurrentFn;
  61. g_driver_glx.fn.glXMakeContextCurrentFn =
  62. [](Display* display, GLXDrawable drawable, GLXDrawable read,
  63. GLXContext context) -> int { return 0; };
  64. EXPECT_FALSE(context->MakeCurrent(surface.get()));
  65. g_driver_glx.fn.glXMakeContextCurrentFn = real_fn;
  66. }
  67. // At this point, MakeCurrent() failed. Make sure the GLContextGLX still was
  68. // not destroyed.
  69. ASSERT_TRUE(context->GetHandle());
  70. surface = nullptr;
  71. connection->Sync();
  72. connection->events().clear();
  73. }
  74. } // namespace gl