1 /*
2  * Copyright Samsung Electronics Co.,LTD.
3  * Copyright (C) 2017 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #ifndef __HARDWARE_EXYNOS_HW2DCOMPOSITOR_G2D_H__
19 #define __HARDWARE_EXYNOS_HW2DCOMPOSITOR_G2D_H__
20 
21 #include <memory>
22 
23 #include <hardware/exynos/acryl.h>
24 
25 #include <hardware/exynos/g2d_hdr_plugin.h>
26 
27 #include <uapi/g2d.h>
28 
29 #include "acrylic_internal.h"
30 #include "acrylic_device.h"
31 
32 class G2DHdrWriter {
33     std::unique_ptr<IG2DHdr10CommandWriter> mWriter;
34     g2d_commandlist *mCmds = nullptr;
35 public:
G2DHdrWriter()36     G2DHdrWriter() {
37 #ifdef LIBACRYL_G2D_HDR_PLUGIN
38         mWriter.reset(IG2DHdr10CommandWriter::createInstance());
39 #endif
40     }
41 
~G2DHdrWriter()42     ~G2DHdrWriter() {
43         putCommands();
44     }
45 
setLayerStaticMetadata(int layer_index,int dataspace,unsigned int min_luminance,unsigned int max_luminance)46     bool setLayerStaticMetadata(int layer_index, int dataspace, unsigned int min_luminance, unsigned int max_luminance) {
47         return mWriter ? mWriter->setLayerStaticMetadata(layer_index, dataspace, min_luminance, max_luminance) : true;
48     }
49 
setLayerImageInfo(int layer_index,unsigned int pixfmt,bool alpha_premult)50     bool setLayerImageInfo(int layer_index, unsigned int pixfmt, bool alpha_premult) {
51         return mWriter ? mWriter->setLayerImageInfo(layer_index, pixfmt, alpha_premult) : true;
52     }
53 
setLayerOpaqueData(int layer_index,void * data,size_t len)54     void setLayerOpaqueData(int layer_index, void *data, size_t len) {
55         if (mWriter)
56             mWriter->setLayerOpaqueData(layer_index, data, len);
57     }
58 
setTargetInfo(int dataspace,void * data)59     bool setTargetInfo(int dataspace, void *data) {
60         return mWriter ? mWriter->setTargetInfo(dataspace, data) : true;
61     }
62 
setTargetDisplayLuminance(unsigned int min,unsigned int max)63     void setTargetDisplayLuminance(unsigned int min, unsigned int max) {
64         if (mWriter)
65 		mWriter->setTargetDisplayLuminance(min, max);
66     }
67 
getLayerHdrMode(g2d_task & task)68     void getLayerHdrMode(g2d_task &task) {
69         if (!mCmds)
70             return;
71 
72         for (unsigned int i = 0; i < mCmds->layer_count; i++) {
73             unsigned int idx;
74 
75             if (mWriter->hasColorFillLayer())
76                 idx = (mCmds->layer_hdr_mode[i].offset >> 8) - 3;
77             else
78                 idx = (mCmds->layer_hdr_mode[i].offset >> 8) - 2;
79 
80             // If premultiplied alpha values are de-premultied before HDR conversion,
81             // it should be multiplied again after the conversion. But some of the HDR processors
82             // does not have functionality of alpha multiplicaion after the conversion even though
83             // it has demultipier before the conversion.
84             // If the HDR process is lack of alpha multiplication, multiplication of alpha value
85             // should be performed by G2D.
86             if (mCmds->layer_hdr_mode[i].value & G2D_LAYER_HDRMODE_DEMULT_ALPHA)
87                 task.commands.source[idx][G2DSFR_SRC_COMMAND] |= G2D_LAYERCMD_PREMULT_ALPHA;
88             task.commands.source[idx][G2DSFR_SRC_HDRMODE] = mCmds->layer_hdr_mode[i].value;
89         }
90     }
91 
getCommandCount()92     unsigned int getCommandCount() {
93         return mCmds ? mCmds->command_count : 0;
94     }
95 
write(g2d_reg * regs)96     unsigned int write(g2d_reg *regs) {
97         if (mCmds) {
98             memcpy(regs, mCmds->commands, sizeof(*regs) * mCmds->command_count);
99             return mCmds->command_count;
100         }
101 
102         return 0;
103     }
104 
getCommands()105     void getCommands() {
106         if (!mCmds && mWriter)
107             mCmds = mWriter->getCommands();
108     }
109 
putCommands()110     void putCommands() {
111         if (mWriter && mCmds) {
112             mWriter->putCommands(mCmds);
113             mCmds = nullptr;
114         }
115     }
116 };
117 
118 struct g2d_fmt;
119 
120 class AcrylicCompositorG2D: public Acrylic {
121 public:
122     AcrylicCompositorG2D(const HW2DCapability &capability, bool newcolormode);
123     virtual ~AcrylicCompositorG2D();
124     virtual bool execute(int fence[], unsigned int num_fences);
125     virtual bool execute(int *handle = NULL);
126     virtual bool waitExecution(int handle);
getLaptimeUSec()127     virtual unsigned int getLaptimeUSec() { return mTask.laptime_in_usec; }
128     /*
129      * Return -1 on failure in configuring the give priority or the priority is invalid.
130      * Return 0 when the priority is configured successfully without any side effect.
131      * Return 1 when the priority is configured successfully but the priority may not
132      * be reflected promptly due to other pending tasks with lower priorities.
133      */
134     virtual int prioritize(int priority = -1);
135     virtual bool requestPerformanceQoS(AcrylicPerformanceRequest *request);
136 private:
137     int ioctlG2D(void);
138     bool executeG2D(int fence[], unsigned int num_fences, bool nonblocking);
139     bool prepareImage(AcrylicCanvas &layer, struct g2d_layer &image, uint32_t cmd[], int index);
140     bool prepareSource(AcrylicLayer &layer, struct g2d_layer &image, uint32_t cmd[], hw2d_coord_t target_size,
141                        unsigned int index, unsigned int image_index);
142     bool prepareSolidLayer(AcrylicCanvas &canvas, struct g2d_layer &image, uint32_t cmd[]);
143     bool prepareSolidLayer(AcrylicLayer &layer, struct g2d_layer &image, uint32_t cmd[], hw2d_coord_t target_size, unsigned int index);
144     bool reallocLayer(unsigned int layercount);
145     unsigned int updateFilterCoefficients(unsigned int layercount, g2d_reg regs[]);
146 
147     AcrylicDevice mDev;
148     g2d_task	  mTask;
149     G2DHdrWriter  mHdrWriter;
150     unsigned int  mMaxSourceCount;
151     int mPriority;
152     unsigned int mVersion;
153     bool mUsePolyPhaseFilter;
154 
155     g2d_fmt *halfmt_to_g2dfmt_tbl;
156     size_t len_halfmt_to_g2dfmt_tbl;
157 };
158 
159 #endif //__HARDWARE_EXYNOS_HW2DCOMPOSITOR_G2D_H__
160