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 8#include "include/core/SkSurface.h" 9#include "tools/sk_app/RasterWindowContext.h" 10#include "tools/sk_app/unix/WindowContextFactory_unix.h" 11 12using sk_app::RasterWindowContext; 13using sk_app::DisplayParams; 14 15namespace { 16 17class RasterWindowContext_xlib : public RasterWindowContext { 18public: 19 RasterWindowContext_xlib(Display*, XWindow, int width, int height, const DisplayParams&); 20 21 sk_sp<SkSurface> getBackbufferSurface() override; 22 void swapBuffers() override; 23 bool isValid() override { return SkToBool(fWindow); } 24 void resize(int w, int h) override; 25 void setDisplayParams(const DisplayParams& params) override; 26 27protected: 28 sk_sp<SkSurface> fBackbufferSurface; 29 Display* fDisplay; 30 XWindow fWindow; 31 GC fGC; 32 33 using INHERITED = RasterWindowContext; 34}; 35 36RasterWindowContext_xlib::RasterWindowContext_xlib(Display* display, XWindow window, int width, 37 int height, const DisplayParams& params) 38 : INHERITED(params) 39 , fDisplay(display) 40 , fWindow(window) { 41 fGC = XCreateGC(fDisplay, fWindow, 0, nullptr); 42 this->resize(width, height); 43 fWidth = width; 44 fHeight = height; 45} 46 47void RasterWindowContext_xlib::setDisplayParams(const DisplayParams& params) { 48 fDisplayParams = params; 49 XWindowAttributes attrs; 50 XGetWindowAttributes(fDisplay, fWindow, &attrs); 51 this->resize(attrs.width, attrs.height); 52} 53 54void RasterWindowContext_xlib::resize(int w, int h) { 55 SkImageInfo info = SkImageInfo::Make(w, h, fDisplayParams.fColorType, kPremul_SkAlphaType, 56 fDisplayParams.fColorSpace); 57 fBackbufferSurface = SkSurface::MakeRaster(info, &fDisplayParams.fSurfaceProps); 58 59} 60 61sk_sp<SkSurface> RasterWindowContext_xlib::getBackbufferSurface() { return fBackbufferSurface; } 62 63void RasterWindowContext_xlib::swapBuffers() { 64 SkPixmap pm; 65 if (!fBackbufferSurface->peekPixels(&pm)) { 66 return; 67 } 68 int bitsPerPixel = pm.info().bytesPerPixel() * 8; 69 XImage image; 70 memset(&image, 0, sizeof(image)); 71 image.width = pm.width(); 72 image.height = pm.height(); 73 image.format = ZPixmap; 74 image.data = (char*) pm.addr(); 75 image.byte_order = LSBFirst; 76 image.bitmap_unit = bitsPerPixel; 77 image.bitmap_bit_order = LSBFirst; 78 image.bitmap_pad = bitsPerPixel; 79 image.depth = 24; 80 image.bytes_per_line = pm.rowBytes() - pm.width() * pm.info().bytesPerPixel(); 81 image.bits_per_pixel = bitsPerPixel; 82 if (!XInitImage(&image)) { 83 return; 84 } 85 XPutImage(fDisplay, fWindow, fGC, &image, 0, 0, 0, 0, pm.width(), pm.height()); 86} 87 88} // anonymous namespace 89 90namespace sk_app { 91namespace window_context_factory { 92 93std::unique_ptr<WindowContext> MakeRasterForXlib(const XlibWindowInfo& info, 94 const DisplayParams& params) { 95 std::unique_ptr<WindowContext> ctx(new RasterWindowContext_xlib( 96 info.fDisplay, info.fWindow, info.fWidth, info.fHeight, params)); 97 if (!ctx->isValid()) { 98 ctx = nullptr; 99 } 100 return ctx; 101} 102 103} // namespace window_context_factory 104} // namespace sk_app 105