• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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>
21 #include <SkPictureRecorder.h>
22 #include <SkRefCnt.h>
23 #include <SkStream.h>
24 #include <SkSurface.h>
25 #include "tools/SkSharingProc.h"
26 
27 #include <chrono>
28 #include <mutex>
29 
30 #include "CaptureTimer.h"
31 
32 namespace android {
33 namespace renderengine {
34 namespace skia {
35 
36 using namespace std::chrono_literals;
37 
38 /**
39  * Class that captures frames that are sent to Skia in Render Engine. It sets up
40  * a multi frame capture and writes it into a file on the device. The capture is
41  * done based on a timer.
42  */
43 class SkiaCapture {
44     using Interval = std::chrono::milliseconds;
45 
46 public:
SkiaCapture()47     SkiaCapture() {}
48     virtual ~SkiaCapture();
49     // Called every frame. Normally returns early with screen canvas.
50     // But when capture is enabled, returns an nwaycanvas where commands are also recorded.
51     SkCanvas* tryCapture(SkSurface* surface);
52     // Called at the end of every frame.
53     void endCapture();
54     // Returns whether the capture is running.
isCaptureRunning()55     bool isCaptureRunning() { return mCaptureRunning; }
56 
57     // Offscreen state member variables are private to SkiaCapture, but the allocation
58     // and lifetime is managed by the caller. This enables nested offscreen
59     // captures to occur.
60     struct OffscreenState {
61         std::unique_ptr<SkPictureRecorder> offscreenRecorder;
62         std::unique_ptr<SkNWayCanvas> offscreenCanvas;
63     };
64     SkCanvas* tryOffscreenCapture(SkSurface* surface, OffscreenState* state);
65     uint64_t endOffscreenCapture(OffscreenState* state);
66 
67 private:
68     // Performs the first-frame work of a multi frame SKP capture. Returns true if successful.
69     bool setupMultiFrameCapture();
70 
71     // Closes the recording and serializes sequence to a file.
72     void writeToFile();
73 
74     // Multi frame serialization stream and writer used when serializing more than one frame.
75     std::unique_ptr<SkFILEWStream> mOpenMultiPicStream;
76     sk_sp<SkDocument> mMultiPic;
77     std::unique_ptr<SkSharingSerialContext> mSerialContext;
78     std::unique_ptr<SkNWayCanvas> mNwayCanvas;
79 
80     SkCanvas* mCurrentPageCanvas = nullptr;
81 
82     // Capturing and interval control.
83     bool mCaptureRunning = false;
84     CaptureTimer mTimer;
85     Interval mTimerInterval = 0ms;
86 
87     // Mutex to ensure that a frame in progress when the timer fires is allowed to run to
88     // completion before we write the file to disk.
89     std::mutex mMutex;
90 
91     std::string mCaptureFile;
92 };
93 
94 } // namespace skia
95 } // namespace renderengine
96 } // namespace android
97