1 /* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 *  * Redistributions of source code must retain the above copyright
7 *    notice, this list of conditions and the following disclaimer.
8 *  * Redistributions in binary form must reproduce the above
9 *    copyright notice, this list of conditions and the following
10 *    disclaimer in the documentation and/or other materials provided
11 *    with the distribution.
12 *  * Neither the name of The Linux Foundation nor the names of its
13 *    contributors may be used to endorse or promote products derived
14 *    from this software without specific prior written permission.
15 *
16 *
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 
29 * Portions formerly licensed under Apache License, Version 2.0, are re licensed
30 * under section 4 of Apache License, Version 2.0.
31 
32 * Copyright (C) 2010 The Android Open Source Project
33 
34 * Not a Contribution.
35 
36 * Licensed under the Apache License, Version 2.0 (the "License");
37 * you may not use this file except in compliance with the License.
38 * You may obtain a copy of the License at
39 
40 * http://www.apache.org/licenses/LICENSE-2.0
41 
42 * Unless required by applicable law or agreed to in writing, software
43 * distributed under the License is distributed on an "AS IS" BASIS,
44 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
45 * See the License for the specific language governing permissions and
46 * limitations under the License.
47 */
48 
49 #include <hardware/hardware.h>
50 #include <sync/sync.h>
51 #include <copybit.h>
52 #include <memalloc.h>
53 #include <alloc_controller.h>
54 #include <gr.h>
55 
56 #include <utils/constants.h>
57 #include <utils/rect.h>
58 #include <utils/formats.h>
59 
60 #include "blit_engine_c2d.h"
61 #include "hwc_debugger.h"
62 
63 #define __CLASS__ "BlitEngineC2D"
64 
65 // TODO(user): Remove pragma after fixing sign conversion errors
66 #if defined(__clang__)
67 #pragma clang diagnostic push
68 #pragma clang diagnostic ignored "-Wsign-conversion"
69 #endif
70 
71 namespace sdm {
72 
73 
RegionIterator(LayerRectArray rect)74 BlitEngineC2d::RegionIterator::RegionIterator(LayerRectArray rect) {
75   rect_array = rect;
76   r.end = INT(rect.count);
77   r.current = 0;
78   this->next = iterate;
79 }
80 
iterate(copybit_region_t const * self,copybit_rect_t * rect)81 int BlitEngineC2d::RegionIterator::iterate(copybit_region_t const *self, copybit_rect_t *rect) {
82   if (!self || !rect) {
83     DLOGE("iterate invalid parameters");
84     return 0;
85   }
86 
87   RegionIterator const *me = static_cast<RegionIterator const*>(self);
88   if (me->r.current != me->r.end) {
89     rect->l = INT(me->rect_array.rect[me->r.current].left);
90     rect->t = INT(me->rect_array.rect[me->r.current].top);
91     rect->r = INT(me->rect_array.rect[me->r.current].right);
92     rect->b = INT(me->rect_array.rect[me->r.current].bottom);
93     me->r.current++;
94     return 1;
95   }
96   return 0;
97 }
98 
BlitEngineC2d()99 BlitEngineC2d::BlitEngineC2d() {
100   for (uint32_t i = 0; i < kNumBlitTargetBuffers; i++) {
101     blit_target_buffer_[i] = NULL;
102     release_fence_fd_[i] = -1;
103   }
104 
105   HWCDebugHandler::Get()->GetProperty("persist.hwc.blit.comp", &blit_supported_);
106 }
107 
~BlitEngineC2d()108 BlitEngineC2d::~BlitEngineC2d() {
109   if (blit_engine_c2d_) {
110     copybit_close(blit_engine_c2d_);
111     blit_engine_c2d_ = NULL;
112   }
113   FreeBlitTargetBuffers();
114 }
115 
Init()116 int BlitEngineC2d::Init() {
117   if (!blit_supported_) {
118     return -1;
119   }
120 
121   hw_module_t const *module;
122   if (hw_get_module("copybit", &module) == 0) {
123     if (copybit_open(module, &blit_engine_c2d_) < 0) {
124       DLOGI("CopyBitC2D Open failed.");
125       return -1;
126     }
127     DLOGI("Opened Copybit Module");
128   } else {
129     DLOGI("Copybit HW Module not found");
130     return -1;
131   }
132 
133   return 0;
134 }
135 
DeInit()136 void BlitEngineC2d::DeInit() {
137   FreeBlitTargetBuffers();
138   if (blit_engine_c2d_) {
139     copybit_close(blit_engine_c2d_);
140     blit_engine_c2d_ = NULL;
141   }
142 }
143 
AllocateBlitTargetBuffers(uint32_t width,uint32_t height,uint32_t format,uint32_t usage)144 int BlitEngineC2d::AllocateBlitTargetBuffers(uint32_t width, uint32_t height, uint32_t format,
145                                              uint32_t usage) {
146   int status = 0;
147   if (width <= 0 || height <= 0) {
148     return false;
149   }
150 
151   if (blit_target_buffer_[0]) {
152     // Free and reallocate the buffers if the w/h changes
153     if (INT(width) != blit_target_buffer_[0]->width ||
154         INT(height) != blit_target_buffer_[0]->height) {
155       FreeBlitTargetBuffers();
156     }
157   }
158 
159   for (uint32_t i = 0; i < kNumBlitTargetBuffers; i++) {
160     if (blit_target_buffer_[i] == NULL) {
161       status = alloc_buffer(&blit_target_buffer_[i], width, height, format, usage);
162     }
163     if (status < 0) {
164       DLOGE("Allocation of Blit target Buffer failed");
165       FreeBlitTargetBuffers();
166       break;
167     }
168   }
169 
170   return status;
171 }
172 
FreeBlitTargetBuffers()173 void BlitEngineC2d::FreeBlitTargetBuffers() {
174   for (uint32_t i = 0; i < kNumBlitTargetBuffers; i++) {
175     private_handle_t **target_buffer = &blit_target_buffer_[i];
176     if (*target_buffer) {
177       // Free the valid fence
178       if (release_fence_fd_[i] >= 0) {
179         close(release_fence_fd_[i]);
180         release_fence_fd_[i] = -1;
181       }
182       free_buffer(*target_buffer);
183       *target_buffer = NULL;
184     }
185   }
186 }
187 
ClearTargetBuffer(private_handle_t * hnd,const LayerRect & rect)188 int BlitEngineC2d::ClearTargetBuffer(private_handle_t* hnd, const LayerRect& rect) {
189   int status = 0;
190   copybit_rect_t clear_rect = {INT(rect.left), INT(rect.top), INT(rect.right), INT(rect.bottom)};
191 
192   copybit_image_t buffer;
193   buffer.w = ALIGN((hnd->width), 32);
194   buffer.h = hnd->height;
195   buffer.format = hnd->format;
196   buffer.base = reinterpret_cast<void *>(hnd->base);
197   buffer.handle = reinterpret_cast<native_handle_t *>(hnd);
198   int dst_format_mode = COPYBIT_LINEAR;
199   if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
200     dst_format_mode = COPYBIT_UBWC_COMPRESSED;
201   }
202   blit_engine_c2d_->set_parameter(blit_engine_c2d_, COPYBIT_DST_FORMAT_MODE, dst_format_mode);
203 
204   status = blit_engine_c2d_->clear(blit_engine_c2d_, &buffer, &clear_rect);
205   return status;
206 }
207 
PostCommit(LayerStack * layer_stack)208 void BlitEngineC2d::PostCommit(LayerStack *layer_stack) {
209   int fence_fd = -1;
210   uint32_t count = 0;
211   int fd = -1;
212 
213   for (uint32_t i = blit_target_start_index_-2; (i > 0) && (count < num_blit_target_); i--) {
214     Layer &layer = layer_stack->layers[i];
215     LayerBuffer *layer_buffer = layer.input_buffer;
216     if (layer.composition == kCompositionBlit) {
217       int index = blit_target_start_index_ + count;
218       layer_buffer->release_fence_fd = layer_stack->layers[index].input_buffer->release_fence_fd;
219       fence_fd = layer_buffer->release_fence_fd;
220       close(layer_buffer->acquire_fence_fd);
221       layer_buffer->acquire_fence_fd = -1;
222       layer_stack->layers[index].input_buffer->release_fence_fd = -1;
223       fd = layer_stack->layers[index].input_buffer->acquire_fence_fd;
224       layer_stack->layers[index].input_buffer->acquire_fence_fd = -1;
225       count++;
226     }
227   }
228 
229   if (fd >= 0) {
230     // Close the C2D fence FD
231     close(fd);
232   }
233   SetReleaseFence(fence_fd);
234 }
235 
236 // Sync wait to close the previous fd
SetReleaseFence(int fd)237 void BlitEngineC2d::SetReleaseFence(int fd) {
238   if (release_fence_fd_[current_blit_target_index_] >= 0) {
239     int ret = -1;
240     ret = sync_wait(release_fence_fd_[current_blit_target_index_], 1000);
241     if (ret < 0) {
242       DLOGE("sync_wait error! errno = %d, err str = %s", errno, strerror(errno));
243     }
244     close(release_fence_fd_[current_blit_target_index_]);
245   }
246   release_fence_fd_[current_blit_target_index_] = dup(fd);
247 }
248 
BlitActive()249 bool BlitEngineC2d::BlitActive() {
250   return blit_active_;
251 }
252 
SetFrameDumpConfig(uint32_t count)253 void BlitEngineC2d::SetFrameDumpConfig(uint32_t count) {
254   dump_frame_count_ = count;
255   dump_frame_index_ = 0;
256 }
257 
Prepare(LayerStack * layer_stack)258 int BlitEngineC2d::Prepare(LayerStack *layer_stack) {
259   blit_target_start_index_ = 0;
260 
261   uint32_t gpu_target_index = layer_stack->layer_count-1;
262   uint32_t i = INT(layer_stack->layer_count-1);
263 
264   for (i = 0; i < layer_stack->layer_count; i++) {
265     Layer &layer = layer_stack->layers[i];
266     if (!blit_supported_) {
267       return -1;
268     }
269 
270     // No 10 bit support for C2D
271     if (Is10BitFormat(layer.input_buffer->format)) {
272       return -1;
273     }
274 
275     if (layer.composition == kCompositionGPUTarget) {
276       // Need FBT size for allocating buffers
277       gpu_target_index = i;
278       break;
279     }
280   }
281 
282   if ((layer_stack->layer_count-1) == gpu_target_index) {
283     // No blit target layer
284     return -1;
285   }
286 
287   blit_target_start_index_ = ++i;
288   num_blit_target_ = layer_stack->layer_count - blit_target_start_index_;
289 
290   LayerBuffer *layer_buffer = layer_stack->layers[gpu_target_index].input_buffer;
291   int fbwidth = INT(layer_buffer->width);
292   int fbheight = INT(layer_buffer->height);
293   if ((fbwidth < 0) || (fbheight < 0)) {
294     return -1;
295   }
296 
297   current_blit_target_index_ = (current_blit_target_index_ + 1) % kNumBlitTargetBuffers;
298   int k = blit_target_start_index_;
299 
300   for (uint32_t j = 0; j < num_blit_target_; j++, k++) {
301     Layer &layer = layer_stack->layers[k];
302     LayerBuffer *layer_buffer = layer.input_buffer;
303 
304     // Set the buffer height and width
305     layer_buffer->width = fbwidth;
306     layer_buffer->height = fbheight/3;
307 
308     layer.plane_alpha = 0xFF;
309     layer.blending = kBlendingOpaque;
310     layer.composition = kCompositionBlitTarget;
311     layer.frame_rate = layer_stack->layers[gpu_target_index].frame_rate;
312   }
313 
314   return 0;
315 }
316 
PreCommit(hwc_display_contents_1_t * content_list,LayerStack * layer_stack)317 int BlitEngineC2d::PreCommit(hwc_display_contents_1_t *content_list, LayerStack *layer_stack) {
318   int status = 0;
319   uint32_t num_app_layers = (uint32_t) content_list->numHwLayers-1;
320   int target_width = 0;
321   int target_height = 0;
322   uint32_t processed_blit = 0;
323   LayerRect dst_rects[kMaxBlitTargetLayers];
324   bool blit_needed = false;
325   uint32_t usage = 0;
326 
327   if (!num_app_layers) {
328     return -1;
329   }
330 
331   for (uint32_t i = num_app_layers-1; (i > 0) && (processed_blit < num_blit_target_); i--) {
332     Layer &layer = layer_stack->layers[i];
333     if (layer.composition != kCompositionBlit) {
334       continue;
335     }
336     blit_needed = true;
337     layer_stack->flags.attributes_changed = true;
338 
339     Layer &blit_layer = layer_stack->layers[blit_target_start_index_ + processed_blit];
340     LayerRect &blit_src_rect = blit_layer.src_rect;
341     int width = INT(layer.dst_rect.right - layer.dst_rect.left);
342     int height = INT(layer.dst_rect.bottom - layer.dst_rect.top);
343     usage = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP | GRALLOC_USAGE_HW_TEXTURE;
344     if (blit_engine_c2d_->get(blit_engine_c2d_, COPYBIT_UBWC_SUPPORT) > 0) {
345       usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
346     }
347     // TODO(user): FrameBuffer is assumed to be RGBA
348     AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width, height,
349                                  INT(HAL_PIXEL_FORMAT_RGBA_8888), usage, width, height);
350 
351     target_width = MAX(target_width, width);
352     target_height += height;
353 
354     // Left will be zero always
355     dst_rects[processed_blit].top = FLOAT(target_height - height);
356     dst_rects[processed_blit].right = dst_rects[processed_blit].left +
357                                       (layer.dst_rect.right - layer.dst_rect.left);
358     dst_rects[processed_blit].bottom = (dst_rects[processed_blit].top +
359                                       (layer.dst_rect.bottom - layer.dst_rect.top));
360     blit_src_rect = dst_rects[processed_blit];
361     processed_blit++;
362   }
363 
364   // Allocate a single buffer of RGBA8888 format
365   if (blit_needed && (AllocateBlitTargetBuffers(target_width, target_height,
366                                                 HAL_PIXEL_FORMAT_RGBA_8888, usage) < 0)) {
367       status = -1;
368       return status;
369   }
370 
371   if (blit_needed) {
372     for (uint32_t j = 0; j < num_blit_target_; j++) {
373       Layer &layer = layer_stack->layers[j + content_list->numHwLayers];
374       private_handle_t *target_buffer = blit_target_buffer_[current_blit_target_index_];
375       // Set the fd information
376       if (layer.input_buffer) {
377         layer.input_buffer->width = target_width;
378         layer.input_buffer->height = target_height;
379         if (target_buffer->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
380           layer.input_buffer->format = kFormatRGBA8888Ubwc;
381         }
382         layer.input_buffer->planes[0].fd = target_buffer->fd;
383         layer.input_buffer->planes[0].offset = 0;
384         layer.input_buffer->planes[0].stride = target_buffer->width;
385       }
386     }
387   }
388 
389   return status;
390 }
391 
Commit(hwc_display_contents_1_t * content_list,LayerStack * layer_stack)392 int BlitEngineC2d::Commit(hwc_display_contents_1_t *content_list, LayerStack *layer_stack) {
393   int fd = -1;
394   int status = 0;
395   bool hybrid_present = false;
396   uint32_t num_app_layers = (uint32_t) content_list->numHwLayers-1;
397   private_handle_t *target_buffer = blit_target_buffer_[current_blit_target_index_];
398   blit_active_ = false;
399 
400   if (!num_app_layers) {
401     return -1;
402   }
403 
404   // if not Blit Targets return
405   for (uint32_t i = 0; i < num_app_layers; i++) {
406     Layer &layer = layer_stack->layers[i];
407     if (layer.composition == kCompositionHybrid || layer.composition == kCompositionBlit) {
408       hybrid_present = true;
409     }
410   }
411 
412   if (!hybrid_present) {
413     return status;
414   }
415 
416   // Clear blit target buffer
417   LayerRect clear_rect;
418   clear_rect.left =  0;
419   clear_rect.top = 0;
420   clear_rect.right = FLOAT(target_buffer->width);
421   clear_rect.bottom = FLOAT(target_buffer->height);
422   ClearTargetBuffer(target_buffer, clear_rect);
423 
424   int copybit_layer_count = 0;
425   uint32_t processed_blit = 0;
426   for (uint32_t i = num_app_layers-1; (i > 0) && (processed_blit < num_blit_target_) &&
427       (status == 0); i--) {
428     Layer &layer = layer_stack->layers[i];
429     if (layer.composition != kCompositionBlit) {
430       continue;
431     }
432 
433     for (uint32_t k = 0; k <= i; k++) {
434       Layer &bottom_layer = layer_stack->layers[k];
435       LayerBuffer *layer_buffer = bottom_layer.input_buffer;
436       // if layer below the blit layer does not intersect, ignore that layer
437       LayerRect inter_sect = Intersection(layer.dst_rect, bottom_layer.dst_rect);
438       if (bottom_layer.composition != kCompositionHybrid && !IsValid(inter_sect)) {
439         continue;
440       }
441       if (bottom_layer.composition == kCompositionGPU ||
442           bottom_layer.composition == kCompositionSDE ||
443           bottom_layer.composition == kCompositionGPUTarget) {
444         continue;
445       }
446 
447       // For each layer marked as Hybrid, wait for acquire fence and then blit using the C2D
448       if (layer_buffer->acquire_fence_fd >= 0) {
449         // Wait for acquire fence on the App buffers.
450         if (sync_wait(layer_buffer->acquire_fence_fd, 1000) < 0) {
451           DLOGE("sync_wait error!! error no = %d err str = %s", errno, strerror(errno));
452         }
453         layer_buffer->acquire_fence_fd = -1;
454       }
455       hwc_layer_1_t *hwc_layer = &content_list->hwLayers[k];
456       LayerRect src_rect = bottom_layer.blit_regions.rect[processed_blit];
457       Layer &blit_layer = layer_stack->layers[blit_target_start_index_ + processed_blit];
458       LayerRect dest_rect = blit_layer.src_rect;
459       int ret_val = DrawRectUsingCopybit(hwc_layer, &bottom_layer, src_rect, dest_rect);
460       copybit_layer_count++;
461       if (ret_val < 0) {
462         copybit_layer_count = 0;
463         DLOGE("DrawRectUsingCopyBit failed");
464         status = -1;
465         break;
466       }
467     }
468     processed_blit++;
469   }
470 
471   if (copybit_layer_count) {
472     blit_active_ = true;
473     blit_engine_c2d_->flush_get_fence(blit_engine_c2d_, &fd);
474   }
475 
476   if (blit_active_) {
477     // dump the render buffer
478     DumpBlitTargetBuffer(fd);
479 
480     // Set the fd to the LayerStack BlitTargets fd
481     for (uint32_t k = blit_target_start_index_; k < layer_stack->layer_count; k++) {
482       Layer &layer = layer_stack->layers[k];
483       LayerBuffer *layer_buffer = layer.input_buffer;
484       layer_buffer->acquire_fence_fd = fd;
485     }
486   }
487 
488   return status;
489 }
490 
DrawRectUsingCopybit(hwc_layer_1_t * hwc_layer,Layer * layer,LayerRect blit_rect,LayerRect blit_dest_Rect)491 int BlitEngineC2d::DrawRectUsingCopybit(hwc_layer_1_t *hwc_layer, Layer *layer,
492                                         LayerRect blit_rect, LayerRect blit_dest_Rect) {
493   private_handle_t *target_buffer = blit_target_buffer_[current_blit_target_index_];
494   const private_handle_t *hnd = static_cast<const private_handle_t *>(hwc_layer->handle);
495   LayerBuffer *layer_buffer = layer->input_buffer;
496 
497   // Set the Copybit Source
498   copybit_image_t src;
499   src.handle = const_cast<native_handle_t *>(hwc_layer->handle);
500   src.w = hnd->width;
501   src.h = hnd->height;
502   src.base = reinterpret_cast<void *>(hnd->base);
503   src.format = hnd->format;
504   src.horiz_padding = 0;
505   src.vert_padding = 0;
506 
507   // Copybit source rect
508   copybit_rect_t src_rect = {INT(blit_rect.left), INT(blit_rect.top), INT(blit_rect.right),
509                             INT(blit_rect.bottom)};
510 
511   // Copybit destination rect
512   copybit_rect_t dst_rect = {INT(blit_dest_Rect.left), INT(blit_dest_Rect.top),
513                             INT(blit_dest_Rect.right), INT(blit_dest_Rect.bottom)};
514 
515   // Copybit destination buffer
516   copybit_image_t dst;
517   dst.handle = static_cast<native_handle_t *>(target_buffer);
518   dst.w = ALIGN(target_buffer->width, 32);
519   dst.h = ALIGN((target_buffer->height), 32);
520   dst.base = reinterpret_cast<void *>(target_buffer->base);
521   dst.format = target_buffer->format;
522 
523   // Copybit region is the destRect
524   LayerRect region_rect;
525   region_rect.left = FLOAT(dst_rect.l);
526   region_rect.top = FLOAT(dst_rect.t);
527   region_rect.right = FLOAT(dst_rect.r);
528   region_rect.bottom = FLOAT(dst_rect.b);
529 
530   LayerRectArray region;
531   region.count = 1;
532   region.rect  = &region_rect;
533   RegionIterator copybitRegion(region);
534   int acquireFd = layer_buffer->acquire_fence_fd;
535 
536   // FRAMEBUFFER_WIDTH/HEIGHT for c2d is the target buffer w/h
537   blit_engine_c2d_->set_parameter(blit_engine_c2d_, COPYBIT_FRAMEBUFFER_WIDTH,
538                                   target_buffer->width);
539   blit_engine_c2d_->set_parameter(blit_engine_c2d_, COPYBIT_FRAMEBUFFER_HEIGHT,
540                                   target_buffer->height);
541   int transform = 0;
542   if (layer->transform.rotation != 0.0f) transform |= COPYBIT_TRANSFORM_ROT_90;
543   if (layer->transform.flip_horizontal) transform |= COPYBIT_TRANSFORM_FLIP_H;
544   if (layer->transform.flip_vertical) transform |= COPYBIT_TRANSFORM_FLIP_V;
545   blit_engine_c2d_->set_parameter(blit_engine_c2d_, COPYBIT_TRANSFORM, transform);
546   blit_engine_c2d_->set_parameter(blit_engine_c2d_, COPYBIT_PLANE_ALPHA, hwc_layer->planeAlpha);
547   blit_engine_c2d_->set_parameter(blit_engine_c2d_, COPYBIT_BLEND_MODE, hwc_layer->blending);
548   blit_engine_c2d_->set_parameter(blit_engine_c2d_, COPYBIT_DITHER,
549     (dst.format == HAL_PIXEL_FORMAT_RGB_565) ? COPYBIT_ENABLE : COPYBIT_DISABLE);
550 
551   int src_format_mode = COPYBIT_LINEAR;
552   if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
553     src_format_mode = COPYBIT_UBWC_COMPRESSED;
554   }
555   blit_engine_c2d_->set_parameter(blit_engine_c2d_, COPYBIT_SRC_FORMAT_MODE, src_format_mode);
556 
557   blit_engine_c2d_->set_sync(blit_engine_c2d_, acquireFd);
558   int err = blit_engine_c2d_->stretch(blit_engine_c2d_, &dst, &src, &dst_rect, &src_rect,
559                                       &copybitRegion);
560 
561   if (err < 0) {
562     DLOGE("copybit stretch failed");
563   }
564 
565   return err;
566 }
567 
DumpBlitTargetBuffer(int fd)568 void BlitEngineC2d::DumpBlitTargetBuffer(int fd) {
569   if (!dump_frame_count_) {
570     return;
571   }
572 
573   private_handle_t *target_buffer = blit_target_buffer_[current_blit_target_index_];
574 
575   if (fd >= 0) {
576     int error = sync_wait(fd, 1000);
577     if (error < 0) {
578       DLOGW("sync_wait error errno = %d, desc = %s", errno, strerror(errno));
579       return;
580     }
581   }
582 
583   char dump_file_name[PATH_MAX];
584   size_t result = 0;
585   snprintf(dump_file_name, sizeof(dump_file_name), "/data/misc/display/frame_dump_primary"
586            "/blit_target_%d.raw", (dump_frame_index_));
587   FILE* fp = fopen(dump_file_name, "w+");
588   if (fp) {
589     result = fwrite(reinterpret_cast<void *>(target_buffer->base), target_buffer->size, 1, fp);
590     fclose(fp);
591   }
592   dump_frame_count_--;
593   dump_frame_index_++;
594 }
595 
596 }  // namespace sdm
597 #if defined(__clang__)
598 #pragma clang diagnostic pop
599 #endif
600 
601