xref: /aosp_15_r20/external/skia/tools/window/unix/RasterWindowContext_unix.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2016 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 #include "tools/window/unix/RasterWindowContext_unix.h"
8 
9 #include "include/core/SkSurface.h"
10 #include "tools/window/RasterWindowContext.h"
11 #include "tools/window/unix/XlibWindowInfo.h"
12 
13 #include <X11/Xlib.h>
14 
15 using skwindow::DisplayParams;
16 using skwindow::internal::RasterWindowContext;
17 
18 namespace {
19 
20 class RasterWindowContext_xlib : public RasterWindowContext {
21 public:
22     RasterWindowContext_xlib(
23             Display*, XWindow, int width, int height, std::unique_ptr<const DisplayParams>);
24 
25     sk_sp<SkSurface> getBackbufferSurface() override;
isValid()26     bool isValid() override { return SkToBool(fWindow); }
27     void resize(int  w, int h) override;
28     void setDisplayParams(std::unique_ptr<const DisplayParams> params) override;
29 
30 protected:
31     void onSwapBuffers() override;
32 
33     sk_sp<SkSurface> fBackbufferSurface;
34     Display* fDisplay;
35     XWindow  fWindow;
36     GC       fGC;
37 };
38 
RasterWindowContext_xlib(Display * display,XWindow window,int width,int height,std::unique_ptr<const DisplayParams> params)39 RasterWindowContext_xlib::RasterWindowContext_xlib(Display* display,
40                                                    XWindow window,
41                                                    int width,
42                                                    int height,
43                                                    std::unique_ptr<const DisplayParams> params)
44         : RasterWindowContext(std::move(params)), fDisplay(display), fWindow(window) {
45     fGC = XCreateGC(fDisplay, fWindow, 0, nullptr);
46     this->resize(width, height);
47     fWidth = width;
48     fHeight = height;
49 }
50 
setDisplayParams(std::unique_ptr<const DisplayParams> params)51 void RasterWindowContext_xlib::setDisplayParams(std::unique_ptr<const DisplayParams> params) {
52     fDisplayParams = std::move(params);
53     XWindowAttributes attrs;
54     XGetWindowAttributes(fDisplay, fWindow, &attrs);
55     this->resize(attrs.width, attrs.height);
56 }
57 
resize(int w,int h)58 void RasterWindowContext_xlib::resize(int  w, int h) {
59     SkImageInfo info = SkImageInfo::Make(
60             w, h, fDisplayParams->colorType(), kPremul_SkAlphaType, fDisplayParams->colorSpace());
61     fBackbufferSurface = SkSurfaces::Raster(info, &fDisplayParams->surfaceProps());
62 }
63 
getBackbufferSurface()64 sk_sp<SkSurface> RasterWindowContext_xlib::getBackbufferSurface() { return fBackbufferSurface; }
65 
onSwapBuffers()66 void RasterWindowContext_xlib::onSwapBuffers() {
67     SkPixmap pm;
68     if (!fBackbufferSurface->peekPixels(&pm)) {
69         return;
70     }
71     int bitsPerPixel = pm.info().bytesPerPixel() * 8;
72     XImage image;
73     memset(&image, 0, sizeof(image));
74     image.width = pm.width();
75     image.height = pm.height();
76     image.format = ZPixmap;
77     image.data = (char*) pm.writable_addr();
78     image.byte_order = LSBFirst;
79     image.bitmap_unit = bitsPerPixel;
80     image.bitmap_bit_order = LSBFirst;
81     image.bitmap_pad = bitsPerPixel;
82     image.depth = 24;
83     image.bytes_per_line = pm.rowBytes() - pm.width() * pm.info().bytesPerPixel();
84     image.bits_per_pixel = bitsPerPixel;
85     if (!XInitImage(&image)) {
86         return;
87     }
88     XPutImage(fDisplay, fWindow, fGC, &image, 0, 0, 0, 0, pm.width(), pm.height());
89 }
90 
91 }  // anonymous namespace
92 
93 namespace skwindow {
94 
MakeRasterForXlib(const XlibWindowInfo & info,std::unique_ptr<const DisplayParams> params)95 std::unique_ptr<WindowContext> MakeRasterForXlib(const XlibWindowInfo& info,
96                                                  std::unique_ptr<const DisplayParams> params) {
97     std::unique_ptr<WindowContext> ctx(new RasterWindowContext_xlib(
98             info.fDisplay, info.fWindow, info.fWidth, info.fHeight, std::move(params)));
99     if (!ctx->isValid()) {
100         ctx = nullptr;
101     }
102     return ctx;
103 }
104 
105 }  // namespace skwindow
106