From 36d0184e089831b74de6005f01da9e7b26679bb9 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Mon, 2 Nov 2009 17:48:33 -0800 Subject: [PATCH] fix[2228133] pixelflinger ignores the "vertical stride" leading to artifacts when playing back video we lost the concept of vertical stride when moving video playback to EGLImage. Here we bring it back in a somewhat hacky-way that will work only for the softgl/mdp backend. --- include/private/opengles/gl_context.h | 4 +++- include/ui/GraphicBuffer.h | 2 ++ libs/surfaceflinger/LayerBuffer.cpp | 2 ++ libs/ui/GraphicBuffer.cpp | 8 ++++++++ opengl/libagl/copybit.cpp | 25 ++++++++++++++++++------- opengl/libagl/egl.cpp | 2 +- 6 files changed, 34 insertions(+), 9 deletions(-) diff --git a/include/private/opengles/gl_context.h b/include/private/opengles/gl_context.h index 67c2dd80681fd..26cde38693b9a 100644 --- a/include/private/opengles/gl_context.h +++ b/include/private/opengles/gl_context.h @@ -32,6 +32,8 @@ #include #include +struct android_native_buffer_t; + namespace android { const unsigned int OGLES_NUM_COMPRESSED_TEXTURE_FORMATS = 10; @@ -602,7 +604,7 @@ struct copybits_context_t { copybit_device_t* blitEngine; int32_t minScale; int32_t maxScale; - buffer_handle_t drawSurfaceBuffer; + android_native_buffer_t* drawSurfaceBuffer; }; struct ogles_context_t { diff --git a/include/ui/GraphicBuffer.h b/include/ui/GraphicBuffer.h index 21725360d1d9d..b9c491be1a6cc 100644 --- a/include/ui/GraphicBuffer.h +++ b/include/ui/GraphicBuffer.h @@ -93,6 +93,8 @@ public: void setIndex(int index); int getIndex() const; + void setVerticalStride(uint32_t vstride); + uint32_t getVerticalStride() const; protected: GraphicBuffer(const Parcel& reply); diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp index 82a8e519f8738..a36304c8de785 100644 --- a/libs/surfaceflinger/LayerBuffer.cpp +++ b/libs/surfaceflinger/LayerBuffer.cpp @@ -444,6 +444,8 @@ void LayerBuffer::BufferSource::onDraw(const Region& clip) const GraphicBuffer::USAGE_HW_TEXTURE, src.img.w, src.img.handle, false); + graphicBuffer->setVerticalStride(src.img.h); + err = mLayer.initializeEglImage(graphicBuffer, &mTexture); } #endif diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp index efe2d786cf1f6..6a5c8a9c4ca53 100644 --- a/libs/ui/GraphicBuffer.cpp +++ b/libs/ui/GraphicBuffer.cpp @@ -226,6 +226,14 @@ int GraphicBuffer::getIndex() const { return mIndex; } +void GraphicBuffer::setVerticalStride(uint32_t vstride) { + mVStride = vstride; +} + +uint32_t GraphicBuffer::getVerticalStride() const { + return mVStride; +} + // --------------------------------------------------------------------------- }; // namespace android diff --git a/opengl/libagl/copybit.cpp b/opengl/libagl/copybit.cpp index 3de5b2ba55474..1bef859b2ebaf 100644 --- a/opengl/libagl/copybit.cpp +++ b/opengl/libagl/copybit.cpp @@ -46,13 +46,24 @@ namespace android { static void textureToCopyBitImage( const GGLSurface* surface, int32_t opFormat, - buffer_handle_t buffer, copybit_image_t* img) + android_native_buffer_t* buffer, copybit_image_t* img) { + uint32_t vstride = 0; + if (opFormat == COPYBIT_FORMAT_YCbCr_422_SP || + opFormat == COPYBIT_FORMAT_YCbCr_420_SP) { + // NOTE: this static_cast is really not safe b/c we can't know for + // sure the buffer passed is of the right type. + // However, since we do this only for YUV formats, we should be safe + // since only SurfaceFlinger makes use of them. + GraphicBuffer* graphicBuffer = static_cast(buffer); + vstride = graphicBuffer->getVerticalStride(); + } + img->w = surface->stride; - img->h = surface->height; + img->h = vstride ? vstride : surface->height; img->format = opFormat; img->base = surface->data; - img->handle = (native_handle_t *)buffer; + img->handle = (native_handle_t *)buffer->handle; } struct clipRectRegion : public copybit_region_t { @@ -279,8 +290,8 @@ static bool copybit(GLint x, GLint y, copybit_device_t* copybit = c->copybits.blitEngine; copybit_image_t src; - buffer_handle_t source_hnd = textureObject->buffer->handle; - textureToCopyBitImage(&textureObject->surface, opFormat, source_hnd, &src); + textureToCopyBitImage(&textureObject->surface, opFormat, + textureObject->buffer, &src); copybit_rect_t srect = { Ucr, Vcr + Hcr, Ucr + Wcr, Vcr }; /* @@ -360,8 +371,8 @@ static bool copybit(GLint x, GLint y, } copybit_image_t dst; - buffer_handle_t target_hnd = c->copybits.drawSurfaceBuffer; - textureToCopyBitImage(&cbSurface, cbSurface.format, target_hnd, &dst); + textureToCopyBitImage(&cbSurface, cbSurface.format, + c->copybits.drawSurfaceBuffer, &dst); copybit_rect_t drect = {x, y, x+w, y+h}; diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp index d04900e870541..80ddc0280f9ac 100644 --- a/opengl/libagl/egl.cpp +++ b/opengl/libagl/egl.cpp @@ -651,7 +651,7 @@ EGLBoolean egl_window_surface_v2_t::bindDrawSurface(ogles_context_t* gl) if (supportedCopybitsDestinationFormat(buffer.format)) { buffer_handle_t handle = this->buffer->handle; if (handle != NULL) { - gl->copybits.drawSurfaceBuffer = handle; + gl->copybits.drawSurfaceBuffer = this->buffer; } } }