| /* | |
| * Copyright 2016 Google Inc. | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #include "include/core/SkSurface.h" | |
| #include "include/private/SkLog.h" | |
| #include "src/core/SkAutoMalloc.h" | |
| #include "tools/window/RasterWindowContext.h" | |
| #include "tools/window/win/WindowContextFactory_win.h" | |
| #include <Windows.h> | |
| using skwindow::DisplayParams; | |
| using skwindow::internal::RasterWindowContext; | |
| namespace { | |
| class RasterWindowContext_win : public RasterWindowContext { | |
| public: | |
| RasterWindowContext_win(HWND, std::unique_ptr<const DisplayParams>); | |
| sk_sp<SkSurface> getBackbufferSurface() override; | |
| bool isValid() override { return SkToBool(fWnd); } | |
| void resize(int w, int h) override; | |
| void setDisplayParams(std::unique_ptr<const DisplayParams> params) override; | |
| protected: | |
| void onSwapBuffers() override; | |
| SkAutoMalloc fSurfaceMemory; | |
| sk_sp<SkSurface> fBackbufferSurface; | |
| HWND fWnd; | |
| }; | |
| RasterWindowContext_win::RasterWindowContext_win(HWND wnd, | |
| std::unique_ptr<const DisplayParams> params) | |
| : RasterWindowContext(std::move(params)), fWnd(wnd) { | |
| RECT rect; | |
| GetClientRect(wnd, &rect); | |
| this->resize(rect.right - rect.left, rect.bottom - rect.top); | |
| } | |
| void RasterWindowContext_win::setDisplayParams(std::unique_ptr<const DisplayParams> params) { | |
| fDisplayParams = std::move(params); | |
| RECT rect; | |
| GetClientRect(fWnd, &rect); | |
| this->resize(rect.right - rect.left, rect.bottom - rect.top); | |
| } | |
| void RasterWindowContext_win::resize(int w, int h) { | |
| fWidth = w; | |
| fHeight = h; | |
| fBackbufferSurface.reset(); | |
| const size_t bmpSize = sizeof(BITMAPINFOHEADER) + w * h * sizeof(uint32_t); | |
| fSurfaceMemory.reset(bmpSize); | |
| BITMAPINFO* bmpInfo = reinterpret_cast<BITMAPINFO*>(fSurfaceMemory.get()); | |
| ZeroMemory(bmpInfo, sizeof(BITMAPINFO)); | |
| bmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); | |
| bmpInfo->bmiHeader.biWidth = w; | |
| bmpInfo->bmiHeader.biHeight = -h; // negative means top-down bitmap. Skia draws top-down. | |
| bmpInfo->bmiHeader.biPlanes = 1; | |
| bmpInfo->bmiHeader.biBitCount = 32; | |
| bmpInfo->bmiHeader.biCompression = BI_RGB; | |
| void* pixels = bmpInfo->bmiColors; | |
| SkImageInfo info = SkImageInfo::Make( | |
| w, h, fDisplayParams->colorType(), kPremul_SkAlphaType, fDisplayParams->colorSpace()); | |
| fBackbufferSurface = SkSurfaces::WrapPixels(info, pixels, sizeof(uint32_t) * w); | |
| } | |
| sk_sp<SkSurface> RasterWindowContext_win::getBackbufferSurface() { return fBackbufferSurface; } | |
| void RasterWindowContext_win::onSwapBuffers() { | |
| BITMAPINFO* bmpInfo = reinterpret_cast<BITMAPINFO*>(fSurfaceMemory.get()); | |
| HDC dc = GetDC(fWnd); | |
| StretchDIBits(dc, 0, 0, fWidth, fHeight, 0, 0, fWidth, fHeight, bmpInfo->bmiColors, bmpInfo, | |
| DIB_RGB_COLORS, SRCCOPY); | |
| ReleaseDC(fWnd, dc); | |
| } | |
| } // anonymous namespace | |
| namespace skwindow { | |
| std::unique_ptr<WindowContext> MakeRasterForWin(HWND wnd, | |
| std::unique_ptr<const DisplayParams> params) { | |
| std::unique_ptr<WindowContext> ctx(new RasterWindowContext_win(wnd, std::move(params))); | |
| if (!ctx->isValid()) { | |
| SKIA_LOG_D("Invalid raster context for Windows"); | |
| return nullptr; | |
| } | |
| return ctx; | |
| } | |
| } // namespace skwindow |