Flutter Engine
The Flutter Engine
screenshot.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "screenshot.h"
6
7#include <lib/zx/vmar.h>
8
9#include <map>
10#include <ostream>
11#include <utility>
12#include <vector>
13
14#include "flutter/fml/logging.h"
15
16namespace fuchsia_test_utils {
17namespace {
18constexpr uint64_t kBytesPerPixel = 4;
19} // namespace
20
21Screenshot::Screenshot(const zx::vmo& screenshot_vmo,
22 uint64_t width,
23 uint64_t height,
24 int rotation)
25 : width_(width), height_(height) {
26 FML_CHECK(rotation == 0 || rotation == 90 || rotation == 270);
27 if (rotation == 90 || rotation == 270) {
28 std::swap(width_, height_);
29 }
30 // Populate |screenshot_| from |screenshot_vmo|.
31 uint64_t vmo_size;
32 screenshot_vmo.get_prop_content_size(&vmo_size);
33 FML_CHECK(vmo_size == kBytesPerPixel * width_ * height_);
34 uint8_t* vmo_host = nullptr;
35 auto status = zx::vmar::root_self()->map(
36 ZX_VM_PERM_READ, /*vmar_offset*/ 0, screenshot_vmo,
37 /*vmo_offset*/ 0, vmo_size, reinterpret_cast<uintptr_t*>(&vmo_host));
38 FML_CHECK(status == ZX_OK);
39 ExtractScreenshotFromVMO(vmo_host);
40 // map the pointer.
41 uintptr_t address = reinterpret_cast<uintptr_t>(vmo_host);
42 status = zx::vmar::root_self()->unmap(address, vmo_size);
43 FML_CHECK(status == ZX_OK);
44}
45
46std::ostream& operator<<(std::ostream& stream, const Pixel& pixel) {
47 return stream << "{Pixel:" << " r:" << static_cast<unsigned int>(pixel.red)
48 << " g:" << static_cast<unsigned int>(pixel.green)
49 << " b:" << static_cast<unsigned int>(pixel.blue)
50 << " a:" << static_cast<unsigned int>(pixel.alpha) << "}";
51}
52
53Pixel Screenshot::GetPixelAt(uint64_t x, uint64_t y) const {
54 FML_CHECK(x >= 0 && x < width_ && y >= 0 && y < height_)
55 << "Index out of bounds";
56 return screenshot_[y][x];
57}
58
59std::map<Pixel, uint32_t> Screenshot::Histogram() const {
60 std::map<Pixel, uint32_t> histogram;
61 FML_CHECK(screenshot_.size() == height_ && screenshot_[0].size() == width_);
62 for (size_t i = 0; i < height_; i++) {
63 for (size_t j = 0; j < width_; j++) {
64 histogram[screenshot_[i][j]]++;
65 }
66 }
67 return histogram;
68}
69
70void Screenshot::ExtractScreenshotFromVMO(uint8_t* screenshot_vmo) {
71 FML_CHECK(screenshot_vmo);
72 for (size_t i = 0; i < height_; i++) {
73 // The head index of the ith row in the screenshot is |i* width_*
74 // KbytesPerPixel|.
75 screenshot_.push_back(GetPixelsInRow(screenshot_vmo, i));
76 }
77}
78
79std::vector<Pixel> Screenshot::GetPixelsInRow(uint8_t* screenshot_vmo,
80 size_t row_index) {
81 std::vector<Pixel> row;
82 for (size_t col_idx = 0;
83 col_idx < static_cast<size_t>(width_ * kBytesPerPixel);
84 col_idx += kBytesPerPixel) {
85 // Each row in the screenshot has |kBytesPerPixel * width_| elements.
86 // Therefore in order to reach the first pixel of the |row_index| row, we
87 // have to jump |row_index * width_ * kBytesPerPixel| positions.
88 auto pixel_start_index = row_index * width_ * kBytesPerPixel;
89 // Every |kBytesPerPixel| bytes represents the BGRA values of a pixel. Skip
90 // |kBytesPerPixel| bytes to get to the BGRA values of the next pixel. Each
91 // row in a screenshot has |kBytesPerPixel * width_| bytes of data.
92 // Example:-
93 // auto data = TakeScreenshot();
94 // data[0-3] -> RGBA of pixel 0.
95 // data[4-7] -> RGBA pf pixel 1.
96 row.emplace_back(screenshot_vmo[pixel_start_index + col_idx],
97 screenshot_vmo[pixel_start_index + col_idx + 1],
98 screenshot_vmo[pixel_start_index + col_idx + 2],
99 screenshot_vmo[pixel_start_index + col_idx + 3]);
100 }
101 return row;
102}
103
104} // namespace fuchsia_test_utils
void swap(sk_sp< T > &a, sk_sp< T > &b)
Definition: SkRefCnt.h:341
Screenshot(const zx::vmo &screenshot_vmo, uint64_t width, uint64_t height, int rotation)
Definition: screenshot.cc:21
Pixel GetPixelAt(uint64_t x, uint64_t y) const
Definition: screenshot.cc:53
std::map< Pixel, uint32_t > Histogram() const
Definition: screenshot.cc:59
#define FML_CHECK(condition)
Definition: logging.h:85
double y
double x
std::ostream & operator<<(std::ostream &stream, const Pixel &pixel)
Definition: screenshot.cc:46
int32_t height
int32_t width