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 "../RasterWindowContext.h" 9 #include "SkAutoMalloc.h" 10 #include "SkSurface.h" 11 #include "WindowContextFactory_win.h" 12 13 #include <Windows.h> 14 15 using sk_app::RasterWindowContext; 16 using sk_app::DisplayParams; 17 18 namespace { 19 20 class RasterWindowContext_win : public RasterWindowContext { 21 public: 22 RasterWindowContext_win(HWND, const DisplayParams&); 23 24 sk_sp<SkSurface> getBackbufferSurface() override; 25 void swapBuffers() override; 26 bool isValid() override { return SkToBool(fWnd); } 27 void resize(int w, int h) override; 28 void setDisplayParams(const DisplayParams& params) override; 29 30 protected: 31 SkAutoMalloc fSurfaceMemory; 32 sk_sp<SkSurface> fBackbufferSurface; 33 HWND fWnd; 34 35 private: 36 typedef RasterWindowContext INHERITED; 37 }; 38 39 RasterWindowContext_win::RasterWindowContext_win(HWND wnd, const DisplayParams& params) 40 : INHERITED(params) 41 , fWnd(wnd) { 42 RECT rect; 43 GetClientRect(wnd, &rect); 44 this->resize(rect.right - rect.left, rect.bottom - rect.top); 45 } 46 47 void RasterWindowContext_win::setDisplayParams(const DisplayParams& params) { 48 fDisplayParams = params; 49 RECT rect; 50 GetClientRect(fWnd, &rect); 51 this->resize(rect.right - rect.left, rect.bottom - rect.top); 52 } 53 54 void RasterWindowContext_win::resize(int w, int h) { 55 fWidth = w; 56 fHeight = h; 57 fBackbufferSurface.reset(); 58 const size_t bmpSize = sizeof(BITMAPINFOHEADER) + w * h * sizeof(uint32_t); 59 fSurfaceMemory.reset(bmpSize); 60 BITMAPINFO* bmpInfo = reinterpret_cast<BITMAPINFO*>(fSurfaceMemory.get()); 61 ZeroMemory(bmpInfo, sizeof(BITMAPINFO)); 62 bmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 63 bmpInfo->bmiHeader.biWidth = w; 64 bmpInfo->bmiHeader.biHeight = -h; // negative means top-down bitmap. Skia draws top-down. 65 bmpInfo->bmiHeader.biPlanes = 1; 66 bmpInfo->bmiHeader.biBitCount = 32; 67 bmpInfo->bmiHeader.biCompression = BI_RGB; 68 void* pixels = bmpInfo->bmiColors; 69 70 SkImageInfo info = SkImageInfo::Make(w, h, fDisplayParams.fColorType, kPremul_SkAlphaType, 71 fDisplayParams.fColorSpace); 72 fBackbufferSurface = SkSurface::MakeRasterDirect(info, pixels, sizeof(uint32_t) * w); 73 } 74 75 sk_sp<SkSurface> RasterWindowContext_win::getBackbufferSurface() { return fBackbufferSurface; } 76 77 void RasterWindowContext_win::swapBuffers() { 78 BITMAPINFO* bmpInfo = reinterpret_cast<BITMAPINFO*>(fSurfaceMemory.get()); 79 HDC dc = GetDC(fWnd); 80 StretchDIBits(dc, 0, 0, fWidth, fHeight, 0, 0, fWidth, fHeight, bmpInfo->bmiColors, bmpInfo, 81 DIB_RGB_COLORS, SRCCOPY); 82 ReleaseDC(fWnd, dc); 83 } 84 85 } // anonymous namespace 86 87 namespace sk_app { 88 namespace window_context_factory { 89 90 WindowContext* NewRasterForWin(HWND wnd, const DisplayParams& params) { 91 WindowContext* ctx = new RasterWindowContext_win(wnd, params); 92 if (!ctx->isValid()) { 93 delete ctx; 94 ctx = nullptr; 95 } 96 return ctx; 97 } 98 99 } // namespace window_context_factory 100 } // namespace sk_app 101