1 /*
2 * Copyright (C) 2010 The Android Open Source Project
3 * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
4 *
5 * Not a Contribution, Apache license notifications and license are retained
6 * for attribution purposes only.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21 #define DEBUG_COPYBIT 0
22 #include <sync/sync.h>
23 #include <copybit.h>
24 #include <utils/Timers.h>
25 #include <mdp_version.h>
26 #include "hwc_copybit.h"
27 #include "comptype.h"
28 #include "gr.h"
29
30 namespace qhwc {
31
32 struct range {
33 int current;
34 int end;
35 };
36 struct region_iterator : public copybit_region_t {
37
region_iteratorqhwc::region_iterator38 region_iterator(hwc_region_t region) {
39 mRegion = region;
40 r.end = region.numRects;
41 r.current = 0;
42 this->next = iterate;
43 }
44
45 private:
iterateqhwc::region_iterator46 static int iterate(copybit_region_t const * self, copybit_rect_t* rect){
47 if (!self || !rect) {
48 ALOGE("iterate invalid parameters");
49 return 0;
50 }
51
52 region_iterator const* me =
53 static_cast<region_iterator const*>(self);
54 if (me->r.current != me->r.end) {
55 rect->l = me->mRegion.rects[me->r.current].left;
56 rect->t = me->mRegion.rects[me->r.current].top;
57 rect->r = me->mRegion.rects[me->r.current].right;
58 rect->b = me->mRegion.rects[me->r.current].bottom;
59 me->r.current++;
60 return 1;
61 }
62 return 0;
63 }
64
65 hwc_region_t mRegion;
66 mutable range r;
67 };
68
reset()69 void CopyBit::reset() {
70 mIsModeOn = false;
71 mCopyBitDraw = false;
72 }
73
canUseCopybitForYUV(hwc_context_t * ctx)74 bool CopyBit::canUseCopybitForYUV(hwc_context_t *ctx) {
75 // return true for non-overlay targets
76 if(ctx->mMDP.hasOverlay && ctx->mMDP.version >= qdutils::MDP_V4_0) {
77 return false;
78 }
79 return true;
80 }
81
canUseCopybitForRGB(hwc_context_t * ctx,hwc_display_contents_1_t * list,int dpy)82 bool CopyBit::canUseCopybitForRGB(hwc_context_t *ctx,
83 hwc_display_contents_1_t *list,
84 int dpy) {
85 int compositionType = qdutils::QCCompositionType::
86 getInstance().getCompositionType();
87
88 if (compositionType & qdutils::COMPOSITION_TYPE_DYN) {
89 // DYN Composition:
90 // use copybit, if (TotalRGBRenderArea < threashold * FB Area)
91 // this is done based on perf inputs in ICS
92 // TODO: Above condition needs to be re-evaluated in JB
93 int fbWidth = ctx->dpyAttr[dpy].xres;
94 int fbHeight = ctx->dpyAttr[dpy].yres;
95 unsigned int fbArea = (fbWidth * fbHeight);
96 unsigned int renderArea = getRGBRenderingArea(list);
97 ALOGD_IF (DEBUG_COPYBIT, "%s:renderArea %u, fbArea %u",
98 __FUNCTION__, renderArea, fbArea);
99 if (renderArea < (mDynThreshold * fbArea)) {
100 return true;
101 }
102 } else if ((compositionType & qdutils::COMPOSITION_TYPE_MDP)) {
103 // MDP composition, use COPYBIT always
104 return true;
105 } else if ((compositionType & qdutils::COMPOSITION_TYPE_C2D)) {
106 // C2D composition, use COPYBIT
107 return true;
108 }
109 return false;
110 }
111
getRGBRenderingArea(const hwc_display_contents_1_t * list)112 unsigned int CopyBit::getRGBRenderingArea
113 (const hwc_display_contents_1_t *list) {
114 //Calculates total rendering area for RGB layers
115 unsigned int renderArea = 0;
116 unsigned int w=0, h=0;
117 // Skipping last layer since FrameBuffer layer should not affect
118 // which composition to choose
119 for (unsigned int i=0; i<list->numHwLayers -1; i++) {
120 private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle;
121 if (hnd) {
122 if (BUFFER_TYPE_UI == hnd->bufferType) {
123 getLayerResolution(&list->hwLayers[i], w, h);
124 renderArea += (w*h);
125 }
126 }
127 }
128 return renderArea;
129 }
130
prepare(hwc_context_t * ctx,hwc_display_contents_1_t * list,int dpy)131 bool CopyBit::prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list,
132 int dpy) {
133
134 if(mEngine == NULL) {
135 // No copybit device found - cannot use copybit
136 return false;
137 }
138 int compositionType = qdutils::QCCompositionType::
139 getInstance().getCompositionType();
140
141 if ((compositionType == qdutils::COMPOSITION_TYPE_GPU) ||
142 (compositionType == qdutils::COMPOSITION_TYPE_CPU)) {
143 //GPU/CPU composition, don't change layer composition type
144 return true;
145 }
146
147 if(!(validateParams(ctx, list))) {
148 ALOGE("%s:Invalid Params", __FUNCTION__);
149 return false;
150 }
151
152 if(ctx->listStats[dpy].skipCount) {
153 //GPU will be anyways used
154 return false;
155 }
156
157 if (ctx->listStats[dpy].numAppLayers > MAX_NUM_APP_LAYERS) {
158 // Reached max layers supported by HWC.
159 return false;
160 }
161
162 bool useCopybitForYUV = canUseCopybitForYUV(ctx);
163 bool useCopybitForRGB = canUseCopybitForRGB(ctx, list, dpy);
164 LayerProp *layerProp = ctx->layerProp[dpy];
165 size_t fbLayerIndex = ctx->listStats[dpy].fbLayerIndex;
166 hwc_layer_1_t *fbLayer = &list->hwLayers[fbLayerIndex];
167 private_handle_t *fbHnd = (private_handle_t *)fbLayer->handle;
168
169
170 // Following are MDP3 limitations for which we
171 // need to fallback to GPU composition:
172 // 1. HW issues with mdp3 and rotation.
173 // 2. Plane alpha is not supported by MDP3.
174 if (qdutils::MDPVersion::getInstance().getMDPVersion() < 400) {
175 for (int i = ctx->listStats[dpy].numAppLayers-1; i >= 0 ; i--) {
176 hwc_layer_1_t *layer = (hwc_layer_1_t *) &list->hwLayers[i];
177 if ((layer->transform & (HAL_TRANSFORM_FLIP_H |
178 HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90)) &&
179 ((layer->displayFrame.bottom - layer->displayFrame.top) % 16 ||
180 (layer->displayFrame.right - layer->displayFrame.left) % 16))
181 return true;
182 if (layer->planeAlpha != 0xFF)
183 return true;
184 }
185 }
186
187 //Allocate render buffers if they're not allocated
188 if (useCopybitForYUV || useCopybitForRGB) {
189 int ret = allocRenderBuffers(fbHnd->width,
190 fbHnd->height,
191 fbHnd->format);
192 if (ret < 0) {
193 return false;
194 } else {
195 mCurRenderBufferIndex = (mCurRenderBufferIndex + 1) %
196 NUM_RENDER_BUFFERS;
197 }
198 }
199
200 // We cannot mix copybit layer with layers marked to be drawn on FB
201 if (!useCopybitForYUV && ctx->listStats[dpy].yuvCount)
202 return true;
203
204 // numAppLayers-1, as we iterate till 0th layer index
205 for (int i = ctx->listStats[dpy].numAppLayers-1; i >= 0 ; i--) {
206 private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle;
207
208 if ((hnd->bufferType == BUFFER_TYPE_VIDEO && useCopybitForYUV) ||
209 (hnd->bufferType == BUFFER_TYPE_UI && useCopybitForRGB)) {
210 layerProp[i].mFlags |= HWC_COPYBIT;
211 list->hwLayers[i].compositionType = HWC_OVERLAY;
212 mCopyBitDraw = true;
213 } else {
214 // We currently cannot mix copybit layers with layers marked to
215 // be drawn on the framebuffer or that are on the layer cache.
216 mCopyBitDraw = false;
217 //There is no need to reset layer properties here as we return in
218 //draw if mCopyBitDraw is false
219 break;
220 }
221 }
222 return true;
223 }
224
clear(private_handle_t * hnd,hwc_rect_t & rect)225 int CopyBit::clear (private_handle_t* hnd, hwc_rect_t& rect)
226 {
227 int ret = 0;
228 copybit_rect_t clear_rect = {rect.left, rect.top,
229 rect.right,
230 rect.bottom};
231
232 copybit_image_t buf;
233 buf.w = ALIGN(getWidth(hnd),32);
234 buf.h = getHeight(hnd);
235 buf.format = hnd->format;
236 buf.base = (void *)hnd->base;
237 buf.handle = (native_handle_t *)hnd;
238
239 copybit_device_t *copybit = mEngine;
240 ret = copybit->clear(copybit, &buf, &clear_rect);
241 return ret;
242 }
243
draw(hwc_context_t * ctx,hwc_display_contents_1_t * list,int dpy,int32_t * fd)244 bool CopyBit::draw(hwc_context_t *ctx, hwc_display_contents_1_t *list,
245 int dpy, int32_t *fd) {
246 // draw layers marked for COPYBIT
247 int retVal = true;
248 int copybitLayerCount = 0;
249 LayerProp *layerProp = ctx->layerProp[dpy];
250
251 if(mCopyBitDraw == false) // there is no layer marked for copybit
252 return false ;
253
254 //render buffer
255 private_handle_t *renderBuffer = getCurrentRenderBuffer();
256 if (!renderBuffer) {
257 ALOGE("%s: Render buffer layer handle is NULL", __FUNCTION__);
258 return false;
259 }
260
261 //Wait for the previous frame to complete before rendering onto it
262 if(mRelFd[0] >=0) {
263 sync_wait(mRelFd[0], 1000);
264 close(mRelFd[0]);
265 mRelFd[0] = -1;
266 }
267
268 if (ctx->mMDP.version >= qdutils::MDP_V4_0) {
269 //Clear the visible region on the render buffer
270 //XXX: Do this only when needed.
271 hwc_rect_t clearRegion;
272 getNonWormholeRegion(list, clearRegion);
273 clear(renderBuffer, clearRegion);
274 }
275 // numAppLayers-1, as we iterate from 0th layer index with HWC_COPYBIT flag
276 for (int i = 0; i <= (ctx->listStats[dpy].numAppLayers-1); i++) {
277 hwc_layer_1_t *layer = &list->hwLayers[i];
278 if(!(layerProp[i].mFlags & HWC_COPYBIT)) {
279 ALOGD_IF(DEBUG_COPYBIT, "%s: Not Marked for copybit", __FUNCTION__);
280 continue;
281 }
282 int ret = -1;
283 if (list->hwLayers[i].acquireFenceFd != -1
284 && ctx->mMDP.version >= qdutils::MDP_V4_0) {
285 // Wait for acquire Fence on the App buffers.
286 ret = sync_wait(list->hwLayers[i].acquireFenceFd, 1000);
287 if(ret < 0) {
288 ALOGE("%s: sync_wait error!! error no = %d err str = %s",
289 __FUNCTION__, errno, strerror(errno));
290 }
291 close(list->hwLayers[i].acquireFenceFd);
292 list->hwLayers[i].acquireFenceFd = -1;
293 }
294 retVal = drawLayerUsingCopybit(ctx, &(list->hwLayers[i]),
295 renderBuffer, dpy, !i);
296 copybitLayerCount++;
297 if(retVal < 0) {
298 ALOGE("%s : drawLayerUsingCopybit failed", __FUNCTION__);
299 }
300 }
301
302 if (copybitLayerCount) {
303 copybit_device_t *copybit = getCopyBitDevice();
304 // Async mode
305 copybit->flush_get_fence(copybit, fd);
306 }
307 return true;
308 }
309
drawLayerUsingCopybit(hwc_context_t * dev,hwc_layer_1_t * layer,private_handle_t * renderBuffer,int dpy,bool isFG)310 int CopyBit::drawLayerUsingCopybit(hwc_context_t *dev, hwc_layer_1_t *layer,
311 private_handle_t *renderBuffer, int dpy, bool isFG)
312 {
313 hwc_context_t* ctx = (hwc_context_t*)(dev);
314 int err = 0, acquireFd;
315 if(!ctx) {
316 ALOGE("%s: null context ", __FUNCTION__);
317 return -1;
318 }
319
320 private_handle_t *hnd = (private_handle_t *)layer->handle;
321 if(!hnd) {
322 ALOGE("%s: invalid handle", __FUNCTION__);
323 return -1;
324 }
325
326 private_handle_t *fbHandle = (private_handle_t *)renderBuffer;
327 if(!fbHandle) {
328 ALOGE("%s: Framebuffer handle is NULL", __FUNCTION__);
329 return -1;
330 }
331
332 // Set the copybit source:
333 copybit_image_t src;
334 src.w = getWidth(hnd);
335 src.h = getHeight(hnd);
336 src.format = hnd->format;
337 src.base = (void *)hnd->base;
338 src.handle = (native_handle_t *)layer->handle;
339 src.horiz_padding = src.w - getWidth(hnd);
340 // Initialize vertical padding to zero for now,
341 // this needs to change to accomodate vertical stride
342 // if needed in the future
343 src.vert_padding = 0;
344
345 // Copybit source rect
346 hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
347 copybit_rect_t srcRect = {sourceCrop.left, sourceCrop.top,
348 sourceCrop.right,
349 sourceCrop.bottom};
350
351 // Copybit destination rect
352 hwc_rect_t displayFrame = layer->displayFrame;
353 copybit_rect_t dstRect = {displayFrame.left, displayFrame.top,
354 displayFrame.right,
355 displayFrame.bottom};
356
357 // Copybit dst
358 copybit_image_t dst;
359 dst.w = ALIGN(fbHandle->width,32);
360 dst.h = fbHandle->height;
361 dst.format = fbHandle->format;
362 dst.base = (void *)fbHandle->base;
363 dst.handle = (native_handle_t *)fbHandle;
364
365 copybit_device_t *copybit = mEngine;
366
367 int32_t screen_w = displayFrame.right - displayFrame.left;
368 int32_t screen_h = displayFrame.bottom - displayFrame.top;
369 int32_t src_crop_width = sourceCrop.right - sourceCrop.left;
370 int32_t src_crop_height = sourceCrop.bottom -sourceCrop.top;
371
372 // Copybit dst
373 float copybitsMaxScale =
374 (float)copybit->get(copybit,COPYBIT_MAGNIFICATION_LIMIT);
375 float copybitsMinScale =
376 (float)copybit->get(copybit,COPYBIT_MINIFICATION_LIMIT);
377
378 if((layer->transform == HWC_TRANSFORM_ROT_90) ||
379 (layer->transform == HWC_TRANSFORM_ROT_270)) {
380 //swap screen width and height
381 int tmp = screen_w;
382 screen_w = screen_h;
383 screen_h = tmp;
384 }
385 private_handle_t *tmpHnd = NULL;
386
387 if(screen_w <=0 || screen_h<=0 ||src_crop_width<=0 || src_crop_height<=0 ) {
388 ALOGE("%s: wrong params for display screen_w=%d src_crop_width=%d \
389 screen_w=%d src_crop_width=%d", __FUNCTION__, screen_w,
390 src_crop_width,screen_w,src_crop_width);
391 return -1;
392 }
393
394 float dsdx = (float)screen_w/src_crop_width;
395 float dtdy = (float)screen_h/src_crop_height;
396
397 float scaleLimitMax = copybitsMaxScale * copybitsMaxScale;
398 float scaleLimitMin = copybitsMinScale * copybitsMinScale;
399 if(dsdx > scaleLimitMax ||
400 dtdy > scaleLimitMax ||
401 dsdx < 1/scaleLimitMin ||
402 dtdy < 1/scaleLimitMin) {
403 ALOGE("%s: greater than max supported size dsdx=%f dtdy=%f \
404 scaleLimitMax=%f scaleLimitMin=%f", __FUNCTION__,dsdx,dtdy,
405 scaleLimitMax,1/scaleLimitMin);
406 return -1;
407 }
408 acquireFd = layer->acquireFenceFd;
409 if(dsdx > copybitsMaxScale ||
410 dtdy > copybitsMaxScale ||
411 dsdx < 1/copybitsMinScale ||
412 dtdy < 1/copybitsMinScale){
413 // The requested scale is out of the range the hardware
414 // can support.
415 ALOGD("%s:%d::Need to scale twice dsdx=%f, dtdy=%f,copybitsMaxScale=%f,\
416 copybitsMinScale=%f,screen_w=%d,screen_h=%d \
417 src_crop_width=%d src_crop_height=%d",__FUNCTION__,__LINE__,
418 dsdx,dtdy,copybitsMaxScale,1/copybitsMinScale,screen_w,screen_h,
419 src_crop_width,src_crop_height);
420
421 //Driver makes width and height as even
422 //that may cause wrong calculation of the ratio
423 //in display and crop.Hence we make
424 //crop width and height as even.
425 src_crop_width = (src_crop_width/2)*2;
426 src_crop_height = (src_crop_height/2)*2;
427
428 int tmp_w = src_crop_width;
429 int tmp_h = src_crop_height;
430
431 if (dsdx > copybitsMaxScale || dtdy > copybitsMaxScale ){
432 tmp_w = src_crop_width*copybitsMaxScale;
433 tmp_h = src_crop_height*copybitsMaxScale;
434 }else if (dsdx < 1/copybitsMinScale ||dtdy < 1/copybitsMinScale ){
435 tmp_w = src_crop_width/copybitsMinScale;
436 tmp_h = src_crop_height/copybitsMinScale;
437 tmp_w = (tmp_w/2)*2;
438 tmp_h = (tmp_h/2)*2;
439 }
440 ALOGD("%s:%d::tmp_w = %d,tmp_h = %d",__FUNCTION__,__LINE__,tmp_w,tmp_h);
441
442 int usage = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP;
443 int format = fbHandle->format;
444
445 // We do not want copybit to generate alpha values from nothing
446 if (format == HAL_PIXEL_FORMAT_RGBA_8888 &&
447 src.format != HAL_PIXEL_FORMAT_RGBA_8888) {
448 format = HAL_PIXEL_FORMAT_RGBX_8888;
449 }
450 if (0 == alloc_buffer(&tmpHnd, tmp_w, tmp_h, format, usage)){
451 copybit_image_t tmp_dst;
452 copybit_rect_t tmp_rect;
453 tmp_dst.w = tmp_w;
454 tmp_dst.h = tmp_h;
455 tmp_dst.format = tmpHnd->format;
456 tmp_dst.handle = tmpHnd;
457 tmp_dst.horiz_padding = src.horiz_padding;
458 tmp_dst.vert_padding = src.vert_padding;
459 tmp_rect.l = 0;
460 tmp_rect.t = 0;
461 tmp_rect.r = tmp_dst.w;
462 tmp_rect.b = tmp_dst.h;
463 //create one clip region
464 hwc_rect tmp_hwc_rect = {0,0,tmp_rect.r,tmp_rect.b};
465 hwc_region_t tmp_hwc_reg = {1,(hwc_rect_t const*)&tmp_hwc_rect};
466 region_iterator tmp_it(tmp_hwc_reg);
467 copybit->set_parameter(copybit,COPYBIT_TRANSFORM,0);
468 //TODO: once, we are able to read layer alpha, update this
469 copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 255);
470 copybit->set_sync(copybit, acquireFd);
471 err = copybit->stretch(copybit,&tmp_dst, &src, &tmp_rect,
472 &srcRect, &tmp_it);
473 if(err < 0){
474 ALOGE("%s:%d::tmp copybit stretch failed",__FUNCTION__,
475 __LINE__);
476 if(tmpHnd)
477 free_buffer(tmpHnd);
478 return err;
479 }
480 // use release fence as aquire fd for next stretch
481 if (ctx->mMDP.version < qdutils::MDP_V4_0) {
482 copybit->flush_get_fence(copybit, &acquireFd);
483 close(acquireFd);
484 acquireFd = -1;
485 }
486 // copy new src and src rect crop
487 src = tmp_dst;
488 srcRect = tmp_rect;
489 }
490 }
491 // Copybit region
492 hwc_region_t region = layer->visibleRegionScreen;
493 region_iterator copybitRegion(region);
494
495 copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_WIDTH,
496 renderBuffer->width);
497 copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_HEIGHT,
498 renderBuffer->height);
499 copybit->set_parameter(copybit, COPYBIT_TRANSFORM,
500 layer->transform);
501 //TODO: once, we are able to read layer alpha, update this
502 copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 255);
503 copybit->set_parameter(copybit, COPYBIT_BLEND_MODE,
504 layer->blending);
505 copybit->set_parameter(copybit, COPYBIT_DITHER,
506 (dst.format == HAL_PIXEL_FORMAT_RGB_565)?
507 COPYBIT_ENABLE : COPYBIT_DISABLE);
508 copybit->set_parameter(copybit, COPYBIT_FG_LAYER, isFG ?
509 COPYBIT_ENABLE : COPYBIT_DISABLE);
510
511 copybit->set_parameter(copybit, COPYBIT_BLIT_TO_FRAMEBUFFER,
512 COPYBIT_ENABLE);
513 copybit->set_sync(copybit, acquireFd);
514 err = copybit->stretch(copybit, &dst, &src, &dstRect, &srcRect,
515 ©bitRegion);
516 copybit->set_parameter(copybit, COPYBIT_BLIT_TO_FRAMEBUFFER,
517 COPYBIT_DISABLE);
518
519 if(tmpHnd) {
520 if (ctx->mMDP.version < qdutils::MDP_V4_0){
521 int ret = -1, releaseFd;
522 // we need to wait for the buffer before freeing
523 copybit->flush_get_fence(copybit, &releaseFd);
524 ret = sync_wait(releaseFd, 1000);
525 if(ret < 0) {
526 ALOGE("%s: sync_wait error!! error no = %d err str = %s",
527 __FUNCTION__, errno, strerror(errno));
528 }
529 close(releaseFd);
530 }
531 free_buffer(tmpHnd);
532 }
533
534 if(err < 0)
535 ALOGE("%s: copybit stretch failed",__FUNCTION__);
536 return err;
537 }
538
getLayerResolution(const hwc_layer_1_t * layer,unsigned int & width,unsigned int & height)539 void CopyBit::getLayerResolution(const hwc_layer_1_t* layer,
540 unsigned int& width, unsigned int& height)
541 {
542 hwc_rect_t displayFrame = layer->displayFrame;
543
544 width = displayFrame.right - displayFrame.left;
545 height = displayFrame.bottom - displayFrame.top;
546 }
547
validateParams(hwc_context_t * ctx,const hwc_display_contents_1_t * list)548 bool CopyBit::validateParams(hwc_context_t *ctx,
549 const hwc_display_contents_1_t *list) {
550 //Validate parameters
551 if (!ctx) {
552 ALOGE("%s:Invalid HWC context", __FUNCTION__);
553 return false;
554 } else if (!list) {
555 ALOGE("%s:Invalid HWC layer list", __FUNCTION__);
556 return false;
557 }
558 return true;
559 }
560
561
allocRenderBuffers(int w,int h,int f)562 int CopyBit::allocRenderBuffers(int w, int h, int f)
563 {
564 int ret = 0;
565 for (int i = 0; i < NUM_RENDER_BUFFERS; i++) {
566 if (mRenderBuffer[i] == NULL) {
567 ret = alloc_buffer(&mRenderBuffer[i],
568 w, h, f,
569 GRALLOC_USAGE_PRIVATE_IOMMU_HEAP);
570 }
571 if(ret < 0) {
572 freeRenderBuffers();
573 break;
574 }
575 }
576 return ret;
577 }
578
freeRenderBuffers()579 void CopyBit::freeRenderBuffers()
580 {
581 for (int i = 0; i < NUM_RENDER_BUFFERS; i++) {
582 if(mRenderBuffer[i]) {
583 free_buffer(mRenderBuffer[i]);
584 mRenderBuffer[i] = NULL;
585 }
586 }
587 }
588
getCurrentRenderBuffer()589 private_handle_t * CopyBit::getCurrentRenderBuffer() {
590 return mRenderBuffer[mCurRenderBufferIndex];
591 }
592
setReleaseFd(int fd)593 void CopyBit::setReleaseFd(int fd) {
594 if(mRelFd[0] >=0)
595 close(mRelFd[0]);
596 mRelFd[0] = mRelFd[1];
597 mRelFd[1] = dup(fd);
598 }
599
getCopyBitDevice()600 struct copybit_device_t* CopyBit::getCopyBitDevice() {
601 return mEngine;
602 }
603
CopyBit()604 CopyBit::CopyBit():mIsModeOn(false), mCopyBitDraw(false),
605 mCurRenderBufferIndex(0){
606 hw_module_t const *module;
607 for (int i = 0; i < NUM_RENDER_BUFFERS; i++)
608 mRenderBuffer[i] = NULL;
609 mRelFd[0] = -1;
610 mRelFd[1] = -1;
611
612 char value[PROPERTY_VALUE_MAX];
613 property_get("debug.hwc.dynThreshold", value, "2");
614 mDynThreshold = atof(value);
615
616 if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) {
617 if(copybit_open(module, &mEngine) < 0) {
618 ALOGE("FATAL ERROR: copybit open failed.");
619 }
620 } else {
621 ALOGE("FATAL ERROR: copybit hw module not found");
622 }
623 }
624
~CopyBit()625 CopyBit::~CopyBit()
626 {
627 freeRenderBuffers();
628 if(mRelFd[0] >=0)
629 close(mRelFd[0]);
630 if(mRelFd[1] >=0)
631 close(mRelFd[1]);
632 if(mEngine)
633 {
634 copybit_close(mEngine);
635 mEngine = NULL;
636 }
637 }
638 }; //namespace qhwc
639