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