diff options
author | Mathias Agopian <mathias@google.com> | 2009-06-25 17:41:12 -0700 |
---|---|---|
committer | Mathias Agopian <mathias@google.com> | 2009-06-25 17:41:12 -0700 |
commit | d512f238a6c439c422a229fe53a86dc386bd3b58 (patch) | |
tree | b305f83c609313f1bc3f0c5f10f88c2d407ce5e0 /libs/surfaceflinger/LayerBuffer.cpp | |
parent | 958b3cac99cef204767b9c8f5bb8e20cbe1fc97b (diff) | |
download | frameworks_native-d512f238a6c439c422a229fe53a86dc386bd3b58.zip frameworks_native-d512f238a6c439c422a229fe53a86dc386bd3b58.tar.gz frameworks_native-d512f238a6c439c422a229fe53a86dc386bd3b58.tar.bz2 |
add support for out-of-range copybit scaling. camera capture is in color again
Diffstat (limited to 'libs/surfaceflinger/LayerBuffer.cpp')
-rw-r--r-- | libs/surfaceflinger/LayerBuffer.cpp | 107 |
1 files changed, 55 insertions, 52 deletions
diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp index 1827efa..a088b0a 100644 --- a/libs/surfaceflinger/LayerBuffer.cpp +++ b/libs/surfaceflinger/LayerBuffer.cpp @@ -245,6 +245,8 @@ LayerBuffer::Buffer::Buffer(const ISurface::BufferHeap& buffers, ssize_t offset) src.img.format = buffers.format; src.img.base = (void*)(intptr_t(buffers.heap->base()) + offset); + // FIXME: gross hack, we should never access private_handle_t from here, + // but this is needed by msm drivers private_handle_t* hnd = new private_handle_t( buffers.heap->heapID(), buffers.heap->getSize(), 0); hnd->offset = offset; @@ -421,56 +423,6 @@ void LayerBuffer::BufferSource::onDraw(const Region& clip) const int t(W); W=H; H=t; } -#if 0 - /* With LayerBuffer, it is likely that we'll have to rescale the - * surface, because this is often used for video playback or - * camera-preview. Since we want these operation as fast as possible - * we make sure we can use the 2D H/W even if it doesn't support - * the requested scale factor, in which case we perform the scaling - * in several passes. */ - - const float min = copybit->get(copybit, COPYBIT_MINIFICATION_LIMIT); - const float mag = copybit->get(copybit, COPYBIT_MAGNIFICATION_LIMIT); - - float xscale = 1.0f; - if (src_width > W*min) xscale = 1.0f / min; - else if (src_width*mag < W) xscale = mag; - - float yscale = 1.0f; - if (src_height > H*min) yscale = 1.0f / min; - else if (src_height*mag < H) yscale = mag; - - if (UNLIKELY(xscale!=1.0f || yscale!=1.0f)) { - if (UNLIKELY(mTemporaryDealer == 0)) { - // allocate a memory-dealer for this the first time - mTemporaryDealer = mLayer.mFlinger->getSurfaceHeapManager() - ->createHeap(ISurfaceComposer::eHardware); - mTempBitmap.init(mTemporaryDealer); - } - - const int tmp_w = floorf(src_width * xscale); - const int tmp_h = floorf(src_height * yscale); - err = mTempBitmap.setBits(tmp_w, tmp_h, 1, src.img.format); - - if (LIKELY(err == NO_ERROR)) { - NativeBuffer tmp; - mTempBitmap.getBitmapSurface(&tmp.img); - tmp.crop.l = 0; - tmp.crop.t = 0; - tmp.crop.r = tmp.img.w; - tmp.crop.b = tmp.img.h; - - region_iterator tmp_it(Region(Rect(tmp.crop.r, tmp.crop.b))); - copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0); - copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF); - copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE); - err = copybit->stretch(copybit, - &tmp.img, &src.img, &tmp.crop, &src.crop, &tmp_it); - src = tmp; - } - } -#endif - #ifdef EGL_ANDROID_get_render_buffer EGLDisplay dpy = eglGetCurrentDisplay(); EGLSurface draw = eglGetCurrentSurface(EGL_DRAW); @@ -486,9 +438,60 @@ void LayerBuffer::BufferSource::onDraw(const Region& clip) const dst.base = NULL; // unused by copybit on msm7k dst.handle = (native_handle_t *)nb->handle; + /* With LayerBuffer, it is likely that we'll have to rescale the + * surface, because this is often used for video playback or + * camera-preview. Since we want these operation as fast as possible + * we make sure we can use the 2D H/W even if it doesn't support + * the requested scale factor, in which case we perform the scaling + * in several passes. */ + + const float min = copybit->get(copybit, COPYBIT_MINIFICATION_LIMIT); + const float mag = copybit->get(copybit, COPYBIT_MAGNIFICATION_LIMIT); + + float xscale = 1.0f; + if (src_width > W*min) xscale = 1.0f / min; + else if (src_width*mag < W) xscale = mag; + + float yscale = 1.0f; + if (src_height > H*min) yscale = 1.0f / min; + else if (src_height*mag < H) yscale = mag; + + if (UNLIKELY(xscale!=1.0f || yscale!=1.0f)) { + const int tmp_w = floorf(src_width * xscale); + const int tmp_h = floorf(src_height * yscale); + + if (mTempBitmap==0 || + mTempBitmap->getWidth() < tmp_w || + mTempBitmap->getHeight() < tmp_h) { + mTempBitmap.clear(); + mTempBitmap = new android::Buffer(tmp_w, tmp_h, src.img.format); + err = mTempBitmap->initCheck(); + } + + if (LIKELY(err == NO_ERROR)) { + NativeBuffer tmp; + tmp.img.w = tmp_w; + tmp.img.h = tmp_h; + tmp.img.format = src.img.format; + tmp.img.handle = (native_handle_t*)mTempBitmap->getNativeBuffer()->handle; + tmp.crop.l = 0; + tmp.crop.t = 0; + tmp.crop.r = tmp.img.w; + tmp.crop.b = tmp.img.h; + + region_iterator tmp_it(Region(Rect(tmp.crop.r, tmp.crop.b))); + copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0); + copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF); + copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE); + err = copybit->stretch(copybit, + &tmp.img, &src.img, &tmp.crop, &src.crop, &tmp_it); + src = tmp; + } + } + const Rect& transformedBounds = mLayer.getTransformedBounds(); - const copybit_rect_t& drect - = reinterpret_cast<const copybit_rect_t&>(transformedBounds); + const copybit_rect_t& drect = + reinterpret_cast<const copybit_rect_t&>(transformedBounds); const State& s(mLayer.drawingState()); region_iterator it(clip); |