From fcfeb4b5970c8f361634429934a2518d7e8328dd Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Mon, 8 Mar 2010 11:14:20 -0800 Subject: fixes for [2474091] Saw Poor behaviour playing a video. - fix a bug when hacking video buffers into gralloc buffers where the buffer size was incorrect this was causing the "direct-form-texture" mode to fail - also when the above fails, make sure to revert to the "mdp copy mode" before going to "slow mode" - finally disable completely the "direct-from-texture" mode for now. It cannot work because the allocated buffers can't respect the GPU constraints (alignment and such). We'll have to find a solution for that. --- libs/surfaceflinger/Layer.cpp | 16 +++++++++++++--- libs/surfaceflinger/LayerBase.cpp | 9 ++------- libs/surfaceflinger/LayerBuffer.cpp | 14 +++++++++++--- libs/surfaceflinger/LayerBuffer.h | 3 ++- 4 files changed, 28 insertions(+), 14 deletions(-) (limited to 'libs/surfaceflinger') diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp index c080513..7ca7875 100644 --- a/libs/surfaceflinger/Layer.cpp +++ b/libs/surfaceflinger/Layer.cpp @@ -156,7 +156,11 @@ void Layer::reloadTexture(const Region& dirty) if (mFlags & DisplayHardware::DIRECT_TEXTURE) { if (buffer->usage & GraphicBuffer::USAGE_HW_TEXTURE) { if (mTextures[index].dirty) { - initializeEglImage(buffer, &mTextures[index]); + if (initializeEglImage(buffer, &mTextures[index]) != NO_ERROR) { + // not sure what we can do here... + mFlags &= ~DisplayHardware::DIRECT_TEXTURE; + goto slowpath; + } } } else { if (mHybridBuffer==0 || (mHybridBuffer->width != buffer->width || @@ -166,8 +170,13 @@ void Layer::reloadTexture(const Region& dirty) buffer->width, buffer->height, buffer->format, GraphicBuffer::USAGE_SW_WRITE_OFTEN | GraphicBuffer::USAGE_HW_TEXTURE); - initializeEglImage( - mHybridBuffer, &mTextures[0]); + if (initializeEglImage( + mHybridBuffer, &mTextures[0]) != NO_ERROR) { + // not sure what we can do here... + mFlags &= ~DisplayHardware::DIRECT_TEXTURE; + mHybridBuffer.clear(); + goto slowpath; + } } GGLSurface t; @@ -236,6 +245,7 @@ void Layer::reloadTexture(const Region& dirty) } else #endif { +slowpath: for (size_t i=0 ; iimage == EGL_NO_IMAGE_KHR, - "eglCreateImageKHR() failed. err=0x%4x", - eglGetError()); - if (texture->image != EGL_NO_IMAGE_KHR) { glBindTexture(GL_TEXTURE_2D, texture->name); glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)texture->image); GLint error = glGetError(); if (UNLIKELY(error != GL_NO_ERROR)) { - // this failed, for instance, because we don't support NPOT. - // FIXME: do something! LOGE("layer=%p, glEGLImageTargetTexture2DOES(%p) " "failed err=0x%04x", this, texture->image, error); - mFlags &= ~DisplayHardware::DIRECT_TEXTURE; err = INVALID_OPERATION; } else { // Everything went okay! @@ -691,6 +684,8 @@ status_t LayerBase::initializeEglImage( texture->height = clientBuf->height; } } else { + LOGE("layer=%p, eglCreateImageKHR() failed. err=0x%4x", + this, eglGetError()); err = INVALID_OPERATION; } return err; diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp index 6d1685b..5c21593 100644 --- a/libs/surfaceflinger/LayerBuffer.cpp +++ b/libs/surfaceflinger/LayerBuffer.cpp @@ -261,7 +261,8 @@ sp LayerBuffer::SurfaceLayerBuffer::createOverlay( // LayerBuffer::Buffer // ============================================================================ -LayerBuffer::Buffer::Buffer(const ISurface::BufferHeap& buffers, ssize_t offset) +LayerBuffer::Buffer::Buffer(const ISurface::BufferHeap& buffers, + ssize_t offset, size_t bufferSize) : mBufferHeap(buffers), mSupportsCopybit(false) { NativeBuffer& src(mNativeBuffer); @@ -280,7 +281,7 @@ LayerBuffer::Buffer::Buffer(const ISurface::BufferHeap& buffers, ssize_t offset) if (module && module->perform) { int err = module->perform(module, GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER, - buffers.heap->heapID(), buffers.heap->getSize(), + buffers.heap->heapID(), bufferSize, offset, buffers.heap->base(), &src.img.handle); @@ -415,7 +416,7 @@ void LayerBuffer::BufferSource::postBuffer(ssize_t offset) sp buffer; if (buffers.heap != 0) { - buffer = new LayerBuffer::Buffer(buffers, offset); + buffer = new LayerBuffer::Buffer(buffers, offset, mBufferSize); if (buffer->getStatus() != NO_ERROR) buffer.clear(); setBuffer(buffer); @@ -469,6 +470,11 @@ void LayerBuffer::BufferSource::onDraw(const Region& clip) const if (mLayer.mFlags & DisplayHardware::DIRECT_TEXTURE) { err = INVALID_OPERATION; if (ourBuffer->supportsCopybit()) { + + // there are constraints on buffers used by the GPU and these may not + // be honored here. We need to change the API so the buffers + // are allocated with gralloc. For now disable this code-path +#if 0 // First, try to use the buffer as an EGLImage directly if (mUseEGLImageDirectly) { // NOTE: Assume the buffer is allocated with the proper USAGE flags @@ -483,6 +489,8 @@ void LayerBuffer::BufferSource::onDraw(const Region& clip) const mUseEGLImageDirectly = false; } } +#endif + copybit_device_t* copybit = mLayer.mBlitEngine; if (copybit && err != NO_ERROR) { // create our EGLImageKHR the first time diff --git a/libs/surfaceflinger/LayerBuffer.h b/libs/surfaceflinger/LayerBuffer.h index eb5b8eb..b176623 100644 --- a/libs/surfaceflinger/LayerBuffer.h +++ b/libs/surfaceflinger/LayerBuffer.h @@ -99,7 +99,8 @@ private: class Buffer : public LightRefBase { public: - Buffer(const ISurface::BufferHeap& buffers, ssize_t offset); + Buffer(const ISurface::BufferHeap& buffers, + ssize_t offset, size_t bufferSize); inline bool supportsCopybit() const { return mSupportsCopybit; } -- cgit v1.1