1 /*
2  * Copyright (C) 2016 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 #include "guest/hals/hwcomposer/common/cpu_composer.h"
18 
19 #include <algorithm>
20 #include <cstdlib>
21 #include <utility>
22 #include <vector>
23 
24 #include <drm_fourcc.h>
25 #include <hardware/hwcomposer.h>
26 #include <hardware/hwcomposer_defs.h>
27 #include <libyuv.h>
28 #include <log/log.h>
29 
30 #include "common/libs/utils/size_utils.h"
31 #include "guest/hals/hwcomposer/common/drm_utils.h"
32 #include "guest/hals/hwcomposer/common/geometry_utils.h"
33 
34 namespace cvd {
35 
36 namespace {
37 
LayerNeedsScaling(const hwc_layer_1_t & layer)38 bool LayerNeedsScaling(const hwc_layer_1_t& layer) {
39   int from_w = layer.sourceCrop.right - layer.sourceCrop.left;
40   int from_h = layer.sourceCrop.bottom - layer.sourceCrop.top;
41   int to_w = layer.displayFrame.right - layer.displayFrame.left;
42   int to_h = layer.displayFrame.bottom - layer.displayFrame.top;
43 
44   bool not_rot_scale = from_w != to_w || from_h != to_h;
45   bool rot_scale = from_w != to_h || from_h != to_w;
46 
47   bool needs_rot = layer.transform & HAL_TRANSFORM_ROT_90;
48 
49   return needs_rot ? rot_scale : not_rot_scale;
50 }
51 
LayerNeedsBlending(const hwc_layer_1_t & layer)52 bool LayerNeedsBlending(const hwc_layer_1_t& layer) {
53   return layer.blending != HWC_BLENDING_NONE;
54 }
55 
LayerNeedsAttenuation(const hwc_layer_1_t & layer)56 bool LayerNeedsAttenuation(const hwc_layer_1_t& layer) {
57   return layer.blending == HWC_BLENDING_COVERAGE;
58 }
59 
60 struct BufferSpec;
61 typedef int (*ConverterFunction)(const BufferSpec& src, const BufferSpec& dst,
62                                  bool v_flip);
63 int DoCopy(const BufferSpec& src, const BufferSpec& dst, bool v_flip);
64 int ConvertFromYV12(const BufferSpec& src, const BufferSpec& dst, bool v_flip);
65 
GetConverterForDrmFormat(uint32_t drm_format)66 ConverterFunction GetConverterForDrmFormat(uint32_t drm_format) {
67   switch (drm_format) {
68     case DRM_FORMAT_ABGR8888:
69     case DRM_FORMAT_XBGR8888:
70       return &DoCopy;
71     case DRM_FORMAT_YVU420:
72       return &ConvertFromYV12;
73   }
74   ALOGW("Unsupported format: %d(%s), returning null converter",
75         drm_format, GetDrmFormatString(drm_format));
76   return nullptr;
77 }
78 
IsDrmFormatSupported(uint32_t drm_format)79 bool IsDrmFormatSupported(uint32_t drm_format) {
80   return GetConverterForDrmFormat(drm_format) != nullptr;
81 }
82 
83 /*******************************************************************************
84 Libyuv's convert functions only allow the combination of any rotation (multiple
85 of 90 degrees) and a vertical flip, but not horizontal flips.
86 Surfaceflinger's transformations are expressed in terms of a vertical flip, a
87 horizontal flip and/or a single 90 degrees clockwise rotation (see
88 NATIVE_WINDOW_TRANSFORM_HINT documentation on system/window.h for more insight).
89 The following code allows to turn a horizontal flip into a 180 degrees rotation
90 and a vertical flip.
91 *******************************************************************************/
GetRotationFromTransform(uint32_t transform)92 libyuv::RotationMode GetRotationFromTransform(uint32_t transform) {
93   uint32_t rotation =
94       (transform & HAL_TRANSFORM_ROT_90) ? 1 : 0;          // 1 * ROT90 bit
95   rotation += (transform & HAL_TRANSFORM_FLIP_H) ? 2 : 0;  // 2 * VFLIP bit
96   return static_cast<libyuv::RotationMode>(90 * rotation);
97 }
98 
GetVFlipFromTransform(uint32_t transform)99 bool GetVFlipFromTransform(uint32_t transform) {
100   // vertical flip xor horizontal flip
101   return ((transform & HAL_TRANSFORM_FLIP_V) >> 1) ^
102          (transform & HAL_TRANSFORM_FLIP_H);
103 }
104 
105 struct BufferSpec {
106   uint8_t* buffer;
107   std::optional<android_ycbcr> buffer_ycbcr;
108   int width;
109   int height;
110   int crop_x;
111   int crop_y;
112   int crop_width;
113   int crop_height;
114   uint32_t drm_format;
115   int stride_bytes;
116   int sample_bytes;
117 
BufferSpeccvd::__anonb73405500111::BufferSpec118   BufferSpec(uint8_t* buffer,
119              std::optional<android_ycbcr> buffer_ycbcr,
120              int width,
121              int height,
122              int crop_x,
123              int crop_y,
124              int crop_width,
125              int crop_height,
126              uint32_t drm_format,
127              int stride_bytes,
128              int sample_bytes)
129       : buffer(buffer),
130         buffer_ycbcr(buffer_ycbcr),
131         width(width),
132         height(height),
133         crop_x(crop_x),
134         crop_y(crop_y),
135         crop_width(crop_width),
136         crop_height(crop_height),
137         drm_format(drm_format),
138         stride_bytes(stride_bytes),
139         sample_bytes(sample_bytes) {}
140 
BufferSpeccvd::__anonb73405500111::BufferSpec141   BufferSpec(uint8_t* buffer,
142              int width,
143              int height,
144              int stride_bytes)
145       : BufferSpec(buffer,
146                    /*buffer_ycbcr=*/std::nullopt,
147                    width,
148                    height,
149                    /*crop_x=*/0,
150                    /*crop_y=*/0,
151                    /*crop_width=*/width,
152                    /*crop_height=*/height,
153                    /*drm_format=*/DRM_FORMAT_ABGR8888,
154                    stride_bytes,
155                    /*sample_bytes=*/4) {}
156 
157 };
158 
ConvertFromYV12(const BufferSpec & src,const BufferSpec & dst,bool v_flip)159 int ConvertFromYV12(const BufferSpec& src, const BufferSpec& dst, bool v_flip) {
160   // The following calculation of plane offsets and alignments are based on
161   // swiftshader's Sampler::setTextureLevel() implementation
162   // (Renderer/Sampler.cpp:225)
163 
164   auto& src_buffer_ycbcr_opt = src.buffer_ycbcr;
165   if (!src_buffer_ycbcr_opt) {
166     ALOGE("%s called on non ycbcr buffer", __FUNCTION__);
167     return -1;
168   }
169   auto& src_buffer_ycbcr = *src_buffer_ycbcr_opt;
170 
171   // The libyuv::I420ToARGB() function is for tri-planar.
172   if (src_buffer_ycbcr.chroma_step != 1) {
173     ALOGE("%s called with bad chroma step", __FUNCTION__);
174     return -1;
175   }
176 
177   uint8_t* src_y = reinterpret_cast<uint8_t*>(src_buffer_ycbcr.y);
178   int stride_y = src_buffer_ycbcr.ystride;
179   uint8_t* src_u = reinterpret_cast<uint8_t*>(src_buffer_ycbcr.cb);
180   int stride_u = src_buffer_ycbcr.cstride;
181   uint8_t* src_v = reinterpret_cast<uint8_t*>(src_buffer_ycbcr.cr);
182   int stride_v = src_buffer_ycbcr.cstride;
183 
184   // Adjust for crop
185   src_y += src.crop_y * stride_y + src.crop_x;
186   src_v += (src.crop_y / 2) * stride_v + (src.crop_x / 2);
187   src_u += (src.crop_y / 2) * stride_u + (src.crop_x / 2);
188   uint8_t* dst_buffer = dst.buffer + dst.crop_y * dst.stride_bytes +
189                         dst.crop_x * dst.sample_bytes;
190 
191   // YV12 is the same as I420, with the U and V planes swapped
192   return libyuv::I420ToARGB(src_y, stride_y,
193                             src_v, stride_v,
194                             src_u, stride_u,
195                             dst_buffer, dst.stride_bytes,
196                             dst.crop_width,
197                             v_flip ? -dst.crop_height : dst.crop_height);
198 }
199 
DoConversion(const BufferSpec & src,const BufferSpec & dst,bool v_flip)200 int DoConversion(const BufferSpec& src, const BufferSpec& dst, bool v_flip) {
201   return (*GetConverterForDrmFormat(src.drm_format))(src, dst, v_flip);
202 }
203 
DoCopy(const BufferSpec & src,const BufferSpec & dst,bool v_flip)204 int DoCopy(const BufferSpec& src, const BufferSpec& dst, bool v_flip) {
205   // Point to the upper left corner of the crop rectangle
206   uint8_t* src_buffer = src.buffer + src.crop_y * src.stride_bytes +
207                         src.crop_x * src.sample_bytes;
208   uint8_t* dst_buffer = dst.buffer + dst.crop_y * dst.stride_bytes +
209                         dst.crop_x * dst.sample_bytes;
210   int width = src.crop_width;
211   int height = src.crop_height;
212 
213   if (v_flip) {
214     height = -height;
215   }
216 
217   // HAL formats are named based on the order of the pixel componets on the
218   // byte stream, while libyuv formats are named based on the order of those
219   // pixel components in an integer written from left to right. So
220   // libyuv::FOURCC_ARGB is equivalent to HAL_PIXEL_FORMAT_BGRA_8888.
221   auto ret = libyuv::ARGBCopy(src_buffer, src.stride_bytes,
222                               dst_buffer, dst.stride_bytes,
223                               width, height);
224   return ret;
225 }
226 
DoRotation(const BufferSpec & src,const BufferSpec & dst,libyuv::RotationMode rotation,bool v_flip)227 int DoRotation(const BufferSpec& src, const BufferSpec& dst,
228                libyuv::RotationMode rotation, bool v_flip) {
229   // Point to the upper left corner of the crop rectangles
230   uint8_t* src_buffer = src.buffer + src.crop_y * src.stride_bytes +
231                         src.crop_x * src.sample_bytes;
232   uint8_t* dst_buffer = dst.buffer + dst.crop_y * dst.stride_bytes +
233                         dst.crop_x * dst.sample_bytes;
234   int width = src.crop_width;
235   int height = src.crop_height;
236 
237   if (v_flip) {
238     height = -height;
239   }
240 
241   return libyuv::ARGBRotate(src_buffer, src.stride_bytes,
242                             dst_buffer, dst.stride_bytes,
243                             width, height, rotation);
244 }
245 
DoScaling(const BufferSpec & src,const BufferSpec & dst,bool v_flip)246 int DoScaling(const BufferSpec& src, const BufferSpec& dst, bool v_flip) {
247   // Point to the upper left corner of the crop rectangles
248   uint8_t* src_buffer = src.buffer + src.crop_y * src.stride_bytes +
249                         src.crop_x * src.sample_bytes;
250   uint8_t* dst_buffer = dst.buffer + dst.crop_y * dst.stride_bytes +
251                         dst.crop_x * dst.sample_bytes;
252   int src_width = src.crop_width;
253   int src_height = src.crop_height;
254   int dst_width = dst.crop_width;
255   int dst_height = dst.crop_height;
256 
257   if (v_flip) {
258     src_height = -src_height;
259   }
260 
261   return libyuv::ARGBScale(src_buffer, src.stride_bytes, src_width, src_height,
262                            dst_buffer, dst.stride_bytes, dst_width, dst_height,
263                            libyuv::kFilterBilinear);
264 }
265 
DoAttenuation(const BufferSpec & src,const BufferSpec & dst,bool v_flip)266 int DoAttenuation(const BufferSpec& src, const BufferSpec& dst, bool v_flip) {
267   // Point to the upper left corner of the crop rectangles
268   uint8_t* src_buffer = src.buffer + src.crop_y * src.stride_bytes +
269                         src.crop_x * src.sample_bytes;
270   uint8_t* dst_buffer = dst.buffer + dst.crop_y * dst.stride_bytes +
271                         dst.crop_x * dst.sample_bytes;
272   int width = dst.crop_width;
273   int height = dst.crop_height;
274 
275   if (v_flip) {
276     height = -height;
277   }
278 
279   return libyuv::ARGBAttenuate(src_buffer, src.stride_bytes,
280                                dst_buffer, dst.stride_bytes,
281                                width, height);
282 }
283 
DoBlending(const BufferSpec & src,const BufferSpec & dst,bool v_flip)284 int DoBlending(const BufferSpec& src, const BufferSpec& dst, bool v_flip) {
285   // Point to the upper left corner of the crop rectangles
286   uint8_t* src_buffer = src.buffer + src.crop_y * src.stride_bytes +
287                         src.crop_x * src.sample_bytes;
288   uint8_t* dst_buffer = dst.buffer + dst.crop_y * dst.stride_bytes +
289                         dst.crop_x * dst.sample_bytes;
290   int width = dst.crop_width;
291   int height = dst.crop_height;
292 
293   if (v_flip) {
294     height = -height;
295   }
296 
297   // libyuv's ARGB format is hwcomposer's BGRA format, since blending only cares
298   // for the position of alpha in the pixel and not the position of the colors
299   // this function is perfectly usable.
300   return libyuv::ARGBBlend(src_buffer, src.stride_bytes,
301                            dst_buffer, dst.stride_bytes,
302                            dst_buffer, dst.stride_bytes,
303                            width, height);
304 }
305 
GetBufferSpec(GrallocBuffer & buffer,const hwc_rect_t & buffer_crop)306 std::optional<BufferSpec> GetBufferSpec(GrallocBuffer& buffer,
307                                         const hwc_rect_t& buffer_crop) {
308   auto buffer_format_opt = buffer.GetDrmFormat();
309   if (!buffer_format_opt) {
310     ALOGE("Failed to get gralloc buffer format.");
311     return std::nullopt;
312   }
313   uint32_t buffer_format = *buffer_format_opt;
314 
315   auto buffer_width_opt = buffer.GetWidth();
316   if (!buffer_width_opt) {
317     ALOGE("Failed to get gralloc buffer width.");
318     return std::nullopt;
319   }
320   uint32_t buffer_width = *buffer_width_opt;
321 
322   auto buffer_height_opt = buffer.GetHeight();
323   if (!buffer_height_opt) {
324     ALOGE("Failed to get gralloc buffer height.");
325     return std::nullopt;
326   }
327   uint32_t buffer_height = *buffer_height_opt;
328 
329   uint8_t* buffer_data = nullptr;
330   uint32_t buffer_stride_bytes = 0;
331   std::optional<android_ycbcr> buffer_ycbcr_data;
332 
333   if (buffer_format == DRM_FORMAT_NV12 ||
334       buffer_format == DRM_FORMAT_NV21 ||
335       buffer_format == DRM_FORMAT_YVU420) {
336     buffer_ycbcr_data = buffer.LockYCbCr();
337     if (!buffer_ycbcr_data) {
338       ALOGE("%s failed to lock gralloc buffer.", __FUNCTION__);
339       return std::nullopt;
340     }
341   } else {
342     auto buffer_data_opt = buffer.Lock();
343     if (!buffer_data_opt) {
344       ALOGE("%s failed to lock gralloc buffer.", __FUNCTION__);
345       return std::nullopt;
346     }
347     buffer_data = reinterpret_cast<uint8_t*>(*buffer_data_opt);
348 
349     auto buffer_stride_bytes_opt = buffer.GetMonoPlanarStrideBytes();
350     if (!buffer_stride_bytes_opt) {
351       ALOGE("%s failed to get plane stride.", __FUNCTION__);
352       return std::nullopt;
353     }
354     buffer_stride_bytes = *buffer_stride_bytes_opt;
355   }
356 
357   return BufferSpec(
358       buffer_data,
359       buffer_ycbcr_data,
360       buffer_width,
361       buffer_height,
362       buffer_crop.left,
363       buffer_crop.top,
364       buffer_crop.right - buffer_crop.left,
365       buffer_crop.bottom - buffer_crop.top,
366       buffer_format,
367       buffer_stride_bytes,
368       GetDrmFormatBytesPerPixel(buffer_format));
369 }
370 
371 }  // namespace
372 
CanCompositeLayer(const hwc_layer_1_t & layer)373 bool CpuComposer::CanCompositeLayer(const hwc_layer_1_t& layer) {
374   buffer_handle_t buffer_handle = layer.handle;
375   if (buffer_handle == nullptr) {
376     ALOGW("%s received a layer with a null handle", __FUNCTION__);
377     return false;
378   }
379 
380   auto buffer_opt = gralloc_.Import(buffer_handle);
381   if (!buffer_opt) {
382     ALOGE("Failed to import layer buffer.");
383     return false;
384   }
385   GrallocBuffer& buffer = *buffer_opt;
386 
387   auto buffer_format_opt = buffer.GetDrmFormat();
388   if (!buffer_format_opt) {
389     ALOGE("Failed to get layer buffer format.");
390     return false;
391   }
392   uint32_t buffer_format = *buffer_format_opt;
393 
394   if (!IsDrmFormatSupported(buffer_format)) {
395     ALOGD("Unsupported pixel format: 0x%x, doing software composition instead",
396           buffer_format);
397     return false;
398   }
399   return true;
400 }
401 
CompositeLayer(hwc_layer_1_t * src_layer,int buffer_idx)402 void CpuComposer::CompositeLayer(hwc_layer_1_t* src_layer, int buffer_idx) {
403   libyuv::RotationMode rotation =
404       GetRotationFromTransform(src_layer->transform);
405 
406   auto src_imported_buffer_opt = gralloc_.Import(src_layer->handle);
407   if (!src_imported_buffer_opt) {
408     ALOGE("Failed to import layer buffer.");
409     return;
410   }
411   GrallocBuffer& src_imported_buffer = *src_imported_buffer_opt;
412 
413   auto src_layer_spec_opt = GetBufferSpec(src_imported_buffer, src_layer->sourceCrop);
414   if (!src_layer_spec_opt) {
415     return;
416   }
417   BufferSpec src_layer_spec = *src_layer_spec_opt;
418 
419   // TODO(jemoreira): Remove the hardcoded fomat.
420   bool needs_conversion = src_layer_spec.drm_format != DRM_FORMAT_XBGR8888;
421   bool needs_scaling = LayerNeedsScaling(*src_layer);
422   bool needs_rotation = rotation != libyuv::kRotate0;
423   bool needs_transpose = needs_rotation && rotation != libyuv::kRotate180;
424   bool needs_vflip = GetVFlipFromTransform(src_layer->transform);
425   bool needs_attenuation = LayerNeedsAttenuation(*src_layer);
426   bool needs_blending = LayerNeedsBlending(*src_layer);
427   bool needs_copy = !(needs_conversion || needs_scaling || needs_rotation ||
428                       needs_vflip || needs_attenuation || needs_blending);
429 
430   uint8_t* dst_buffer =
431     reinterpret_cast<uint8_t*>(screen_view_->GetBuffer(buffer_idx));
432 
433   BufferSpec dst_layer_spec(
434       dst_buffer,
435       /*buffer_ycbcr=*/std::nullopt,
436       screen_view_->x_res(),
437       screen_view_->y_res(),
438       src_layer->displayFrame.left,
439       src_layer->displayFrame.top,
440       src_layer->displayFrame.right - src_layer->displayFrame.left,
441       src_layer->displayFrame.bottom - src_layer->displayFrame.top,
442       DRM_FORMAT_XBGR8888,
443       screen_view_->line_length(),
444       4);
445 
446   // Add the destination layer to the bottom of the buffer stack
447   std::vector<BufferSpec> dest_buffer_stack(1, dst_layer_spec);
448 
449   // If more than operation is to be performed, a temporary buffer is needed for
450   // each additional operation
451 
452   // N operations need N destination buffers, the destination layer (the
453   // framebuffer) is one of them, so only N-1 temporary buffers are needed.
454   // Vertical flip is not taken into account because it can be done together
455   // with any other operation.
456   int needed_tmp_buffers = (needs_conversion ? 1 : 0) +
457                            (needs_scaling ? 1 : 0) + (needs_rotation ? 1 : 0) +
458                            (needs_attenuation ? 1 : 0) +
459                            (needs_blending ? 1 : 0) + (needs_copy ? 1 : 0) - 1;
460 
461   int tmp_buffer_width =
462       src_layer->displayFrame.right - src_layer->displayFrame.left;
463   int tmp_buffer_height =
464       src_layer->displayFrame.bottom - src_layer->displayFrame.top;
465   int tmp_buffer_stride_bytes =
466       cvd::AlignToPowerOf2(tmp_buffer_width * screen_view_->bytes_per_pixel(), 4);
467 
468   for (int i = 0; i < needed_tmp_buffers; i++) {
469     BufferSpec tmp_buffer_spec(
470         RotateTmpBuffer(i),
471         tmp_buffer_width,
472         tmp_buffer_height,
473         tmp_buffer_stride_bytes);
474     dest_buffer_stack.push_back(tmp_buffer_spec);
475   }
476 
477   // Conversion and scaling should always be the first operations, so that every
478   // other operation works on equally sized frames (garanteed to fit in the tmp
479   // buffers)
480 
481   // TODO(jemoreira): We are converting to ARGB as the first step under the
482   // assumption that scaling ARGB is faster than scaling I420 (the most common).
483   // This should be confirmed with testing.
484   if (needs_conversion) {
485     BufferSpec& dst_buffer_spec = dest_buffer_stack.back();
486     if (needs_scaling || needs_transpose) {
487       // If a rotation or a scaling operation are needed the dimensions at the
488       // top of the buffer stack are wrong (wrong sizes for scaling, swapped
489       // width and height for 90 and 270 rotations).
490       // Make width and height match the crop sizes on the source
491       int src_width = src_layer_spec.crop_width;
492       int src_height = src_layer_spec.crop_height;
493       int dst_stride_bytes =
494           cvd::AlignToPowerOf2(src_width * screen_view_->bytes_per_pixel(), 4);
495       size_t needed_size = dst_stride_bytes * src_height;
496       dst_buffer_spec.width = src_width;
497       dst_buffer_spec.height = src_height;
498       // Adjust the stride accordingly
499       dst_buffer_spec.stride_bytes = dst_stride_bytes;
500       // Crop sizes also need to be adjusted
501       dst_buffer_spec.crop_width = src_width;
502       dst_buffer_spec.crop_height = src_height;
503       // crop_x and y are fine at 0, format is already set to match destination
504 
505       // In case of a scale, the source frame may be bigger than the default tmp
506       // buffer size
507       if (needed_size > tmp_buffer_.size() / kNumTmpBufferPieces) {
508         dst_buffer_spec.buffer = GetSpecialTmpBuffer(needed_size);
509       }
510     }
511 
512     int retval = DoConversion(src_layer_spec, dst_buffer_spec, needs_vflip);
513     if (retval) {
514       ALOGE("Got error code %d from DoConversion function", retval);
515     }
516     needs_vflip = false;
517     src_layer_spec = dst_buffer_spec;
518     dest_buffer_stack.pop_back();
519   }
520 
521   if (needs_scaling) {
522     BufferSpec& dst_buffer_spec = dest_buffer_stack.back();
523     if (needs_transpose) {
524       // If a rotation is needed, the temporary buffer has the correct size but
525       // needs to be transposed and have its stride updated accordingly. The
526       // crop sizes also needs to be transposed, but not the x and y since they
527       // are both zero in a temporary buffer (and it is a temporary buffer
528       // because a rotation will be performed next).
529       std::swap(dst_buffer_spec.width, dst_buffer_spec.height);
530       std::swap(dst_buffer_spec.crop_width, dst_buffer_spec.crop_height);
531       // TODO (jemoreira): Aligment (To align here may cause the needed size to
532       // be bigger than the buffer, so care should be taken)
533       dst_buffer_spec.stride_bytes =
534           dst_buffer_spec.width * screen_view_->bytes_per_pixel();
535     }
536     int retval = DoScaling(src_layer_spec, dst_buffer_spec, needs_vflip);
537     needs_vflip = false;
538     if (retval) {
539       ALOGE("Got error code %d from DoScaling function", retval);
540     }
541     src_layer_spec = dst_buffer_spec;
542     dest_buffer_stack.pop_back();
543   }
544 
545   if (needs_rotation) {
546     int retval = DoRotation(src_layer_spec, dest_buffer_stack.back(), rotation,
547                             needs_vflip);
548     needs_vflip = false;
549     if (retval) {
550       ALOGE("Got error code %d from DoTransform function", retval);
551     }
552     src_layer_spec = dest_buffer_stack.back();
553     dest_buffer_stack.pop_back();
554   }
555 
556   if (needs_attenuation) {
557     int retval = DoAttenuation(src_layer_spec, dest_buffer_stack.back(),
558                                needs_vflip);
559     needs_vflip = false;
560     if (retval) {
561       ALOGE("Got error code %d from DoBlending function", retval);
562     }
563     src_layer_spec = dest_buffer_stack.back();
564     dest_buffer_stack.pop_back();
565   }
566 
567   if (needs_copy) {
568     int retval = DoCopy(src_layer_spec, dest_buffer_stack.back(), needs_vflip);
569     needs_vflip = false;
570     if (retval) {
571       ALOGE("Got error code %d from DoBlending function", retval);
572     }
573     src_layer_spec = dest_buffer_stack.back();
574     dest_buffer_stack.pop_back();
575   }
576 
577   // Blending (if needed) should always be the last operation, so that it reads
578   // and writes in the destination layer and not some temporary buffer.
579   if (needs_blending) {
580     int retval = DoBlending(src_layer_spec, dest_buffer_stack.back(),
581                             needs_vflip);
582     needs_vflip = false;
583     if (retval) {
584       ALOGE("Got error code %d from DoBlending function", retval);
585     }
586     // Don't need to assign destination to source in the last one
587     dest_buffer_stack.pop_back();
588   }
589 
590   src_imported_buffer.Unlock();
591 }
592 
593 /* static */ const int CpuComposer::kNumTmpBufferPieces = 2;
594 
CpuComposer(std::unique_ptr<ScreenView> screen_view)595 CpuComposer::CpuComposer(std::unique_ptr<ScreenView> screen_view)
596     : BaseComposer(std::move(screen_view)),
597       tmp_buffer_(kNumTmpBufferPieces * screen_view_->buffer_size()) {}
598 
PrepareLayers(size_t num_layers,hwc_layer_1_t * layers)599 int CpuComposer::PrepareLayers(size_t num_layers, hwc_layer_1_t* layers) {
600   int composited_layers_count = 0;
601 
602   // Loop over layers in inverse order of z-index
603   for (size_t layer_index = num_layers; layer_index > 0;) {
604     // Decrement here to be able to compare unsigned integer with 0 in the
605     // loop condition
606     --layer_index;
607     if (IS_TARGET_FRAMEBUFFER(layers[layer_index].compositionType)) {
608       continue;
609     }
610     if (layers[layer_index].flags & HWC_SKIP_LAYER) {
611       continue;
612     }
613     if (layers[layer_index].compositionType == HWC_BACKGROUND) {
614       layers[layer_index].compositionType = HWC_FRAMEBUFFER;
615       continue;
616     }
617     layers[layer_index].compositionType = HWC_OVERLAY;
618     // Hwcomposer cannot draw below software-composed layers, so we need
619     // to mark those HWC_FRAMEBUFFER as well.
620     for (size_t top_idx = layer_index + 1; top_idx < num_layers; ++top_idx) {
621       // layers marked as skip are in a state that makes them unreliable to
622       // read, so it's best to assume they cover the whole screen
623       if (layers[top_idx].flags & HWC_SKIP_LAYER ||
624           (layers[top_idx].compositionType == HWC_FRAMEBUFFER &&
625            LayersOverlap(layers[layer_index], layers[top_idx]))) {
626         layers[layer_index].compositionType = HWC_FRAMEBUFFER;
627         break;
628       }
629     }
630     if (layers[layer_index].compositionType == HWC_OVERLAY &&
631         !CanCompositeLayer(layers[layer_index])) {
632       layers[layer_index].compositionType = HWC_FRAMEBUFFER;
633     }
634     if (layers[layer_index].compositionType == HWC_OVERLAY) {
635       ++composited_layers_count;
636     }
637   }
638   return composited_layers_count;
639 }
640 
SetLayers(size_t num_layers,hwc_layer_1_t * layers)641 int CpuComposer::SetLayers(size_t num_layers, hwc_layer_1_t* layers) {
642   int targetFbs = 0;
643   int buffer_idx = screen_view_->NextBuffer();
644 
645   // The framebuffer target layer should be composed if at least one layers was
646   // marked HWC_FRAMEBUFFER or if it's the only layer in the composition
647   // (unlikely)
648   bool fb_target = true;
649   for (size_t idx = 0; idx < num_layers; idx++) {
650     if (layers[idx].compositionType == HWC_FRAMEBUFFER) {
651       // At least one was found
652       fb_target = true;
653       break;
654     }
655     if (layers[idx].compositionType == HWC_OVERLAY) {
656       // Not the only layer in the composition
657       fb_target = false;
658     }
659   }
660 
661   // When the framebuffer target needs to be composed, it has to go first.
662   if (fb_target) {
663     for (size_t idx = 0; idx < num_layers; idx++) {
664       if (IS_TARGET_FRAMEBUFFER(layers[idx].compositionType)) {
665         CompositeLayer(&layers[idx], buffer_idx);
666         break;
667       }
668     }
669   }
670 
671   for (size_t idx = 0; idx < num_layers; idx++) {
672     if (IS_TARGET_FRAMEBUFFER(layers[idx].compositionType)) {
673       ++targetFbs;
674     }
675     if (layers[idx].compositionType == HWC_OVERLAY &&
676         !(layers[idx].flags & HWC_SKIP_LAYER)) {
677       CompositeLayer(&layers[idx], buffer_idx);
678     }
679   }
680   if (targetFbs != 1) {
681     ALOGW("Saw %zu layers, posted=%d", num_layers, targetFbs);
682   }
683   screen_view_->Broadcast(buffer_idx);
684   return 0;
685 }
686 
RotateTmpBuffer(unsigned int order)687 uint8_t* CpuComposer::RotateTmpBuffer(unsigned int order) {
688   return &tmp_buffer_[(order % kNumTmpBufferPieces) * tmp_buffer_.size() /
689                       kNumTmpBufferPieces];
690 }
691 
GetSpecialTmpBuffer(size_t needed_size)692 uint8_t* CpuComposer::GetSpecialTmpBuffer(size_t needed_size) {
693   special_tmp_buffer_.resize(needed_size);
694   return &special_tmp_buffer_[0];
695 }
696 
697 }  // namespace cvd
698