• 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 <SkSurface.h>
23 
24 #include <chrono>
25 #include <mutex>
26 
27 #include "CaptureTimer.h"
28 #include "tools/SkSharingProc.h"
29 
30 namespace android {
31 namespace renderengine {
32 namespace skia {
33 
34 using 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  */
41 class SkiaCapture {
42     using Interval = std::chrono::milliseconds;
43 
44 public:
SkiaCapture()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();
52     // Returns whether the capture is running.
isCaptureRunning()53     bool isCaptureRunning() { return mCaptureRunning; }
54 
55     // 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 
65 private:
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 
78     SkCanvas* mCurrentPageCanvas = nullptr;
79 
80     // Capturing and interval control.
81     bool mCaptureRunning = false;
82     CaptureTimer mTimer;
83     Interval mTimerInterval = 0ms;
84 
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;
88 
89     std::string mCaptureFile;
90 };
91 
92 } // namespace skia
93 } // namespace renderengine
94 } // namespace android
95