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