/// Performs the logic to commit the local state of this surface.
///
/// This will update the scenic Node for this surface.
Performs the logic to commit the local state of this surface.
This will update the scenic Node for this surface.
Performs the logic to commit the local state of this surface . This will update the scenic Node for this surface .
fn commit_self(
        &mut self,
        task_queue: TaskQueue,
        callbacks: &mut Vec<ObjectRef<Callback>>,
    ) -> Result<(), Error> {
        ftrace::duration!("wayland", "Surface::commit_self");
        // Save the last buffer ID before applying updates.
        let last_buffer_id = self.content.as_ref().map(|content| content.id());
        let commands = mem::replace(&mut self.pending_commands, Vec::new());
        for command in commands {
            self.apply(command)?;
        }
        let node = match self.node.as_ref() {
            Some(node) => node,
            None => {
                // This is expected for some surfaces that aren't implemented
                // yet, like wl_pointer cursor surfaces.
                println!(
                    "No flatland instance associated with surface role {:?}; skipping commit",
                    self.role
                );
                return Ok(());
            }
        };
        if let Some(content) = &self.content {
            // Acquire image content. The instance ID ensures that usage of buffer by
            // another surface will not conflict with this surface.
            let image_content =
                content.buffer.image_content(self.image_instance_id, &node.flatland);
            let image_size = content.buffer.image_size();
            // Set image as content for transform.
            node.flatland
                .borrow()
                .proxy()
                .set_content(&mut node.transform_id.clone(), &mut image_content.id.clone())
                .expect("fidl error");
            // Set image sample region based on current crop params.
            let mut sample_region = self.crop_params.map_or(
                RectF {
                    x: 0.0,
                    y: 0.0,
                    width: image_size.width as f32,
                    height: image_size.height as f32,
                },
                |crop| RectF { x: crop.x, y: crop.y, width: crop.width, height: crop.height },
            );
            node.flatland
                .borrow()
                .proxy()
                .set_image_sample_region(&mut image_content.id.clone(), &mut sample_region)
                .expect("fidl error");
            // Set destination size based on current scale params.
            let mut destination_size = self.scale_params.map_or(
                SizeU { width: image_size.width as u32, height: image_size.height as u32 },
                |scale| SizeU { width: scale.width as u32, height: scale.height as u32 },
            );
            node.flatland
                .borrow()
                .proxy()
                .set_image_destination_size(&mut image_content.id.clone(), &mut destination_size)
                .expect("fidl error");
            // Update surface size. This is used to determine window geometry and blend mode.
            self.size = Size {
                width: destination_size.width as i32,
                height: destination_size.height as i32,
            };
            // Set blend mode based on the opaque region and if the buffer
            // has an alpha channel.
            let blend_mode = if content.buffer.has_alpha() {
                // Blending is not required if opaque region is set and
                // matches the size of the surface.
                if !self.opaque_region.rects.is_empty()
                    && self.opaque_region.rects.iter().all(|r| {
                        *r == (
                            RectKind::Add,
                            Rect { x: 0, y: 0, width: self.size.width, height: self.size.height },
                        )
                    })
                {
                    BlendMode::Src
                } else {
                    BlendMode::SrcOver
                }
            } else {
                BlendMode::Src
            };
            node.flatland
                .borrow()
                .proxy()
                .set_image_blending_function(&mut image_content.id.clone(), blend_mode)
                .expect("fidl error");
        }
        let mut translation = if let Some(window_geometry) = self.window_geometry.as_ref() {
            Vec_ { x: self.position.0 - window_geometry.x, y: self.position.1 - window_geometry.y }
        } else {
            Vec_ { x: self.position.0, y: self.position.1 }
        };
        node.flatland
            .borrow()
            .proxy()
            .set_translation(&mut node.transform_id.clone(), &mut translation)
            .expect("fidl error");
        // Create and register a release fence to release the last buffer unless
        // it's the same as the current buffer.
        // TODO(fxbug.dev/85402): Track multiple usages of the same buffer and only
        // generate the release event when all usages drop to zero.
        let buffer_id = self.content.as_ref().map(|content| content.id());
        if last_buffer_id != buffer_id {
            if let Some(last_buffer_id) = last_buffer_id {
                let release_fence = zx::Event::create().unwrap();
                node.flatland.borrow_mut().add_release_fence(
                    release_fence.duplicate_handle(zx::Rights::SAME_RIGHTS).unwrap(),
                );
                let task_queue = task_queue.clone();
                fasync::Task::local(async move {
                    let _signals =
                        fasync::OnSignals::new(&release_fence, zx::Signals::EVENT_SIGNALED)
                            .await
                            .unwrap();
                    // Safe to ignore result as EVENT_SIGNALED must have
                    // been observed if we reached this.
                    task_queue.post(move |client| {
                        client.event_queue().post(last_buffer_id, WlBufferEvent::Release)
                    });
                })
                .detach();
            }
        }
        callbacks.append(&mut self.frame_callbacks);
        Ok(())
    }
fn commit_self ( & mut self , task_queue : TaskQueue , callbacks : & mut Vec < ObjectRef < Callback > > , ) -> Result < ( ) , Error > { ftrace :: duration ! ( " " " " ) ; // Save the last buffer ID before applying updates. let last_buffer_id = self . content . as_ref ( ) . map ( | content | content . id ( ) ) ; let commands = mem :: replace ( & mut self . pending_commands , Vec :: new ( ) ) ; for command in commands { self . apply ( command ) ? ; } let node = match self . node . as_ref ( ) { Some ( node ) => node , None => { // This is expected for some surfaces that aren't implemented // yet, like wl_pointer cursor surfaces. println ! ( " " self role ) ; return Ok ( ( ) ) ; } } ; if let Some ( content ) = & self . content { // Acquire image content. The instance ID ensures that usage of buffer by // another surface will not conflict with this surface. let image_content = content . buffer . image_content ( self . image_instance_id , & node . flatland ) ; let image_size = content . buffer . image_size ( ) ; // Set image as content for transform. node . flatland . borrow ( ) . proxy ( ) . set_content ( & mut node . transform_id . clone ( ) , & mut image_content . id . clone ( ) ) . expect ( " " ) ; // Set image sample region based on current crop params. let mut sample_region = self . crop_params . map_or ( RectF { x : 0.0 , y : 0.0 , width : image_size . width as f32 , height : image_size . height as f32 , } , | crop | RectF { x : crop . x , y : crop . y , width : crop . width , height : crop . height } , ) ; node . flatland . borrow ( ) . proxy ( ) . set_image_sample_region ( & mut image_content . id . clone ( ) , & mut sample_region ) . expect ( " " ) ; // Set destination size based on current scale params. let mut destination_size = self . scale_params . map_or ( SizeU { width : image_size . width as u32 , height : image_size . height as u32 } , | scale | SizeU { width : scale . width as u32 , height : scale . height as u32 } , ) ; node . flatland . borrow ( ) . proxy ( ) . set_image_destination_size ( & mut image_content . id . clone ( ) , & mut destination_size ) . expect ( " " ) ; // Update surface size. This is used to determine window geometry and blend mode. self . size = Size { width : destination_size . width as i32 , height : destination_size . height as i32 , } ; // Set blend mode based on the opaque region and if the buffer // has an alpha channel. let blend_mode = if content . buffer . has_alpha ( ) { // Blending is not required if opaque region is set and // matches the size of the surface. if ! self . opaque_region . rects . is_empty ( ) && self . opaque_region . rects . iter ( ) . all ( | r | { * r == ( RectKind :: Add , Rect { x : 0 , y : 0 , width : self . size . width , height : self . size . height } , ) } ) { BlendMode :: Src } else { BlendMode :: SrcOver } } else { BlendMode :: Src } ; node . flatland . borrow ( ) . proxy ( ) . set_image_blending_function ( & mut image_content . id . clone ( ) , blend_mode ) . expect ( " " ) ; } let mut translation = if let Some ( window_geometry ) = self . window_geometry . as_ref ( ) { Vec_ { x : self . position . 0 - window_geometry . x , y : self . position . 1 - window_geometry . y } } else { Vec_ { x : self . position . 0 , y : self . position . 1 } } ; node . flatland . borrow ( ) . proxy ( ) . set_translation ( & mut node . transform_id . clone ( ) , & mut translation ) . expect ( " " ) ; // Create and register a release fence to release the last buffer unless // it's the same as the current buffer. // TODO(fxbug.dev/85402): Track multiple usages of the same buffer and only // generate the release event when all usages drop to zero. let buffer_id = self . content . as_ref ( ) . map ( | content | content . id ( ) ) ; if last_buffer_id != buffer_id { if let Some ( last_buffer_id ) = last_buffer_id { let release_fence = zx :: Event :: create ( ) . unwrap ( ) ; node . flatland . borrow_mut ( ) . add_release_fence ( release_fence . duplicate_handle ( zx :: Rights :: SAME_RIGHTS ) . unwrap ( ) , ) ; let task_queue = task_queue . clone ( ) ; fasync :: Task :: local ( async move { let _signals = fasync :: OnSignals :: new ( & release_fence , zx :: Signals :: EVENT_SIGNALED ) . await . unwrap ( ) ; // Safe to ignore result as EVENT_SIGNALED must have // been observed if we reached this. task_queue . post ( move | client | { client . event_queue ( ) . post ( last_buffer_id , WlBufferEvent :: Release ) } ) ; } ) . detach ( ) ; } } callbacks . append ( & mut self . frame_callbacks ) ; Ok ( ( ) ) }
Performs the logic to commit the local state of this surface.
Performs the logic to commit the local state of this surface .
&mut self
task_queue
TaskQueue
callbacks
&mut Vec<ObjectRef<Callback>>