1
2 /*
3 * Copyright 2016 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9 #include "include/core/SkSurface.h"
10 #include "include/core/SkTypes.h"
11 #include "tools/window/RasterWindowContext.h"
12 #include "tools/window/android/WindowContextFactory_android.h"
13
14 using skwindow::internal::RasterWindowContext;
15 using skwindow::DisplayParams;
16
17 namespace {
18 class RasterWindowContext_android : public RasterWindowContext {
19 public:
20 RasterWindowContext_android(ANativeWindow*, const DisplayParams& params);
21
22 sk_sp<SkSurface> getBackbufferSurface() override;
23
isValid()24 bool isValid() override { return SkToBool(fNativeWindow); }
25 void resize(int w, int h) override;
26 void setDisplayParams(const DisplayParams& params) override;
27
28 private:
29 void setBuffersGeometry();
30 void onSwapBuffers() override;
31
32 sk_sp<SkSurface> fBackbufferSurface = nullptr;
33 ANativeWindow* fNativeWindow = nullptr;
34 ANativeWindow_Buffer fBuffer;
35 ARect fBounds;
36 };
37
RasterWindowContext_android(ANativeWindow * window,const DisplayParams & params)38 RasterWindowContext_android::RasterWindowContext_android(ANativeWindow* window,
39 const DisplayParams& params)
40 : RasterWindowContext(params) {
41 fNativeWindow = window;
42 fWidth = ANativeWindow_getWidth(fNativeWindow);
43 fHeight = ANativeWindow_getHeight(fNativeWindow);
44 this->setBuffersGeometry();
45 }
46
setBuffersGeometry()47 void RasterWindowContext_android::setBuffersGeometry() {
48 int32_t format = 0;
49 switch(fDisplayParams.fColorType) {
50 case kRGBA_8888_SkColorType:
51 format = WINDOW_FORMAT_RGBA_8888;
52 break;
53 case kRGB_565_SkColorType:
54 format = WINDOW_FORMAT_RGB_565;
55 break;
56 default:
57 SK_ABORT("Unsupported Android color type");
58 }
59 ANativeWindow_setBuffersGeometry(fNativeWindow, fWidth, fHeight, format);
60 }
61
setDisplayParams(const DisplayParams & params)62 void RasterWindowContext_android::setDisplayParams(const DisplayParams& params) {
63 fDisplayParams = params;
64 this->setBuffersGeometry();
65 }
66
resize(int w,int h)67 void RasterWindowContext_android::resize(int w, int h) {
68 fWidth = w;
69 fHeight = h;
70 this->setBuffersGeometry();
71 }
72
getBackbufferSurface()73 sk_sp<SkSurface> RasterWindowContext_android::getBackbufferSurface() {
74 if (nullptr == fBackbufferSurface) {
75 ANativeWindow_lock(fNativeWindow, &fBuffer, &fBounds);
76 const int bytePerPixel = fBuffer.format == WINDOW_FORMAT_RGB_565 ? 2 : 4;
77 SkImageInfo info = SkImageInfo::Make(fWidth, fHeight,
78 fDisplayParams.fColorType,
79 kPremul_SkAlphaType,
80 fDisplayParams.fColorSpace);
81 fBackbufferSurface =
82 SkSurfaces::WrapPixels(info, fBuffer.bits, fBuffer.stride * bytePerPixel, nullptr);
83 }
84 return fBackbufferSurface;
85 }
86
87
onSwapBuffers()88 void RasterWindowContext_android::onSwapBuffers() {
89 ANativeWindow_unlockAndPost(fNativeWindow);
90 fBackbufferSurface.reset(nullptr);
91 }
92 } // anonymous namespace
93
94 namespace skwindow {
MakeRasterForAndroid(ANativeWindow * window,const DisplayParams & params)95 std::unique_ptr<WindowContext> MakeRasterForAndroid(ANativeWindow* window,
96 const DisplayParams& params) {
97 std::unique_ptr<WindowContext> ctx(new RasterWindowContext_android(window, params));
98 if (!ctx->isValid()) {
99 return nullptr;
100 }
101 return ctx;
102 }
103
104 } // namespace skwindow
105