summaryrefslogtreecommitdiff
path: root/libs/renderengine/include/renderengine/RenderEngine.h
blob: 818d0350c0120937fa7db9fbfa1f09e191cb9ddb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
/*
 * Copyright 2013 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.
 */

#ifndef SF_RENDERENGINE_H_
#define SF_RENDERENGINE_H_

#include <android-base/unique_fd.h>
#include <ftl/future.h>
#include <math/mat4.h>
#include <renderengine/DisplaySettings.h>
#include <renderengine/ExternalTexture.h>
#include <renderengine/LayerSettings.h>
#include <stdint.h>
#include <sys/types.h>
#include <ui/FenceResult.h>
#include <ui/GraphicTypes.h>
#include <ui/Transform.h>

#include <future>
#include <memory>

/**
 * Allows to set RenderEngine backend to GLES (default) or SkiaGL (NOT yet supported).
 */
#define PROPERTY_DEBUG_RENDERENGINE_BACKEND "debug.renderengine.backend"

/**
 * Turns on recording of skia commands in SkiaGL version of the RE. This property
 * defines number of milliseconds for the recording to take place. A non zero value
 * turns on the recording.
 */
#define PROPERTY_DEBUG_RENDERENGINE_CAPTURE_SKIA_MS "debug.renderengine.capture_skia_ms"

/**
 * Set to the most recently saved file once the capture is finished.
 */
#define PROPERTY_DEBUG_RENDERENGINE_CAPTURE_FILENAME "debug.renderengine.capture_filename"

/**
 * Allows recording of Skia drawing commands with systrace.
 */
#define PROPERTY_SKIA_ATRACE_ENABLED "debug.renderengine.skia_atrace_enabled"

struct ANativeWindowBuffer;

namespace android {

class Rect;
class Region;

namespace renderengine {

class ExternalTexture;
class Image;
class Mesh;
class Texture;
struct RenderEngineCreationArgs;

namespace threaded {
class RenderEngineThreaded;
}

namespace impl {
class RenderEngine;
class ExternalTexture;
}

enum class Protection {
    UNPROTECTED = 1,
    PROTECTED = 2,
};

class RenderEngine {
public:
    enum class ContextPriority {
        LOW = 1,
        MEDIUM = 2,
        HIGH = 3,
        REALTIME = 4,
    };

    enum class RenderEngineType {
        SKIA_GL = 3,
        SKIA_GL_THREADED = 4,
        SKIA_VK = 5,
        SKIA_VK_THREADED = 6,
    };

    static std::unique_ptr<RenderEngine> create(const RenderEngineCreationArgs& args);

    virtual ~RenderEngine() = 0;

    // ----- BEGIN DEPRECATED INTERFACE -----
    // This interface, while still in use until a suitable replacement is built,
    // should be considered deprecated, minus some methods which still may be
    // used to support legacy behavior.
    virtual std::future<void> primeCache(bool shouldPrimeUltraHDR) = 0;

    // dump the extension strings. always call the base class.
    virtual void dump(std::string& result) = 0;

    // queries that are required to be thread safe
    virtual size_t getMaxTextureSize() const = 0;
    virtual size_t getMaxViewportDims() const = 0;

    // ----- END DEPRECATED INTERFACE -----

    // ----- BEGIN NEW INTERFACE -----

    // queries that are required to be thread safe
    virtual bool supportsProtectedContent() const = 0;

    // Notify RenderEngine of changes to the dimensions of the active display
    // so that it can configure its internal caches accordingly.
    virtual void onActiveDisplaySizeChanged(ui::Size size) = 0;

    // Renders layers for a particular display via GPU composition. This method
    // should be called for every display that needs to be rendered via the GPU.
    // @param display The display-wide settings that should be applied prior to
    // drawing any layers.
    //
    // Assumptions when calling this method:
    // 1. There is exactly one caller - i.e. multi-threading is not supported.
    // 2. Additional threads may be calling the {bind,cache}ExternalTexture
    // methods above. But the main thread is responsible for holding resources
    // such that Image destruction does not occur while this method is called.
    //
    // TODO(b/136806342): This should behavior should ideally be fixed since
    // the above two assumptions are brittle, as conditional thread safetyness
    // may be insufficient when maximizing rendering performance in the future.
    //
    // @param layers The layers to draw onto the display, in Z-order.
    // @param buffer The buffer which will be drawn to. This buffer will be
    // ready once drawFence fires.
    // @param bufferFence Fence signalling that the buffer is ready to be drawn
    // to.
    // @return A future object of FenceResult indicating whether drawing was
    // successful in async mode.
    virtual ftl::Future<FenceResult> drawLayers(const DisplaySettings& display,
                                                const std::vector<LayerSettings>& layers,
                                                const std::shared_ptr<ExternalTexture>& buffer,
                                                base::unique_fd&& bufferFence);

    // Clean-up method that should be called on the main thread after the
    // drawFence returned by drawLayers fires. This method will free up
    // resources used by the most recently drawn frame. If the frame is still
    // being drawn, then the implementation is free to silently ignore this call.
    virtual void cleanupPostRender() = 0;

    // Returns the priority this context was actually created with. Note: this
    // may not be the same as specified at context creation time, due to
    // implementation limits on the number of contexts that can be created at a
    // specific priority level in the system.
    //
    // This should return a valid EGL context priority enum as described by
    // https://registry.khronos.org/EGL/extensions/IMG/EGL_IMG_context_priority.txt
    // or
    // https://registry.khronos.org/EGL/extensions/NV/EGL_NV_context_priority_realtime.txt
    virtual int getContextPriority() = 0;

    // Returns true if blur was requested in the RenderEngineCreationArgs and the implementation
    // also supports background blur.  If false, no blur will be applied when drawing layers. This
    // query is required to be thread safe.
    virtual bool supportsBackgroundBlur() = 0;

    // Returns the current type of RenderEngine instance that was created.
    // TODO(b/180767535): This is only implemented to allow for backend-specific behavior, which
    // we should not allow in general, so remove this.
    RenderEngineType getRenderEngineType() const { return mRenderEngineType; }

    static void validateInputBufferUsage(const sp<GraphicBuffer>&);
    static void validateOutputBufferUsage(const sp<GraphicBuffer>&);

    // Allows flinger to get the render engine thread id for power management with ADPF
    // Returns the tid of the renderengine thread if it's threaded, and std::nullopt otherwise
    virtual std::optional<pid_t> getRenderEngineTid() const { return std::nullopt; }

    virtual void setEnableTracing(bool /*tracingEnabled*/) {}

protected:
    RenderEngine() : RenderEngine(RenderEngineType::SKIA_GL) {}

    RenderEngine(RenderEngineType type) : mRenderEngineType(type) {}

    // Maps GPU resources for this buffer.
    // Note that work may be deferred to an additional thread, i.e. this call
    // is made asynchronously, but the caller can expect that map/unmap calls
    // are performed in a manner that's conflict serializable, i.e. unmapping
    // a buffer should never occur before binding the buffer if the caller
    // called mapExternalTextureBuffer before calling unmap.
    // Note also that if the buffer contains protected content, then mapping those GPU resources may
    // be deferred until the buffer is really used for drawing. This is because typical SoCs that
    // support protected memory only support a limited amount, so optimisitically mapping protected
    // memory may be too burdensome. If a buffer contains protected content and the RenderEngine
    // implementation supports protected context, then GPU resources may be mapped into both the
    // protected and unprotected contexts.
    // If the buffer may ever be written to by RenderEngine, then isRenderable must be true.
    virtual void mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer, bool isRenderable) = 0;
    // Unmaps GPU resources used by this buffer. This method should be
    // invoked when the caller will no longer hold a reference to a GraphicBuffer
    // and needs to clean up its resources.
    // Note that if there are multiple callers holding onto the same buffer, then the buffer's
    // resources may be internally ref-counted to guard against use-after-free errors. Note that
    // work may be deferred to an additional thread, i.e. this call is expected to be made
    // asynchronously, but the caller can expect that map/unmap calls are performed in a manner
    // that's conflict serializable, i.e. unmap a buffer should never occur before binding the
    // buffer if the caller called mapExternalTextureBuffer before calling unmap.
    virtual void unmapExternalTextureBuffer(sp<GraphicBuffer>&& buffer) = 0;

    // A thread safe query to determine if any post rendering cleanup is necessary.  Returning true
    // is a signal that calling the postRenderCleanup method would be a no-op and that callers can
    // avoid any thread synchronization that may be required by directly calling postRenderCleanup.
    virtual bool canSkipPostRenderCleanup() const = 0;

    friend class impl::ExternalTexture;
    friend class threaded::RenderEngineThreaded;
    friend class RenderEngineTest_cleanupPostRender_cleansUpOnce_Test;
    const RenderEngineType mRenderEngineType;

    // Update protectedContext mode depending on whether or not any layer has a protected buffer.
    void updateProtectedContext(const std::vector<LayerSettings>&,
                                const std::shared_ptr<ExternalTexture>&);

    // Attempt to switch RenderEngine into and out of protectedContext mode
    virtual void useProtectedContext(bool useProtectedContext) = 0;

    virtual void drawLayersInternal(
            const std::shared_ptr<std::promise<FenceResult>>&& resultPromise,
            const DisplaySettings& display, const std::vector<LayerSettings>& layers,
            const std::shared_ptr<ExternalTexture>& buffer, base::unique_fd&& bufferFence) = 0;
};

struct RenderEngineCreationArgs {
    int pixelFormat;
    uint32_t imageCacheSize;
    bool useColorManagement;
    bool enableProtectedContext;
    bool precacheToneMapperShaderOnly;
    bool supportsBackgroundBlur;
    RenderEngine::ContextPriority contextPriority;
    RenderEngine::RenderEngineType renderEngineType;

    struct Builder;

private:
    // must be created by Builder via constructor with full argument list
    RenderEngineCreationArgs(int _pixelFormat, uint32_t _imageCacheSize,
                             bool _enableProtectedContext, bool _precacheToneMapperShaderOnly,
                             bool _supportsBackgroundBlur,
                             RenderEngine::ContextPriority _contextPriority,
                             RenderEngine::RenderEngineType _renderEngineType)
          : pixelFormat(_pixelFormat),
            imageCacheSize(_imageCacheSize),
            enableProtectedContext(_enableProtectedContext),
            precacheToneMapperShaderOnly(_precacheToneMapperShaderOnly),
            supportsBackgroundBlur(_supportsBackgroundBlur),
            contextPriority(_contextPriority),
            renderEngineType(_renderEngineType) {}
    RenderEngineCreationArgs() = delete;
};

struct RenderEngineCreationArgs::Builder {
    Builder() {}

    Builder& setPixelFormat(int pixelFormat) {
        this->pixelFormat = pixelFormat;
        return *this;
    }
    Builder& setImageCacheSize(uint32_t imageCacheSize) {
        this->imageCacheSize = imageCacheSize;
        return *this;
    }
    Builder& setEnableProtectedContext(bool enableProtectedContext) {
        this->enableProtectedContext = enableProtectedContext;
        return *this;
    }
    Builder& setPrecacheToneMapperShaderOnly(bool precacheToneMapperShaderOnly) {
        this->precacheToneMapperShaderOnly = precacheToneMapperShaderOnly;
        return *this;
    }
    Builder& setSupportsBackgroundBlur(bool supportsBackgroundBlur) {
        this->supportsBackgroundBlur = supportsBackgroundBlur;
        return *this;
    }
    Builder& setContextPriority(RenderEngine::ContextPriority contextPriority) {
        this->contextPriority = contextPriority;
        return *this;
    }
    Builder& setRenderEngineType(RenderEngine::RenderEngineType renderEngineType) {
        this->renderEngineType = renderEngineType;
        return *this;
    }
    RenderEngineCreationArgs build() const {
        return RenderEngineCreationArgs(pixelFormat, imageCacheSize, enableProtectedContext,
                                        precacheToneMapperShaderOnly, supportsBackgroundBlur,
                                        contextPriority, renderEngineType);
    }

private:
    // 1 means RGBA_8888
    int pixelFormat = 1;
    uint32_t imageCacheSize = 0;
    bool enableProtectedContext = false;
    bool precacheToneMapperShaderOnly = false;
    bool supportsBackgroundBlur = false;
    RenderEngine::ContextPriority contextPriority = RenderEngine::ContextPriority::MEDIUM;
    RenderEngine::RenderEngineType renderEngineType =
            RenderEngine::RenderEngineType::SKIA_GL_THREADED;
};

} // namespace renderengine
} // namespace android

#endif /* SF_RENDERENGINE_H_ */