blob: 5e18e60f937772d1229a17cbff4ba5ff57d1b2f2 [file] [log] [blame]
Ana Krulec70d15b1b2020-12-01 10:05:15 -08001/*
2 * Copyright 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#include <SkDocument.h>
20#include <SkNWayCanvas.h>
Derek Sollenberger76664d62021-02-04 11:13:09 -050021#include <SkPictureRecorder.h>
Ana Krulec70d15b1b2020-12-01 10:05:15 -080022#include <SkSurface.h>
Derek Sollenberger76664d62021-02-04 11:13:09 -050023
Ana Krulec70d15b1b2020-12-01 10:05:15 -080024#include <chrono>
Derek Sollenberger76664d62021-02-04 11:13:09 -050025#include <mutex>
26
Ana Krulec70d15b1b2020-12-01 10:05:15 -080027#include "CaptureTimer.h"
28#include "tools/SkSharingProc.h"
29
30namespace android {
31namespace renderengine {
32namespace skia {
33
34using namespace std::chrono_literals;
35
36/**
37 * Class that captures frames that are sent to Skia in Render Engine. It sets up
38 * a multi frame capture and writes it into a file on the device. The capture is
39 * done based on a timer.
40 */
41class SkiaCapture {
42 using Interval = std::chrono::milliseconds;
43
44public:
45 SkiaCapture() {}
46 virtual ~SkiaCapture();
47 // Called every frame. Normally returns early with screen canvas.
48 // But when capture is enabled, returns an nwaycanvas where commands are also recorded.
49 SkCanvas* tryCapture(SkSurface* surface);
50 // Called at the end of every frame.
51 void endCapture();
Ana Krulec6eab17a2020-12-09 15:52:36 -080052 // Returns whether the capture is running.
53 bool isCaptureRunning() { return mCaptureRunning; }
Ana Krulec70d15b1b2020-12-01 10:05:15 -080054
Derek Sollenberger76664d62021-02-04 11:13:09 -050055 // Offscreen state member variables are private to SkiaCapture, but the allocation
56 // and lifetime is managed by the caller. This enables nested offscreen
57 // captures to occur.
58 struct OffscreenState {
59 std::unique_ptr<SkPictureRecorder> offscreenRecorder;
60 std::unique_ptr<SkNWayCanvas> offscreenCanvas;
61 };
62 SkCanvas* tryOffscreenCapture(SkSurface* surface, OffscreenState* state);
63 uint64_t endOffscreenCapture(OffscreenState* state);
64
Ana Krulec70d15b1b2020-12-01 10:05:15 -080065private:
66 // Performs the first-frame work of a multi frame SKP capture. Returns true if successful.
67 bool setupMultiFrameCapture();
68
69 // Closes the recording and serializes sequence to a file.
70 void writeToFile();
71
72 // Multi frame serialization stream and writer used when serializing more than one frame.
73 std::unique_ptr<SkFILEWStream> mOpenMultiPicStream;
74 sk_sp<SkDocument> mMultiPic;
75 std::unique_ptr<SkSharingSerialContext> mSerialContext;
76 std::unique_ptr<SkNWayCanvas> mNwayCanvas;
77
Greg Kaisere5f84262021-02-16 06:57:36 -080078 SkCanvas* mCurrentPageCanvas = nullptr;
Derek Sollenberger76664d62021-02-04 11:13:09 -050079
Ana Krulec70d15b1b2020-12-01 10:05:15 -080080 // Capturing and interval control.
81 bool mCaptureRunning = false;
82 CaptureTimer mTimer;
83 Interval mTimerInterval = 0ms;
Derek Sollenberger76664d62021-02-04 11:13:09 -050084
85 // Mutex to ensure that a frame in progress when the timer fires is allowed to run to
86 // completion before we write the file to disk.
87 std::mutex mMutex;
Ana Krulec70d15b1b2020-12-01 10:05:15 -080088};
89
90} // namespace skia
91} // namespace renderengine
92} // namespace android