bool plane_state_render =
plane.GetCompositionState() == DisplayPlaneState::State::kRender;
if (ignore_cursor_layer && plane.IsCursorPlane() && !plane_state_render) {
+ ignore_commit = false;
continue;
}
}
}
- plane.TransferSurfaces(last_plane, content_changed || region_changed);
- if (content_changed || region_changed) {
+ plane.TransferSurfaces(
+ last_plane, content_changed || region_changed || reset_regions);
+ if (content_changed || region_changed || reset_regions) {
if (last_plane.GetSurfaces().size() == 3) {
NativeSurface* surface = last_plane.GetOffScreenTarget();
surface->RecycleSurface(last_plane);
if (tracker.IgnoreUpdate())
return true;
- if (synchronize_) {
+ if (sync_) {
compositor_.EnsureTasksAreDone();
- synchronize_ = false;
+ sync_ = false;
}
size_t size = source_layers.size();
size_t previous_size = in_flight_layers_.size();
std::vector<OverlayLayer> layers;
bool frame_changed = (size != previous_size);
- bool previous_frame_had_cursor = frame_has_cursor_;
- bool cursor_gpu_rendered = cursor_gpu_rendered_;
+ bool cursor_state_changed = false;
bool idle_frame = tracker.RenderIdleMode() || idle_update;
- if ((state_ & kConfigurationChanged) || idle_frame) {
- frame_changed = true;
- }
+ uint32_t previous_frame_cursor_state = cursor_state_;
+ cursor_state_ = kNoCursorState;
bool layers_changed = false;
*retire_fence = -1;
uint32_t index = 0;
OverlayLayer* cursor_layer = NULL;
- frame_has_cursor_ = false;
- cursor_gpu_rendered_ = false;
+ if (previous_frame_cursor_state & kFrameHasCursor) {
+ cursor_state_changed = true;
+ }
for (size_t layer_index = 0; layer_index < size; layer_index++) {
HwcLayer* layer = source_layers.at(layer_index);
if (overlay_layer.IsCursorLayer()) {
cursor_layer = &overlay_layer;
- frame_has_cursor_ = true;
+ cursor_state_ |= kFrameHasCursor;
+ if (previous_frame_cursor_state & kFrameHasCursor) {
+ cursor_state_changed = false;
+ } else {
+ cursor_state_changed = true;
+ }
} else if (overlay_layer.HasLayerAttributesChanged()) {
layers_changed = true;
}
index++;
}
- bool cursor_state_changed = previous_frame_had_cursor != frame_has_cursor_;
- bool ignore_cursor_layer = false;
bool add_cursor_layer = false;
-
// Optimize cursor visibility state change.
if (!layers_changed && !tracker.RevalidateLayers()) {
- // Let's invalidating the whole cache when cursor state has changed
+ if ((state_ & kConfigurationChanged) || idle_frame) {
+ frame_changed = true;
+ } else if (frame_changed) {
+ if ((layers.size() == previous_size) ||
+ ((previous_frame_cursor_state & kIgnoredCursorLayer) &&
+ (layers.size() == previous_size - 1))) {
+ frame_changed = false;
+ }
+ }
+
+ // Let's avoid invalidating the whole cache when cursor state has changed
// from visible to invisible.
if (frame_changed && cursor_state_changed) {
if (previous_size - size == 1) {
- ignore_cursor_layer = true;
+ cursor_state_ |= kIgnoredCursorLayer;
} else if (size - previous_size == 1) {
// Sometimes this is first frame and we only have cursor layer.
if (!previous_plane_state_.empty() && cursor_layer) {
}
}
} else if (frame_changed ||
- (cursor_state_changed && !cursor_gpu_rendered)) {
+ (cursor_state_changed &&
+ !(previous_frame_cursor_state & kCursorIsGpuRendered))) {
layers_changed = true;
}
}
bool can_ignore_commit = false;
// Before forcing layer validation, check if content has changed
// if not continue showing the current buffer.
- GetCachedLayers(layers, ignore_cursor_layer, ¤t_composition_planes,
- &render_layers, &can_ignore_commit);
+ GetCachedLayers(layers, cursor_state_ & kIgnoredCursorLayer,
+ ¤t_composition_planes, &render_layers,
+ &can_ignore_commit);
if (add_cursor_layer) {
bool render_cursor = display_plane_manager_->ValidateCursorLayer(
cursor_layer, current_composition_planes);
HandleCommitIgnored(current_composition_planes);
return true;
}
-
} else {
- tracker.ResetTrackerState();
+ if (!idle_frame)
+ tracker.ResetTrackerState();
+
render_layers = display_plane_manager_->ValidateLayers(
layers, state_ & kConfigurationChanged, idle_frame || disable_ovelays,
current_composition_planes);
state_ &= ~kConfigurationChanged;
- if (cursor_layer) {
- cursor_gpu_rendered_ = cursor_layer->IsGpuRendered();
- } else {
- cursor_gpu_rendered_ = false;
+ if (cursor_layer && cursor_layer->IsGpuRendered()) {
+ cursor_state_ |= kCursorIsGpuRendered;
}
}
DUMP_CURRENT_COMPOSITION_PLANES();
-
+ // Handle any 3D Composition.
if (render_layers) {
if (!compositor_.BeginFrame(disable_ovelays)) {
ETRACE("Failed to initialize compositor.");
kms_fence_ = 0;
}
#endif
-
return true;
}
void DisplayQueue::ReleaseSurfaces() {
compositor_.FreeResources(false);
- synchronize_ = true;
+ sync_ = true;
}
void DisplayQueue::UpdateSurfaceInUse(
}
compositor_.Reset();
- synchronize_ = true;
+ sync_ = true;
+ cursor_state_ = kNoCursorState;
}
bool DisplayQueue::CheckPlaneFormat(uint32_t format) {
kDisableOverlayUsage = 1 << 3, // Disable Overlays.
kReleaseSurfaces = 1 << 5, // Release Native Surfaces.
kIgnoreIdleRefresh =
- 1 << 6, // Ignore refresh request during idle callback.
- kClonedMode = 1 << 7, // We are in cloned mode.
+ 1 << 6, // Ignore refresh request during idle callback.
+ kClonedMode = 1 << 7, // We are in cloned mode.
kLastFrameIdleUpdate = 1 << 8 // Last frame was a refresh for Idle state.
};
+ enum CursorState {
+ kNoCursorState = 1 << 0, // No state
+ kFrameHasCursor = 1 << 1, // Current Frame has Cursor.
+ kCursorIsGpuRendered = 1 << 2, // Current Frame Cursor is Gpu Rendered
+ kIgnoredCursorLayer = 1 << 3, // CursorLayer was ignored last frame.
+ // This is useful when we need to remove
+ // cursor layer from cache when previous
+ // frame commit was ignored.
+ };
+
struct ScalingTracker {
enum ScalingState {
kNeeedsNoSclaing = 0, // Needs no scaling.
// done
std::shared_ptr<RefreshCallback> refresh_callback_ = NULL;
uint32_t refrsh_display_id_ = 0;
- uint32_t state_ = kConfigurationChanged;
+ int state_ = kConfigurationChanged;
+ uint32_t cursor_state_ = kNoCursorState;
PhysicalDisplay* display_ = NULL;
SpinLock power_mode_lock_;
- bool synchronize_ = false;
- bool frame_has_cursor_ = false;
- bool cursor_gpu_rendered_ = false;
+ bool sync_ = false; // Synchronize with compositor thread.
};
} // namespace hwcomposer