1 // Copyright 2019 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 5 #ifndef UI_BASE_X_X11_SHM_IMAGE_POOL_H_ 6 #define UI_BASE_X_X11_SHM_IMAGE_POOL_H_ 7 8 #include <cstring> 9 #include <list> 10 #include <vector> 11 12 #include "base/callback_forward.h" 13 #include "base/component_export.h" 14 #include "base/macros.h" 15 #include "base/memory/ref_counted.h" 16 #include "base/sequence_checker.h" 17 #include "third_party/skia/include/core/SkBitmap.h" 18 #include "third_party/skia/include/core/SkCanvas.h" 19 #include "ui/base/x/x11_util.h" 20 #include "ui/events/platform/x11/x11_event_source.h" 21 #include "ui/gfx/geometry/size.h" 22 #include "ui/gfx/x/event.h" 23 #include "ui/gfx/x/shm.h" 24 25 namespace ui { 26 27 // Creates XImages backed by shared memory that will be shared with the X11 28 // server for processing. COMPONENT_EXPORT(UI_BASE_X)29class COMPONENT_EXPORT(UI_BASE_X) XShmImagePool : public XEventDispatcher { 30 public: 31 XShmImagePool(x11::Connection* connection, 32 x11::Drawable drawable, 33 x11::VisualId visual, 34 int depth, 35 std::size_t max_frames_pending, 36 bool enable_multibuffering); 37 38 ~XShmImagePool() override; 39 40 bool Resize(const gfx::Size& pixel_size); 41 42 // Is XSHM supported by the server and are the shared buffers ready for use? 43 bool Ready(); 44 45 // Obtain state for the current frame. 46 SkBitmap& CurrentBitmap(); 47 SkCanvas* CurrentCanvas(); 48 x11::Shm::Seg CurrentSegment(); 49 50 // Switch to the next cached frame. CurrentBitmap() and CurrentImage() will 51 // change to reflect the new frame. 52 void SwapBuffers(base::OnceCallback<void(const gfx::Size&)> callback); 53 54 protected: 55 void DispatchShmCompletionEvent(x11::Shm::CompletionEvent event); 56 57 private: 58 friend class base::RefCountedThreadSafe<XShmImagePool>; 59 60 struct FrameState { 61 FrameState(); 62 ~FrameState(); 63 64 x11::Shm::Seg shmseg{}; 65 int shmid = 0; 66 void* shmaddr = nullptr; 67 bool shmem_attached_to_server = false; 68 SkBitmap bitmap; 69 std::unique_ptr<SkCanvas> canvas; 70 }; 71 72 struct SwapClosure { 73 SwapClosure(); 74 ~SwapClosure(); 75 76 base::OnceClosure closure; 77 x11::Shm::Seg shmseg{}; 78 }; 79 80 // XEventDispatcher: 81 bool DispatchXEvent(x11::Event* xev) override; 82 83 void Cleanup(); 84 85 x11::Connection* const connection_; 86 const x11::Drawable drawable_; 87 const x11::VisualId visual_; 88 const int depth_; 89 const bool enable_multibuffering_; 90 91 bool ready_ = false; 92 gfx::Size pixel_size_; 93 std::size_t frame_bytes_ = 0; 94 std::vector<FrameState> frame_states_; 95 std::size_t current_frame_index_ = 0; 96 std::list<SwapClosure> swap_closures_; 97 98 SEQUENCE_CHECKER(sequence_checker_); 99 100 DISALLOW_COPY_AND_ASSIGN(XShmImagePool); 101 }; 102 103 } // namespace ui 104 105 #endif // UI_BASE_X_X11_SHM_IMAGE_POOL_H_ 106