diff options
author | Alin Jerpelea <jerpelea@gmail.com> | 2013-07-20 12:56:31 +0100 |
---|---|---|
committer | OliverG96 <oliverarafo@gmail.com> | 2013-07-25 19:38:36 +0100 |
commit | 35c7cd72f91eedc77ab693ebb94121bdd57cc22c (patch) | |
tree | d71afbbf19d5794d5351660ede45e253722c5c5e | |
parent | fa7e3f769d69fd06d7fadb7c48947f074075f2e4 (diff) | |
download | android_frameworks_native-jellybean.tar.gz android_frameworks_native-jellybean.tar.bz2 android_frameworks_native-jellybean.zip |
native: Add missing changes for multimedia on STE devicesjellybean
Change-Id: Icfa731aa501ea0e79529f5bb85081cd476a33102
-rw-r--r-- | include/gui/SurfaceTexture.h | 73 | ||||
-rw-r--r-- | include/ui/Region.h | 26 | ||||
-rw-r--r-- | libs/gui/SurfaceTexture.cpp | 233 | ||||
-rw-r--r-- | libs/ui/PixelFormat.cpp | 12 | ||||
-rw-r--r-- | services/surfaceflinger/DisplayHardware/DisplayHardware.cpp | 4 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 17 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 55 |
7 files changed, 413 insertions, 7 deletions
diff --git a/include/gui/SurfaceTexture.h b/include/gui/SurfaceTexture.h index 2635e2f3a..ec73f952c 100644 --- a/include/gui/SurfaceTexture.h +++ b/include/gui/SurfaceTexture.h @@ -31,6 +31,11 @@ #include <utils/Vector.h> #include <utils/threads.h> +#ifdef STE_HARDWARE +#include <hardware/copybit.h> +#include <gui/IGraphicBufferAlloc.h> +#endif + #define ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID "mSurfaceTexture" namespace android { @@ -42,6 +47,9 @@ class String8; class SurfaceTexture : public virtual RefBase, protected BufferQueue::ConsumerListener { public: +#ifdef STE_HARDWARE + enum { NUM_BLIT_BUFFER_SLOTS = 2 }; +#endif struct FrameAvailableListener : public virtual RefBase { // onFrameAvailable() is called each time an additional frame becomes // available for consumption. This means that frames that are queued @@ -91,6 +99,13 @@ public: // target texture belongs is bound to the calling thread. status_t updateTexImage(); +#ifdef STE_HARDWARE + // convert() performs the deferred texture conversion as scheduled + // by updateTexImage(bool deferConversion). + // The method returns immediately if no conversion is necessary. + status_t convert(); +#endif + // setBufferCountServer set the buffer count. If the client has requested // a buffer count using setBufferCount, the server-buffer count will // take effect once the client sets the count back to zero. @@ -248,12 +263,27 @@ private: virtual ~BufferRejecter() { } }; friend class Layer; +#ifndef STE_HARDWARE status_t updateTexImage(BufferRejecter* rejecter); +#else + // A surface that uses a non-native format requires conversion of + // its buffers. This conversion can be deferred until the layer + // based on this surface is drawn. + status_t updateTexImage(BufferRejecter* rejecter, bool deferConversion); +#endif // createImage creates a new EGLImage from a GraphicBuffer. EGLImageKHR createImage(EGLDisplay dpy, const sp<GraphicBuffer>& graphicBuffer); +#ifdef STE_HARDWARE + // returns TRUE if buffer needs color format conversion + bool conversionIsNeeded(const sp<GraphicBuffer>& graphicBuffer); + + // converts buffer to a suitable color format + status_t convert(sp<GraphicBuffer> &srcBuf, sp<GraphicBuffer> &dstBuf); +#endif + // freeBufferLocked frees up the given buffer slot. If the slot has been // initialized this will release the reference to the GraphicBuffer in that // slot and destroy the EGLImage in that slot. Otherwise it has no effect. @@ -349,6 +379,15 @@ private: // to EGL_NO_SYNC_KHR when the buffer is created and (optionally, based // on a compile-time option) set to a new sync object in updateTexImage. EGLSyncKHR mFence; + +#ifdef STE_HARDWARE + // mEglDisplay is the EGLDisplay with which this SurfaceTexture is currently + // associated. It is intialized to EGL_NO_DISPLAY and gets set to the + // current display when updateTexImage is called for the first time and when + // attachToContext is called. + EGLDisplay mEglDisplay; +#endif + }; // mEglDisplay is the EGLDisplay with which this SurfaceTexture is currently @@ -357,6 +396,40 @@ private: // attachToContext is called. EGLDisplay mEglDisplay; +#ifdef STE_HARDWARE + // mBlitEngine is the handle to the copybit device which will be used in + // case color transform is needed before the EGL image is created. + copybit_device_t* mBlitEngine; + + // mBlitSlots contains several buffers which will + // be rendered alternately in case color transform is needed (instead + // of rendering the buffers in mSlots). + EGLSlot mBlitSlots[NUM_BLIT_BUFFER_SLOTS]; + + // mGraphicBufferAlloc is the connection to SurfaceFlinger that is used to + // allocate new GraphicBuffer objects. + sp<IGraphicBufferAlloc> mGraphicBufferAlloc; + + // mNextBlitSlot is the index of the blitter buffer (in mBlitSlots) which + // will be used in the next color transform. + int mNextBlitSlot; + + // mConversionSrcSlot designates the slot where source buffer + // for the last deferred updateTexImage is located. + int mConversionSrcSlot; + + // mConversionBltSlot designates the slot where destination buffer + // for the last deferred updateTexImage is located. + int mConversionBltSlot; + + // mNeedsConversion indicates that a format conversion is necessary + // before the layer based on this surface is drawn. + // This flag is set whenever updateTexImage() with deferred conversion + // is called. It is cleared once the layer is drawn, + // or when updateTexImage() w/o deferred conversion is called. + bool mNeedsConversion; +#endif + // mEglContext is the OpenGL ES context with which this SurfaceTexture is // currently associated. It is initialized to EGL_NO_CONTEXT and gets set // to the current GL context when updateTexImage is called for the first diff --git a/include/ui/Region.h b/include/ui/Region.h index f242f18eb..9f4d32951 100644 --- a/include/ui/Region.h +++ b/include/ui/Region.h @@ -24,6 +24,10 @@ #include <ui/Rect.h> +#ifdef STE_HARDWARE +#include <hardware/copybit.h> +#endif + namespace android { // --------------------------------------------------------------------------- @@ -195,6 +199,28 @@ Region& Region::operator -= (const Region& rhs) { Region& Region::operator += (const Point& pt) { return translateSelf(pt.x, pt.y); } + +#ifdef STE_HARDWARE +// --------------------------------------------------------------------------- + +struct region_iterator : public copybit_region_t { + region_iterator(const Region& region) + : b(region.begin()), e(region.end()) { + this->next = iterate; + } +private: + static int iterate(copybit_region_t const * self, copybit_rect_t* rect) { + region_iterator const* me = static_cast<region_iterator const*>(self); + if (me->b != me->e) { + *reinterpret_cast<Rect*>(rect) = *me->b++; + return 1; + } + return 0; + } + mutable Region::const_iterator b; + Region::const_iterator const e; +}; +#endif // --------------------------------------------------------------------------- }; // namespace android diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp index 2eca22821..21f311269 100644 --- a/libs/gui/SurfaceTexture.cpp +++ b/libs/gui/SurfaceTexture.cpp @@ -120,6 +120,10 @@ SurfaceTexture::SurfaceTexture(GLuint tex, bool allowSynchronousMode, mUseFenceSync(false), #endif mTexTarget(texTarget), +#ifdef STE_HARDWARE + mNextBlitSlot(0), + mNeedsConversion(false), +#endif mEglDisplay(EGL_NO_DISPLAY), mEglContext(EGL_NO_CONTEXT), mAbandoned(false), @@ -128,6 +132,13 @@ SurfaceTexture::SurfaceTexture(GLuint tex, bool allowSynchronousMode, { // Choose a name using the PID and a process-unique ID. mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId()); +#ifdef STE_HARDWARE + sp<ISurfaceComposer> composer(ComposerService::getComposerService()); + mGraphicBufferAlloc = composer->createGraphicBufferAlloc(); + if (mGraphicBufferAlloc == 0) { + ST_LOGE("createGraphicBufferAlloc() failed in SurfaceTexture()"); + } +#endif ST_LOGV("SurfaceTexture"); if (bufferQueue == 0) { ST_LOGV("Creating a new BufferQueue"); @@ -140,6 +151,21 @@ SurfaceTexture::SurfaceTexture(GLuint tex, bool allowSynchronousMode, memcpy(mCurrentTransformMatrix, mtxIdentity, sizeof(mCurrentTransformMatrix)); +#ifdef STE_HARDWARE + + for (int i = 0; i < NUM_BLIT_BUFFER_SLOTS; i++) { + mBlitSlots[i].mEglImage = EGL_NO_IMAGE_KHR; + mBlitSlots[i].mEglDisplay = EGL_NO_DISPLAY; + } + + hw_module_t const* module; + mBlitEngine = 0; + if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) { + copybit_open(module, &mBlitEngine); + } + ALOGE_IF(!mBlitEngine, "\nCannot open copybit mBlitEngine=%p", mBlitEngine); +#endif + // Note that we can't create an sp<...>(this) in a ctor that will not keep a // reference once the ctor ends, as that would cause the refcount of 'this' // dropping to 0 at the end of the ctor. Since all we need is a wp<...> @@ -163,6 +189,11 @@ SurfaceTexture::~SurfaceTexture() { ST_LOGV("~SurfaceTexture"); abandon(); +#ifdef STE_HARDWARE + if (mBlitEngine) { + copybit_close(mBlitEngine); + } +#endif } status_t SurfaceTexture::setBufferCountServer(int bufferCount) { @@ -180,10 +211,19 @@ status_t SurfaceTexture::setDefaultBufferSize(uint32_t w, uint32_t h) } status_t SurfaceTexture::updateTexImage() { +#ifndef STE_HARDWARE return SurfaceTexture::updateTexImage(NULL); +#else + return SurfaceTexture::updateTexImage(NULL, false); +#define STE_DEFERDBG 0 +#endif } +#ifndef STE_HARDWARE status_t SurfaceTexture::updateTexImage(BufferRejecter* rejecter) { +#else +status_t SurfaceTexture::updateTexImage(BufferRejecter* rejecter, bool deferConversion) { +#endif ATRACE_CALL(); ST_LOGV("updateTexImage"); Mutex::Autolock lock(mMutex); @@ -246,6 +286,7 @@ status_t SurfaceTexture::updateTexImage(BufferRejecter* rejecter) { return NO_ERROR; } +#ifndef STE_HARDWARE // Update the GL texture object. We may have to do this even when // item.mGraphicBuffer == NULL, if we destroyed the EGLImage when // detaching from a context but the buffer has not been re-allocated. @@ -271,6 +312,102 @@ status_t SurfaceTexture::updateTexImage(BufferRejecter* rejecter) { } } } +#else + EGLImageKHR image; + EGLDisplay dpy = eglGetCurrentDisplay(); + if (conversionIsNeeded(mEGLSlots[buf].mGraphicBuffer)) { + mNeedsConversion = deferConversion; + // If color conversion is needed we can't use the graphic buffers + // located in mSlots for the textures (wrong color format). Instead + // color convert it into a buffer in mBlitSlots and use that instead. + image = mBlitSlots[mNextBlitSlot].mEglImage; + + // If there exists an image already, make sure that + // the dimensions match the current source buffer. + // Otherwise, destroy the buffer and let a new one be allocated. + if (image != EGL_NO_IMAGE_KHR && + mEGLSlots[buf].mGraphicBuffer != NULL && + mBlitSlots[mNextBlitSlot].mGraphicBuffer != NULL) { + sp<GraphicBuffer> &srcBuf = mEGLSlots[buf].mGraphicBuffer; + sp<GraphicBuffer> &bltBuf = + mBlitSlots[mNextBlitSlot].mGraphicBuffer; + if (srcBuf->getWidth() != bltBuf->getWidth() || + srcBuf->getHeight() != bltBuf->getHeight()) { + eglDestroyImageKHR(mBlitSlots[mNextBlitSlot].mEglDisplay, + image); + mBlitSlots[mNextBlitSlot].mEglImage = EGL_NO_IMAGE_KHR; + mBlitSlots[mNextBlitSlot].mGraphicBuffer = NULL; + image = EGL_NO_IMAGE_KHR; + } + } + if (image == EGL_NO_IMAGE_KHR) { + sp<GraphicBuffer> &srcBuf = mEGLSlots[buf].mGraphicBuffer; + status_t res = 0; + + sp<GraphicBuffer> blitBuffer( + mGraphicBufferAlloc->createGraphicBuffer( + srcBuf->getWidth(), srcBuf->getHeight(), + PIXEL_FORMAT_RGBA_8888, srcBuf->getUsage(), + &res)); + if (blitBuffer == 0) { + ST_LOGE("updateTexImage: SurfaceComposer::createGraphicBuffer failed"); + return NO_MEMORY; + } + if (res != NO_ERROR) { + ST_LOGW("updateTexImage: SurfaceComposer::createGraphicBuffer error=%#04x", res); + } + mBlitSlots[mNextBlitSlot].mGraphicBuffer = blitBuffer; + + EGLDisplay dpy = eglGetCurrentDisplay(); + image = createImage(dpy, blitBuffer); + mBlitSlots[mNextBlitSlot].mEglImage = image; + mBlitSlots[mNextBlitSlot].mEglDisplay = dpy; + } + + if (deferConversion) { + item.mGraphicBuffer = mEGLSlots[buf].mGraphicBuffer; + mConversionSrcSlot = buf; + mConversionBltSlot = mNextBlitSlot; + // At this point item.mGraphicBuffer and image do not point + // at matching buffers. This is intentional as this + // surface might end up being taken care of by HWComposer, + // which needs access to the original buffer. + // GL however, is fed an EGLImage that is created from + // a conversion buffer. It will have its + // content updated once the surface is actually drawn + // in Layer::onDraw() + } else { + if (convert(mEGLSlots[buf].mGraphicBuffer, + mBlitSlots[mNextBlitSlot].mGraphicBuffer) != OK) { + ALOGE("updateTexImage: convert failed"); + return UNKNOWN_ERROR; + } + item.mGraphicBuffer = mBlitSlots[mNextBlitSlot].mGraphicBuffer; + } + // mBlitSlots contains several buffers (NUM_BLIT_BUFFER_SLOTS), + // advance (potentially wrap) the index + mNextBlitSlot = (mNextBlitSlot + 1) % NUM_BLIT_BUFFER_SLOTS; + } else { + mNeedsConversion = false; + image = mEGLSlots[buf].mEglImage ; + item.mGraphicBuffer = mEGLSlots[buf].mGraphicBuffer; + if (image == EGL_NO_IMAGE_KHR) { + EGLDisplay dpy = eglGetCurrentDisplay(); + if (item.mGraphicBuffer == 0) { + ST_LOGE("buffer at slot %d is null", buf); + return BAD_VALUE; + } + image = createImage(dpy, item.mGraphicBuffer); + mEGLSlots[buf].mEglImage = image; + mEglDisplay = dpy; + if (image == EGL_NO_IMAGE_KHR) { + // NOTE: if dpy was invalid, createImage() is guaranteed to + // fail. so we'd end up here. + return -EINVAL; + } + } + } +#endif if (err == NO_ERROR) { GLint error; @@ -278,10 +415,14 @@ status_t SurfaceTexture::updateTexImage(BufferRejecter* rejecter) { ST_LOGW("updateTexImage: clearing GL error: %#04x", error); } +#ifndef STE_HARDWARE if(gpuSupportedFormat) { +#endif glBindTexture(mTexTarget, mTexName); glEGLImageTargetTexture2DOES(mTexTarget, (GLeglImageOES)image); +#ifndef STE_HARDWARE } +#endif while ((error = glGetError()) != GL_NO_ERROR) { ST_LOGE("updateTexImage: error binding external texture image %p " "(slot %d): %#04x", image, buf, error); @@ -322,7 +463,11 @@ status_t SurfaceTexture::updateTexImage(BufferRejecter* rejecter) { // Update the SurfaceTexture state. mCurrentTexture = buf; +#ifndef STE_HARDWARE mCurrentTextureBuf = mEGLSlots[buf].mGraphicBuffer; +#else + mCurrentTextureBuf = item.mGraphicBuffer; +#endif mCurrentCrop = item.mCrop; mCurrentTransform = item.mTransform; mCurrentScalingMode = item.mScalingMode; @@ -758,6 +903,16 @@ void SurfaceTexture::abandon() { for (int i =0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) { freeBufferLocked(i); } +#ifdef STE_HARDWARE + for (int i = 0; i < NUM_BLIT_BUFFER_SLOTS; i++) { + mBlitSlots[i].mGraphicBuffer = 0; + if (mBlitSlots[i].mEglImage != EGL_NO_IMAGE_KHR) { + eglDestroyImageKHR(mBlitSlots[i].mEglDisplay, mBlitSlots[i].mEglImage); + mBlitSlots[i].mEglImage = EGL_NO_IMAGE_KHR; + mBlitSlots[i].mEglDisplay = EGL_NO_DISPLAY; + } + } +#endif // disconnect from the BufferQueue mBufferQueue->consumerDisconnect(); @@ -861,6 +1016,84 @@ void SurfaceTexture::dump(String8& result, const char* prefix, } } +#ifdef STE_HARDWARE +bool SurfaceTexture::conversionIsNeeded(const sp<GraphicBuffer>& graphicBuffer) { + int fmt = graphicBuffer->getPixelFormat(); + return (fmt == PIXEL_FORMAT_YCBCR42XMBN) || (fmt == PIXEL_FORMAT_YCbCr_420_P); +} + +status_t SurfaceTexture::convert() { + if (!mNeedsConversion) + return NO_ERROR; + + if (mConversionBltSlot < 0 || + mConversionBltSlot >= NUM_BLIT_BUFFER_SLOTS || + mConversionSrcSlot < 0 || + mConversionSrcSlot >= BufferQueue::NUM_BUFFER_SLOTS) { + ALOGE_IF(STE_DEFERDBG, "%s: Incorrect setup for deferred " + "texture conversion:\n" + "mConversionSrcSlot=%d mConversionBltSlot=%d", __FUNCTION__, + mConversionSrcSlot, mConversionBltSlot); + return BAD_VALUE; + } + + if (mEGLSlots[mConversionSrcSlot].mGraphicBuffer == NULL) { + ALOGI_IF(STE_DEFERDBG, "%s: NULL source for deferred texture conversion.", + __FUNCTION__); + return OK; + } + + if (mBlitSlots[mConversionBltSlot].mGraphicBuffer == NULL) { + ALOGI_IF(STE_DEFERDBG, "%s: NULL destination for deferred " + "texture conversion.", __FUNCTION__); + return OK; + } + + return convert(mEGLSlots[mConversionSrcSlot].mGraphicBuffer, + mBlitSlots[mConversionBltSlot].mGraphicBuffer); +} + +status_t SurfaceTexture::convert(sp<GraphicBuffer> &srcBuf, sp<GraphicBuffer> &dstBuf) { + copybit_image_t dstImg; + dstImg.w = dstBuf->getWidth(); + dstImg.h = dstBuf->getHeight(); + dstImg.format = dstBuf->getPixelFormat(); + dstImg.handle = (native_handle_t*) dstBuf->getNativeBuffer()->handle; + + copybit_image_t srcImg; + srcImg.w = srcBuf->getWidth(); + srcImg.h = srcBuf->getHeight(); + srcImg.format = srcBuf->getPixelFormat(); + srcImg.base = NULL; + srcImg.handle = (native_handle_t*) srcBuf->getNativeBuffer()->handle; + + copybit_rect_t dstCrop; + dstCrop.l = 0; + dstCrop.t = 0; + dstCrop.r = dstBuf->getWidth(); + dstCrop.b = dstBuf->getHeight(); + + copybit_rect_t srcCrop; + srcCrop.l = 0; + srcCrop.t = 0; + srcCrop.r = srcBuf->getWidth(); + srcCrop.b = srcBuf->getHeight(); + + region_iterator clip(Region(Rect(dstCrop.r, dstCrop.b))); + mBlitEngine->set_parameter(mBlitEngine, COPYBIT_TRANSFORM, 0); + mBlitEngine->set_parameter(mBlitEngine, COPYBIT_PLANE_ALPHA, 0xFF); + mBlitEngine->set_parameter(mBlitEngine, COPYBIT_DITHER, COPYBIT_ENABLE); + + int err = mBlitEngine->stretch( + mBlitEngine, &dstImg, &srcImg, &dstCrop, &srcCrop, &clip); + if (err != 0) { + ALOGE("\nError: Blit stretch operation failed (err:%d)\n", err); + return UNKNOWN_ERROR; + } + return OK; +} +#endif + static void mtxMul(float out[16], const float a[16], const float b[16]) { out[0] = a[0]*b[0] + a[4]*b[1] + a[8]*b[2] + a[12]*b[3]; out[1] = a[1]*b[0] + a[5]*b[1] + a[9]*b[2] + a[13]*b[3]; diff --git a/libs/ui/PixelFormat.cpp b/libs/ui/PixelFormat.cpp index e73dac877..2135cb50c 100644 --- a/libs/ui/PixelFormat.cpp +++ b/libs/ui/PixelFormat.cpp @@ -103,26 +103,24 @@ status_t getPixelFormatInfo(PixelFormat format, PixelFormatInfo* info) #ifdef STE_HARDWARE case HAL_PIXEL_FORMAT_YCrCb_422_SP: case HAL_PIXEL_FORMAT_YCbCr_422_P: -#endif - case HAL_PIXEL_FORMAT_YCbCr_422_I: -#ifdef STE_HARDWARE + case HAL_PIXEL_FORMAT_YCrCb_422_P: case HAL_PIXEL_FORMAT_CbYCrY_422_I: #endif + case HAL_PIXEL_FORMAT_YCbCr_422_I: info->bitsPerPixel = 16; goto done; #ifdef STE_HARDWARE case HAL_PIXEL_FORMAT_YCbCr_420_SP: -#endif - case HAL_PIXEL_FORMAT_YCrCb_420_SP: - case HAL_PIXEL_FORMAT_YV12: -#ifdef STE_HARDWARE case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: case HAL_PIXEL_FORMAT_YCrCb_420_SP_TILED: case HAL_PIXEL_FORMAT_YCbCr_420_P: + case HAL_PIXEL_FORMAT_YCrCb_420_P: case HAL_PIXEL_FORMAT_YCbCr_420_I: case HAL_PIXEL_FORMAT_CbYCrY_420_I: case HAL_PIXEL_FORMAT_YCBCR42XMBN: #endif + case HAL_PIXEL_FORMAT_YCrCb_420_SP: + case HAL_PIXEL_FORMAT_YV12: info->bitsPerPixel = 12; done: info->format = format; diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp index 6896feb45..f30644029 100644 --- a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp +++ b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp @@ -447,6 +447,10 @@ void DisplayHardware::flip(const Region& dirty) const if (mHwc->initCheck() == NO_ERROR) { mHwc->commit(); } else { +#ifdef STE_HARDWARE + // Make sure the swapbuffer call is done in sync + mNativeWindow->compositionComplete(); +#endif eglSwapBuffers(dpy, surface); } checkEGLErrors("eglSwapBuffers"); diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 84a9060d3..520a9fbc0 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -332,6 +332,18 @@ void Layer::setPerFrameData(hwc_layer_t* hwcl) { void Layer::onDraw(const Region& clip) const { +#ifdef STE_HARDWARE + // Convert the texture to a native format if need be. + // convert() returns immediately if no conversion is necessary. + if (mSurfaceTexture != NULL) { + status_t res = mSurfaceTexture->convert(); + if (res != NO_ERROR) { + ALOGE("Layer::onDraw: texture conversion failed. " + "Texture content for this layer will not be initialized."); + } + } +#endif + ATRACE_CALL(); if (CC_UNLIKELY(mActiveBuffer == 0)) { @@ -646,7 +658,12 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions) Reject r(mDrawingState, currentState(), recomputeVisibleRegions); +#ifndef STE_HARDWARE if (mSurfaceTexture->updateTexImage(&r) < NO_ERROR) { +#else + if (mSurfaceTexture->updateTexImage(&r, true) < NO_ERROR) { +#endif + // something happened! recomputeVisibleRegions = true; return; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 3ca2297f3..17a810eb2 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -479,12 +479,16 @@ void SurfaceFlinger::onMessageReceived(int32_t what) if (CC_LIKELY(hw.canDraw())) { // repaint the framebuffer (if needed) handleRepaint(); +#ifndef STE_HARDWARE // inform the h/w that we're done compositing hw.compositionComplete(); +#endif postFramebuffer(); } else { +#ifdef STE_HARDWARE // pretend we did the post hw.compositionComplete(); +#endif } } break; @@ -891,8 +895,10 @@ void SurfaceFlinger::handleRepaint() // set the frame buffer const DisplayHardware& hw(graphicPlane(0).displayHardware()); +#ifndef STE_HARDWARE glMatrixMode(GL_MODELVIEW); glLoadIdentity(); +#endif uint32_t flags = hw.getFlags(); if (flags & DisplayHardware::SWAP_RECTANGLE) { @@ -922,8 +928,15 @@ void SurfaceFlinger::handleRepaint() mDirtyRegion.clear(); } +#ifdef STE_HARDWARE +static bool checkDrawingWithGL(hwc_layer_t* const layers, size_t layerCount); +#endif + void SurfaceFlinger::setupHardwareComposer() { +#ifdef STE_HARDWARE + bool useGL = true; +#endif const DisplayHardware& hw(graphicPlane(0).displayHardware()); HWComposer& hwc(hw.getHwComposer()); hwc_layer_t* const cur(hwc.getLayers()); @@ -953,8 +966,40 @@ void SurfaceFlinger::setupHardwareComposer() } status_t err = hwc.prepare(); ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); +#ifdef STE_HARDWARE + /* + * Check if GL will be used + */ + useGL = checkDrawingWithGL(cur, count); + + if (!useGL) { + return; + } + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + if (CC_UNLIKELY(!mWormholeRegion.isEmpty())) { + // should never happen unless the window manager has a bug + // draw something... + drawWormhole(); + } +#endif } +#ifdef STE_HARDWARE +static bool checkDrawingWithGL(hwc_layer_t* const layers, size_t layerCount) +{ + bool useGL = false; + if (layers) { + for (size_t i=0 ; i<layerCount ; i++) { + if (layers[i].compositionType == HWC_FRAMEBUFFER) { + useGL = true; + } + } + } + return useGL; +} +#endif + void SurfaceFlinger::composeSurfaces(const Region& dirty) { const DisplayHardware& hw(graphicPlane(0).displayHardware()); @@ -981,6 +1026,7 @@ void SurfaceFlinger::composeSurfaces(const Region& dirty) glClear(GL_COLOR_BUFFER_BIT); } } else { +#ifndef STE_HARDWARE // screen is already cleared here if (!mWormholeRegion.isEmpty()) { // can happen with SurfaceView @@ -990,6 +1036,7 @@ void SurfaceFlinger::composeSurfaces(const Region& dirty) #endif drawWormhole(); } +#endif } /* @@ -2541,7 +2588,9 @@ status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, glDeleteRenderbuffersOES(1, &tname); glDeleteFramebuffersOES(1, &name); +#ifdef STE_HARDWARE hw.compositionComplete(); +#endif // ALOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK"); @@ -2769,9 +2818,15 @@ sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h if (err == NO_MEMORY) { GraphicBuffer::dumpAllocationsToSystemLog(); } +#ifndef STE_HARDWARE ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) " "failed (%s), handle=%p", w, h, strerror(-err), graphicBuffer->handle); +#else + ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d, format=%#x) " + "failed (%s), handle=%p", + w, h, format, strerror(-err), graphicBuffer->handle); +#endif return 0; } return graphicBuffer; |