diff options
10 files changed, 255 insertions, 19 deletions
diff --git a/libs/bufferstreams/aidl/Android.bp b/libs/bufferstreams/aidl/Android.bp new file mode 100644 index 0000000000..3f1fa4e532 --- /dev/null +++ b/libs/bufferstreams/aidl/Android.bp @@ -0,0 +1,43 @@ +// Copyright (C) 2024 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. + +aidl_interface { + name: "android.graphics.bufferstreams", + unstable: true, + flags: ["-Werror"], + srcs: ["android/graphics/bufferstreams/*.aidl"], + headers: [ + "HardwareBuffer_aidl", + ], + imports: [ + "android.hardware.common-V2", + ], + backend: { + cpp: { + enabled: false, + }, + java: { + enabled: false, + }, + ndk: { + enabled: false, + }, + rust: { + enabled: true, + additional_rustlibs: [ + "libnativewindow_rs", + ], + }, + }, +} diff --git a/libs/bufferstreams/aidl/android/graphics/bufferstreams/BufferAttachment.aidl b/libs/bufferstreams/aidl/android/graphics/bufferstreams/BufferAttachment.aidl new file mode 100644 index 0000000000..5c905b1d17 --- /dev/null +++ b/libs/bufferstreams/aidl/android/graphics/bufferstreams/BufferAttachment.aidl @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2024 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. + */ + +package android.graphics.bufferstreams; + +import android.graphics.bufferstreams.IBufferOwner; +import android.hardware.HardwareBuffer; + +// Single mapping between a buffer reference and heavy-weight data (like the +// buffer itself) and data that is stable between frames. +parcelable BufferAttachment { + // The HardwareBuffer itself. + // + // This field is @nullable for codegen, since HardwareBuffer doesn't implement Default in Rust. + // In practice, it should never be null. + @nullable HardwareBuffer buffer; + // The buffer owner to which this buffer should be returned. + IBufferOwner owner; +} diff --git a/libs/bufferstreams/aidl/android/graphics/bufferstreams/BufferCacheUpdate.aidl b/libs/bufferstreams/aidl/android/graphics/bufferstreams/BufferCacheUpdate.aidl new file mode 100644 index 0000000000..75041196a8 --- /dev/null +++ b/libs/bufferstreams/aidl/android/graphics/bufferstreams/BufferCacheUpdate.aidl @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2024 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. + */ + +package android.graphics.bufferstreams; + +import android.graphics.bufferstreams.BufferAttachment; + +// A event that changes the state downstream buffer caches. Clients are responsible for forwarding +// these messages to their clients. +union BufferCacheUpdate { + // Event requiring downstream caches to add new entries. + CacheBuffers cacheBuffers; + // Event requiring downstream caches to remove entries. + ForgetBuffers forgetBuffers; + + parcelable CacheBuffers { + // Attachments to add. + List<BufferAttachment> attachments; + } + + parcelable ForgetBuffers { + // References to remove. + long[] bufferIds; + } +} diff --git a/libs/bufferstreams/aidl/android/graphics/bufferstreams/Frame.aidl b/libs/bufferstreams/aidl/android/graphics/bufferstreams/Frame.aidl new file mode 100644 index 0000000000..1e0ec3b5db --- /dev/null +++ b/libs/bufferstreams/aidl/android/graphics/bufferstreams/Frame.aidl @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2024 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. + */ + +package android.graphics.bufferstreams; + +import android.os.ParcelFileDescriptor; + +// A Frame represents a single buffer passing through the stream. +parcelable Frame { + // The service must have provided an associated BufferAttachment and the client is required to + // maintain a cache between the two. + long bufferId; + // The expected present time of this frame, or -1 if immediate. + long presentTimeNs; + // The acquire fence of the buffer for this frame. + @nullable ParcelFileDescriptor fence; +} diff --git a/libs/bufferstreams/aidl/android/graphics/bufferstreams/IBufferOwner.aidl b/libs/bufferstreams/aidl/android/graphics/bufferstreams/IBufferOwner.aidl new file mode 100644 index 0000000000..8b25a6298e --- /dev/null +++ b/libs/bufferstreams/aidl/android/graphics/bufferstreams/IBufferOwner.aidl @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2024 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. + */ + +package android.graphics.bufferstreams; + +import android.os.ParcelFileDescriptor; + +// Interface from a client back to the owner of a buffer. +interface IBufferOwner { + // Called when the buffer is done being processed by the stream to return its owner. + oneway void onBufferReleased(in long bufferId, in @nullable ParcelFileDescriptor releaseFence); +} diff --git a/libs/bufferstreams/aidl/android/graphics/bufferstreams/IBufferSubscriber.aidl b/libs/bufferstreams/aidl/android/graphics/bufferstreams/IBufferSubscriber.aidl new file mode 100644 index 0000000000..52e8216e60 --- /dev/null +++ b/libs/bufferstreams/aidl/android/graphics/bufferstreams/IBufferSubscriber.aidl @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2024 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. + */ + +package android.graphics.bufferstreams; + +import android.graphics.bufferstreams.BufferCacheUpdate; +import android.graphics.bufferstreams.IBufferSubscription; +import android.graphics.bufferstreams.Frame; + +// Interface provided by clients to a service, mirroring the non-IPC interface. +// +// Clients are required to maintain a local cache of Buffer IDs to BufferAttachments. +interface IBufferSubscriber { + // Provide a BufferSubscription object which the client can use to request frames. + oneway void onSubscribe(in IBufferSubscription subscription); + + // Notifies the client to update its local caches. + oneway void onBufferCacheUpdate(in BufferCacheUpdate update); + + // Notifies the client that a requested frame is available. + oneway void onNext(in Frame frame); + + // Notifies the client that a fatal error has occurred. No subsequent on_next events will be + // sent by the service. + // + // Clients must empty their caches. + oneway void onError(); + + // Notifies the client that no further on_next events will be sent by the service in response + // to it cancelling the subscription. + // + // Clients must empty their caches. + oneway void onComplete(); +} diff --git a/libs/bufferstreams/aidl/android/graphics/bufferstreams/IBufferSubscription.aidl b/libs/bufferstreams/aidl/android/graphics/bufferstreams/IBufferSubscription.aidl new file mode 100644 index 0000000000..c37f4e68ea --- /dev/null +++ b/libs/bufferstreams/aidl/android/graphics/bufferstreams/IBufferSubscription.aidl @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2024 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. + */ + +package android.graphics.bufferstreams; + +// Interface provided to a IBufferSubscriber to request frames or gracefully cancel their +// subscription. +interface IBufferSubscription { + // Request n more frames. + oneway void request(long n); + // Cancel the subscription. Requested frames may continue to arrive. + oneway void cancel(); +} diff --git a/libs/bufferstreams/rust/src/buffers/buffer_owner.rs b/libs/bufferstreams/rust/src/buffers/buffer_owner.rs index a4abb9d3b7..155a8bf238 100644 --- a/libs/bufferstreams/rust/src/buffers/buffer_owner.rs +++ b/libs/bufferstreams/rust/src/buffers/buffer_owner.rs @@ -16,7 +16,7 @@ use super::Buffer; /// Trait that represents an owner of a buffer that might need to handle events such as a buffer /// being dropped. -pub trait BufferOwner { +pub trait BufferOwner: Send + Sync { /// Called when a buffer is dropped. fn on_return(&self, buffer: &Buffer); } diff --git a/libs/bufferstreams/rust/src/lib.rs b/libs/bufferstreams/rust/src/lib.rs index be1525d41f..17d4d8767f 100644 --- a/libs/bufferstreams/rust/src/lib.rs +++ b/libs/bufferstreams/rust/src/lib.rs @@ -23,8 +23,6 @@ pub mod subscriptions; use buffers::Buffer; pub use stream_config::*; -use std::time::Instant; - /// This function will print Hello World. #[no_mangle] pub extern "C" fn hello() -> bool { @@ -106,7 +104,8 @@ pub trait BufferSubscriber { /// BufferSubscriptions serve as the bridge between BufferPublishers and /// BufferSubscribers. BufferSubscribers receive a BufferSubscription when they /// subscribe to a BufferPublisher via on_subscribe. -/// This object is to be used by the BufferSubscriber to cancel its subscription +/// +/// This object is used by the BufferSubscriber to cancel its subscription /// or request more buffers. /// /// BufferSubcriptions are required to adhere to the following, based on the @@ -147,7 +146,7 @@ pub trait BufferSubscriber { /// no other Subscription exists at this point. /// * Calling Subscription.cancel MUST return normally. /// * Calling Subscription.request MUST return normally. -pub trait BufferSubscription { +pub trait BufferSubscription: Send + Sync + 'static { /// request fn request(&self, n: u64); /// cancel @@ -161,8 +160,8 @@ pub type BufferError = anyhow::Error; pub struct Frame { /// A buffer to be used this frame. pub buffer: Buffer, - /// The time at which the buffer was dispatched. - pub present_time: Instant, + /// The time at which this buffer is expected to be displayed. + pub present_time: i64, /// A fence used for reading/writing safely. pub fence: i32, } @@ -175,14 +174,12 @@ mod test { use anyhow::anyhow; use buffers::Buffer; use nativewindow::{AHardwareBuffer_Format, AHardwareBuffer_UsageFlags}; - use std::borrow::BorrowMut; - use std::error::Error; - use std::ops::Add; - use std::sync::Arc; - use std::time::Duration; + use std::{borrow::BorrowMut, error::Error, ops::Add, sync::Arc}; - use crate::publishers::testing::*; - use crate::subscribers::{testing::*, SharedSubscriber}; + use crate::{ + publishers::testing::*, + subscribers::{testing::*, SharedSubscriber}, + }; const STREAM_CONFIG: StreamConfig = StreamConfig { width: 1, @@ -200,7 +197,7 @@ mod test { .create_hardware_buffer() .expect("Unable to create hardware buffer for test"), ), - present_time: Instant::now() + Duration::from_secs(1), + present_time: 1, fence: 0, } } diff --git a/libs/bufferstreams/rust/src/publishers/buffer_pool_publisher.rs b/libs/bufferstreams/rust/src/publishers/buffer_pool_publisher.rs index 846105dacd..73a15be897 100644 --- a/libs/bufferstreams/rust/src/publishers/buffer_pool_publisher.rs +++ b/libs/bufferstreams/rust/src/publishers/buffer_pool_publisher.rs @@ -14,8 +14,6 @@ //! -use std::time::Instant; - use crate::{ buffers::BufferPool, subscriptions::SharedBufferSubscription, BufferPublisher, BufferSubscriber, Frame, StreamConfig, @@ -43,7 +41,7 @@ impl BufferPoolPublisher { /// If the [SharedBufferSubscription] is ready for a [Frame], a buffer will be requested from /// [BufferPool] and sent over to the [BufferSubscriber]. - pub fn send_next_frame(&mut self, present_time: Instant) -> bool { + pub fn send_next_frame(&mut self, present_time: i64) -> bool { if let Some(subscriber) = self.subscriber.as_mut() { if self.subscription.take_request() { if let Some(buffer) = self.buffer_pool.next_buffer() { @@ -103,7 +101,7 @@ mod test { subscriber.map_inner(|s| s.request(1)); - assert!(buffer_pool_publisher.send_next_frame(Instant::now())); + assert!(buffer_pool_publisher.send_next_frame(1)); let events = subscriber.map_inner_mut(|s| s.take_events()); assert!(matches!(events.last().unwrap(), TestingSubscriberEvent::Next(_))); |