blob: bc8a5659dd83cbaae902335645db107283f5771b [file] [log] [blame]
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <SkSurface.h>
#include <SkDocument.h>
#include <SkMultiPictureDocument.h>
#include "Lighting.h"
#include "hwui/AnimatedImageDrawable.h"
#include "renderthread/CanvasContext.h"
#include "renderthread/IRenderPipeline.h"
class SkPictureRecorder;
struct SkSharingSerialContext;
namespace android {
namespace uirenderer {
namespace skiapipeline {
class SkiaPipeline : public renderthread::IRenderPipeline {
public:
explicit SkiaPipeline(renderthread::RenderThread& thread);
virtual ~SkiaPipeline();
void onDestroyHardwareResources() override;
bool pinImages(std::vector<SkImage*>& mutableImages) override;
bool pinImages(LsaVector<sk_sp<Bitmap>>& images) override { return false; }
void unpinImages() override;
void renderLayers(const LightGeometry& lightGeometry, LayerUpdateQueue* layerUpdateQueue,
bool opaque, const LightInfo& lightInfo) override;
// If the given node didn't have a layer surface, or had one of the wrong size, this method
// creates a new one and returns true. Otherwise does nothing and returns false.
bool createOrUpdateLayer(RenderNode* node, const DamageAccumulator& damageAccumulator,
ErrorHandler* errorHandler) override;
void setSurfaceColorProperties(ColorMode colorMode) override;
SkColorType getSurfaceColorType() const override { return mSurfaceColorType; }
sk_sp<SkColorSpace> getSurfaceColorSpace() override { return mSurfaceColorSpace; }
void renderFrame(const LayerUpdateQueue& layers, const SkRect& clip,
const std::vector<sp<RenderNode>>& nodes, bool opaque,
const Rect& contentDrawBounds, sk_sp<SkSurface> surface,
const SkMatrix& preTransform);
static void prepareToDraw(const renderthread::RenderThread& thread, Bitmap* bitmap);
void renderLayersImpl(const LayerUpdateQueue& layers, bool opaque);
// Sets the recording callback to the provided function and the recording mode
// to CallbackAPI
void setPictureCapturedCallback(
const std::function<void(sk_sp<SkPicture>&&)>& callback) override {
mPictureCapturedCallback = callback;
mCaptureMode = callback ? CaptureMode::CallbackAPI : CaptureMode::None;
}
protected:
void dumpResourceCacheUsage() const;
renderthread::RenderThread& mRenderThread;
ColorMode mColorMode = ColorMode::Default;
SkColorType mSurfaceColorType;
sk_sp<SkColorSpace> mSurfaceColorSpace;
bool isCapturingSkp() const { return mCaptureMode != CaptureMode::None; }
private:
void renderFrameImpl(const SkRect& clip,
const std::vector<sp<RenderNode>>& nodes, bool opaque,
const Rect& contentDrawBounds, SkCanvas* canvas,
const SkMatrix& preTransform);
/**
* Debugging feature. Draws a semi-transparent overlay on each pixel, indicating
* how many times it has been drawn.
*/
void renderOverdraw(const SkRect& clip,
const std::vector<sp<RenderNode>>& nodes, const Rect& contentDrawBounds,
sk_sp<SkSurface> surface, const SkMatrix& preTransform);
// Called every frame. Normally returns early with screen canvas.
// But when capture is enabled, returns an nwaycanvas where commands are also recorded.
SkCanvas* tryCapture(SkSurface* surface, RenderNode* root, const LayerUpdateQueue& dirtyLayers);
// Called at the end of every frame, closes the recording if necessary.
void endCapture(SkSurface* surface);
// Determine if a new file-based capture should be started.
// If so, sets mCapturedFile and mCaptureSequence and returns true.
// Should be called every frame when capture is enabled.
// sets mCaptureMode.
bool shouldStartNewFileCapture();
// Set up a multi frame capture.
bool setupMultiFrameCapture();
std::vector<sk_sp<SkImage>> mPinnedImages;
// Block of properties used only for debugging to record a SkPicture and save it in a file.
// There are three possible ways of recording drawing commands.
enum class CaptureMode {
// return to this mode when capture stops.
None,
// A mode where every frame is recorded into an SkPicture and sent to a provided callback,
// until that callback is cleared
CallbackAPI,
// A mode where a finite number of frames are recorded to a file with
// SkMultiPictureDocument
MultiFrameSKP,
// A mode which records a single frame to a normal SKP file.
SingleFrameSKP,
};
CaptureMode mCaptureMode = CaptureMode::None;
/**
* mCapturedFile - the filename to write a recorded SKP to in either MultiFrameSKP or
* SingleFrameSKP mode.
*/
std::string mCapturedFile;
/**
* mCaptureSequence counts down how many frames are left to take in the sequence. Applicable
* only to MultiFrameSKP or SingleFrameSKP mode.
*/
int mCaptureSequence = 0;
// Multi frame serialization stream and writer used when serializing more than one frame.
std::unique_ptr<SkSharingSerialContext> mSerialContext; // Must be declared before any other
// serializing member
std::unique_ptr<SkFILEWStream> mOpenMultiPicStream;
sk_sp<SkDocument> mMultiPic;
/**
* mRecorder holds the current picture recorder when serializing in either SingleFrameSKP or
* CallbackAPI modes.
*/
std::unique_ptr<SkPictureRecorder> mRecorder;
std::unique_ptr<SkNWayCanvas> mNwayCanvas;
// Set by setPictureCapturedCallback and when set, CallbackAPI mode recording is ongoing.
// Not used in other recording modes.
std::function<void(sk_sp<SkPicture>&&)> mPictureCapturedCallback;
};
} /* namespace skiapipeline */
} /* namespace uirenderer */
} /* namespace android */