RecordedOp.h revision 0b7e8245db728d127ada698be63d78b33fc6e4da
1/* 2 * Copyright (C) 2015 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#ifndef ANDROID_HWUI_RECORDED_OP_H 18#define ANDROID_HWUI_RECORDED_OP_H 19 20#include "utils/LinearAllocator.h" 21#include "Rect.h" 22#include "Matrix.h" 23#include "RenderNode.h" 24 25#include "SkXfermode.h" 26 27class SkBitmap; 28class SkPaint; 29 30namespace android { 31namespace uirenderer { 32 33class OffscreenBuffer; 34class RenderNode; 35struct Vertex; 36 37/** 38 * The provided macro is executed for each op type in order, with the results separated by commas. 39 * 40 * This serves as the authoritative list of ops, used for generating ID enum, and ID based LUTs. 41 */ 42#define MAP_OPS(OP_FN) \ 43 OP_FN(BitmapOp) \ 44 OP_FN(RectOp) \ 45 OP_FN(RenderNodeOp) \ 46 OP_FN(SimpleRectsOp) \ 47 OP_FN(BeginLayerOp) \ 48 OP_FN(EndLayerOp) \ 49 OP_FN(LayerOp) 50 51// Generate OpId enum 52#define IDENTITY_FN(Type) Type, 53namespace RecordedOpId { 54 enum { 55 MAP_OPS(IDENTITY_FN) 56 Count, 57 }; 58} 59static_assert(RecordedOpId::BitmapOp == 0, 60 "First index must be zero for LUTs to work"); 61 62#define BASE_PARAMS const Rect& unmappedBounds, const Matrix4& localMatrix, const Rect& localClipRect, const SkPaint* paint 63#define BASE_PARAMS_PAINTLESS const Rect& unmappedBounds, const Matrix4& localMatrix, const Rect& localClipRect 64#define SUPER(Type) RecordedOp(RecordedOpId::Type, unmappedBounds, localMatrix, localClipRect, paint) 65#define SUPER_PAINTLESS(Type) RecordedOp(RecordedOpId::Type, unmappedBounds, localMatrix, localClipRect, nullptr) 66 67struct RecordedOp { 68 /* ID from RecordedOpId - generally used for jumping into function tables */ 69 const int opId; 70 71 /* bounds in *local* space, without accounting for DisplayList transformation */ 72 const Rect unmappedBounds; 73 74 /* transform in recording space (vs DisplayList origin) */ 75 const Matrix4 localMatrix; 76 77 /* clip in recording space */ 78 const Rect localClipRect; 79 80 /* optional paint, stored in base object to simplify merging logic */ 81 const SkPaint* paint; 82protected: 83 RecordedOp(unsigned int opId, BASE_PARAMS) 84 : opId(opId) 85 , unmappedBounds(unmappedBounds) 86 , localMatrix(localMatrix) 87 , localClipRect(localClipRect) 88 , paint(paint) {} 89}; 90 91struct RenderNodeOp : RecordedOp { 92 RenderNodeOp(BASE_PARAMS_PAINTLESS, RenderNode* renderNode) 93 : SUPER_PAINTLESS(RenderNodeOp) 94 , renderNode(renderNode) {} 95 RenderNode * renderNode; // not const, since drawing modifies it (somehow...) 96}; 97 98struct BitmapOp : RecordedOp { 99 BitmapOp(BASE_PARAMS, const SkBitmap* bitmap) 100 : SUPER(BitmapOp) 101 , bitmap(bitmap) {} 102 const SkBitmap* bitmap; 103 // TODO: asset atlas/texture id lookup? 104}; 105 106struct RectOp : RecordedOp { 107 RectOp(BASE_PARAMS) 108 : SUPER(RectOp) {} 109}; 110 111struct SimpleRectsOp : RecordedOp { // Filled, no AA (TODO: better name?) 112 SimpleRectsOp(BASE_PARAMS, Vertex* vertices, size_t vertexCount) 113 : SUPER(SimpleRectsOp) 114 , vertices(vertices) 115 , vertexCount(vertexCount) {} 116 Vertex* vertices; 117 const size_t vertexCount; 118}; 119 120/** 121 * Stateful operation! denotes the creation of an off-screen layer, 122 * and that commands following will render into it. 123 */ 124struct BeginLayerOp : RecordedOp { 125 BeginLayerOp(BASE_PARAMS) 126 : SUPER(BeginLayerOp) {} 127}; 128 129/** 130 * Stateful operation! Denotes end of off-screen layer, and that 131 * commands since last BeginLayerOp should be drawn into parent FBO. 132 * 133 * State in this op is empty, it just serves to signal that a layer has been finished. 134 */ 135struct EndLayerOp : RecordedOp { 136 EndLayerOp() 137 : RecordedOp(RecordedOpId::EndLayerOp, Rect(0, 0), Matrix4::identity(), Rect(0, 0), nullptr) {} 138}; 139 140/** 141 * Draws an OffscreenBuffer. 142 * 143 * Alpha, mode, and colorfilter are embedded, since LayerOps are always dynamically generated, 144 * when creating/tracking a SkPaint* during defer isn't worth the bother. 145 */ 146struct LayerOp : RecordedOp { 147 // Records a one-use (saveLayer) layer for drawing. Once drawn, the layer will be destroyed. 148 LayerOp(BASE_PARAMS, OffscreenBuffer** layerHandle) 149 : SUPER_PAINTLESS(LayerOp) 150 , layerHandle(layerHandle) 151 , alpha(paint->getAlpha() / 255.0f) 152 , mode(PaintUtils::getXfermodeDirect(paint)) 153 , colorFilter(paint->getColorFilter()) 154 , destroy(true) {} 155 156 LayerOp(RenderNode& node) 157 : RecordedOp(RecordedOpId::LayerOp, Rect(node.getWidth(), node.getHeight()), Matrix4::identity(), Rect(node.getWidth(), node.getHeight()), nullptr) 158 , layerHandle(node.getLayerHandle()) 159 , alpha(node.properties().layerProperties().alpha() / 255.0f) 160 , mode(node.properties().layerProperties().xferMode()) 161 , colorFilter(node.properties().layerProperties().colorFilter()) 162 , destroy(false) {} 163 164 // Records a handle to the Layer object, since the Layer itself won't be 165 // constructed until after this operation is constructed. 166 OffscreenBuffer** layerHandle; 167 const float alpha; 168 const SkXfermode::Mode mode; 169 170 // pointer to object owned by either LayerProperties, or a recorded Paint object in a 171 // BeginLayerOp. Lives longer than LayerOp in either case, so no skia ref counting is used. 172 SkColorFilter* colorFilter; 173 174 // whether to destroy the layer, once rendered 175 const bool destroy; 176}; 177 178}; // namespace uirenderer 179}; // namespace android 180 181#endif // ANDROID_HWUI_RECORDED_OP_H 182