void Layer::setPerFrameData(hwc_layer_t* hwcl) { const sp<GraphicBuffer>& buffer(mActiveBuffer); if (buffer == NULL) { // this can happen if the client never drew into this layer yet, // or if we ran out of memory. In that case, don't let // HWC handle it. hwcl->flags |= HWC_SKIP_LAYER; hwcl->handle = NULL; } else { hwcl->handle = buffer->handle; } updateLayerQcomFlags(LAYER_ASYNCHRONOUS_STATUS, !mSurfaceTexture->isSynchronousMode(), mLayerQcomFlags); hwcl->flags = getPerFrameFlags(hwcl->flags, mLayerQcomFlags); }
Layer::Layer(SurfaceFlinger* flinger, DisplayID display, const sp<Client>& client) : LayerBaseClient(flinger, display, client), mTextureName(-1U), mQueuedFrames(0), mCurrentTransform(0), mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), mCurrentOpacity(true), mFormat(PIXEL_FORMAT_NONE), mGLExtensions(GLExtensions::getInstance()), mOpaqueLayer(true), mNeedsDithering(false), mSecure(false), mProtectedByApp(false), mLayerQcomFlags(0) { mCurrentCrop.makeInvalid(); glGenTextures(1, &mTextureName); updateLayerQcomFlags(LAYER_UPDATE_STATUS, true, mLayerQcomFlags); }
void Layer::lockPageFlip(bool& recomputeVisibleRegions) { if (mQueuedFrames > 0) { // Capture the old state of the layer for comparisons later const bool oldOpacity = isOpaque(); sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer; // signal another event if we have more frames pending if (android_atomic_dec(&mQueuedFrames) > 1) { mFlinger->signalEvent(); } if (mSurfaceTexture->updateTexImage() < NO_ERROR) { // something happened! recomputeVisibleRegions = true; return; } #ifdef QCOM_HARDWARE updateLayerQcomFlags(LAYER_UPDATE_STATUS, true, mLayerQcomFlags); #endif // update the active buffer mActiveBuffer = mSurfaceTexture->getCurrentBuffer(); const Rect crop(mSurfaceTexture->getCurrentCrop()); const uint32_t transform(mSurfaceTexture->getCurrentTransform()); const uint32_t scalingMode(mSurfaceTexture->getCurrentScalingMode()); if ((crop != mCurrentCrop) || (transform != mCurrentTransform) || (scalingMode != mCurrentScalingMode)) { mCurrentCrop = crop; mCurrentTransform = transform; mCurrentScalingMode = scalingMode; mFlinger->invalidateHwcGeometry(); } GLfloat textureMatrix[16]; mSurfaceTexture->getTransformMatrix(textureMatrix); if (memcmp(textureMatrix, mTextureMatrix, sizeof(textureMatrix))) { memcpy(mTextureMatrix, textureMatrix, sizeof(textureMatrix)); mFlinger->invalidateHwcGeometry(); } uint32_t bufWidth = mActiveBuffer->getWidth(); uint32_t bufHeight = mActiveBuffer->getHeight(); if (oldActiveBuffer != NULL) { if (bufWidth != uint32_t(oldActiveBuffer->width) || bufHeight != uint32_t(oldActiveBuffer->height)) { mFlinger->invalidateHwcGeometry(); } } mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format); if (oldOpacity != isOpaque()) { recomputeVisibleRegions = true; } glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // update the layer size if needed const Layer::State& front(drawingState()); // FIXME: mPostedDirtyRegion = dirty & bounds mPostedDirtyRegion.set(front.w, front.h); if ((front.w != front.requested_w) || (front.h != front.requested_h)) { // check that we received a buffer of the right size // (Take the buffer's orientation into account) if (mCurrentTransform & Transform::ROT_90) { swap(bufWidth, bufHeight); } if (isFixedSize() || (bufWidth == front.requested_w && bufHeight == front.requested_h)) { // Here we pretend the transaction happened by updating the // current and drawing states. Drawing state is only accessed // in this thread, no need to have it locked Layer::State& editDraw(mDrawingState); editDraw.w = editDraw.requested_w; editDraw.h = editDraw.requested_h; // We also need to update the current state so that we don't // end-up doing too much work during the next transaction. // NOTE: We actually don't need hold the transaction lock here // because State::w and State::h are only accessed from // this thread Layer::State& editTemp(currentState()); editTemp.w = editDraw.w; editTemp.h = editDraw.h; // recompute visible region recomputeVisibleRegions = true; } LOGD_IF(DEBUG_RESIZE, "lockPageFlip : " " (layer=%p), buffer (%ux%u, tr=%02x), " "requested (%dx%d)", this, bufWidth, bufHeight, mCurrentTransform, front.requested_w, front.requested_h); } #ifdef QCOM_HARDWARE } else { updateLayerQcomFlags(LAYER_UPDATE_STATUS, false, mLayerQcomFlags); #endif } }
void Layer::setIsUpdating(bool isUpdating) { updateLayerQcomFlags(LAYER_UPDATE_STATUS, isUpdating, mLayerQcomFlags); }