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