diff options
Diffstat (limited to 'services/surfaceflinger/SurfaceFlingerConsumer.cpp')
-rw-r--r-- | services/surfaceflinger/SurfaceFlingerConsumer.cpp | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.cpp b/services/surfaceflinger/SurfaceFlingerConsumer.cpp new file mode 100644 index 0000000..2869250 --- /dev/null +++ b/services/surfaceflinger/SurfaceFlingerConsumer.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define ATRACE_TAG ATRACE_TAG_GRAPHICS +//#define LOG_NDEBUG 0 + +#include "SurfaceFlingerConsumer.h" + +#include <private/gui/SyncFeatures.h> + +#include <utils/Trace.h> +#include <utils/Errors.h> + +namespace android { + +// --------------------------------------------------------------------------- + +status_t SurfaceFlingerConsumer::updateTexImage(BufferRejecter* rejecter) +{ + ATRACE_CALL(); + ALOGV("updateTexImage"); + Mutex::Autolock lock(mMutex); + + if (mAbandoned) { + ALOGE("updateTexImage: GLConsumer is abandoned!"); + return NO_INIT; + } + + // Make sure the EGL state is the same as in previous calls. + status_t err = checkAndUpdateEglStateLocked(); + if (err != NO_ERROR) { + return err; + } + + BufferQueue::BufferItem item; + + // Acquire the next buffer. + // In asynchronous mode the list is guaranteed to be one buffer + // deep, while in synchronous mode we use the oldest buffer. + err = acquireBufferLocked(&item); + if (err != NO_ERROR) { + if (err == BufferQueue::NO_BUFFER_AVAILABLE) { + // This variant of updateTexImage does not guarantee that the + // texture is bound, so no need to call glBindTexture. + err = NO_ERROR; + } else { + ALOGE("updateTexImage: acquire failed: %s (%d)", + strerror(-err), err); + } + return err; + } + + + // We call the rejecter here, in case the caller has a reason to + // not accept this buffer. This is used by SurfaceFlinger to + // reject buffers which have the wrong size + int buf = item.mBuf; + if (rejecter && rejecter->reject(mSlots[buf].mGraphicBuffer, item)) { + releaseBufferLocked(buf, EGL_NO_SYNC_KHR); + return NO_ERROR; + } + + // Release the previous buffer. + err = releaseAndUpdateLocked(item); + if (err != NO_ERROR) { + return err; + } + + if (!SyncFeatures::getInstance().useNativeFenceSync()) { + // Bind the new buffer to the GL texture. + // + // Older devices require the "implicit" synchronization provided + // by glEGLImageTargetTexture2DOES, which this method calls. Newer + // devices will either call this in Layer::onDraw, or (if it's not + // a GL-composited layer) not at all. + err = bindTextureImageLocked(); + } + + return err; +} + +status_t SurfaceFlingerConsumer::bindTextureImage() +{ + Mutex::Autolock lock(mMutex); + + return bindTextureImageLocked(); +} + +// --------------------------------------------------------------------------- +}; // namespace android + |