From 0d792ce45570683ac45842753a49e8781d59797c Mon Sep 17 00:00:00 2001 From: Michael Wu Date: Tue, 9 Dec 2014 13:27:01 -0500 Subject: [PATCH] Convert C code to Rust --- ports/gonk/src/native_window_glue.cpp | 63 +----------- ports/gonk/src/window.rs | 136 ++++++++++++++++++-------- 2 files changed, 98 insertions(+), 101 deletions(-) diff --git a/ports/gonk/src/native_window_glue.cpp b/ports/gonk/src/native_window_glue.cpp index d08fc7f9e78..434f47f81d3 100644 --- a/ports/gonk/src/native_window_glue.cpp +++ b/ports/gonk/src/native_window_glue.cpp @@ -4,64 +4,33 @@ #include #include -#include #include "system/window.h" -#include "utils/Atomic.h" struct GonkNativeWindow { ANativeWindow window; - volatile int32_t count; int (*set_usage)(struct ANativeWindow* window, int usage); int (*set_format)(struct ANativeWindow* window, int format); int (*set_transform)(struct ANativeWindow* window, int transform); int (*set_dimensions)(struct ANativeWindow* window, int w, int h); int (*api_connect)(struct ANativeWindow* window, int api); int (*api_disconnect)(struct ANativeWindow* window, int api); - // XXX Implement this in rust - static void incRef(struct android_native_base_t* base) { - GonkNativeWindow *gnw = (GonkNativeWindow *) base; - android_atomic_inc(&gnw->count); - } - - static void decRef(struct android_native_base_t* base) { - GonkNativeWindow *gnw = (GonkNativeWindow *) base; - const int32_t c = android_atomic_dec(&gnw->count); - if (c <= 0) - free(base); - } -}; - -struct GonkNativeWindowBuffer { - ANativeWindowBuffer buffer; - volatile int32_t count; - - static void incRef(struct android_native_base_t* base) { - GonkNativeWindowBuffer *gnw = (GonkNativeWindowBuffer *) base; - android_atomic_inc(&gnw->count); - } - - static void decRef(struct android_native_base_t* base) { - GonkNativeWindowBuffer *gnw = (GonkNativeWindowBuffer *) base; - const int32_t c = android_atomic_dec(&gnw->count); - if (c <= 0) - free(base); - } }; // Rust doesn't support implementing variadic functions, so handle that here -static int perform(struct ANativeWindow* window, int op, ...) { +extern "C" int +gnw_perform(struct ANativeWindow* window, int op, ...) { GonkNativeWindow *gnw = (GonkNativeWindow *)window; va_list ap; switch (op) { - case NATIVE_WINDOW_SET_USAGE: { + case NATIVE_WINDOW_SET_USAGE: { int usage; va_start(ap, op); usage = va_arg(ap, int); va_end(ap); return gnw->set_usage(window, usage); - } + } case NATIVE_WINDOW_SET_BUFFERS_FORMAT: { int format; va_start(ap, op); @@ -103,27 +72,3 @@ static int perform(struct ANativeWindow* window, int op, ...) { return -1; } } - -extern "C" void* -alloc_native_window(uint32_t size) -{ - GonkNativeWindow *gnw = (GonkNativeWindow *)calloc(size, 1); - ANativeWindow *window = &gnw->window; - GonkNativeWindow::incRef(&window->common); - - window->common.incRef = GonkNativeWindow::incRef; - window->common.decRef = GonkNativeWindow::decRef; - window->perform = perform; - return gnw; -} - -extern "C" void* -alloc_native_buffer(uint32_t size) -{ - GonkNativeWindowBuffer *buf = (GonkNativeWindowBuffer *)calloc(size, 1); - buf->buffer.common.incRef = GonkNativeWindowBuffer::incRef; - buf->buffer.common.decRef = GonkNativeWindowBuffer::decRef; - - GonkNativeWindowBuffer::incRef(&buf->buffer.common); - return buf; -} diff --git a/ports/gonk/src/window.rs b/ports/gonk/src/window.rs index 691bfde286d..9da015b1114 100644 --- a/ports/gonk/src/window.rs +++ b/ports/gonk/src/window.rs @@ -18,6 +18,7 @@ use std::comm::Receiver; use std::rc::Rc; use std::mem::transmute; use std::mem::size_of; +use std::mem::zeroed; use std::ptr; use servo_util::geometry::ScreenPx; use gleam::gl; @@ -282,13 +283,13 @@ pub struct alloc_device { #[allow(dead_code)] pub struct GonkNativeWindow { window: ANativeWindow, - count: i32, // Refcount. Managed by C code. Should rewrite in rust. set_usage: extern fn(*mut GonkNativeWindow, c_int) -> c_int, set_format: extern fn(*mut GonkNativeWindow, c_int) -> c_int, set_transform: extern fn(*mut GonkNativeWindow, c_int) -> c_int, set_dimensions: extern fn(*mut GonkNativeWindow, c_int, c_int) -> c_int, api_connect: extern fn(*mut GonkNativeWindow, c_int) -> c_int, api_disconnect: extern fn(*mut GonkNativeWindow, c_int) -> c_int, + count: i32, alloc_dev: *mut alloc_device, hwc_dev: *mut hwc_composer_device, width: i32, @@ -310,14 +311,12 @@ impl ANativeBase { #[repr(C)] pub struct GonkNativeWindowBuffer { buffer: ANativeWindowBuffer, - count: i32, // Refcount. Managed by C code. + count: i32, } -#[link(name = "cutils")] #[link(name = "native_window_glue", kind = "static")] extern { - fn alloc_native_window(size: u32) -> *mut GonkNativeWindow; - fn alloc_native_buffer(size: u32) -> *mut GonkNativeWindowBuffer; + fn gnw_perform(win: *mut ANativeWindow, op: c_int, ...) -> c_int; } #[link(name = "suspend")] @@ -454,34 +453,65 @@ extern fn api_disconnect(window: *mut GonkNativeWindow, 0 } -#[allow(unused_variables)] +extern fn gnw_incRef(base: *mut ANativeBase) { + let mut win: &mut GonkNativeWindow = unsafe { transmute(base) }; + win.count += 1; +} + +extern fn gnw_decRef(base: *mut ANativeBase) { + let mut win: &mut GonkNativeWindow = unsafe { transmute(base) }; + win.count -= 1; + if win.count == 0 { + unsafe { transmute::<_, Box>(base) }; + } +} + impl GonkNativeWindow { pub fn new(alloc_dev: *mut alloc_device, hwc_dev: *mut hwc_composer_device, width: i32, height: i32, usage: c_int) -> *mut GonkNativeWindow { - let win: &mut GonkNativeWindow; - unsafe { - win = transmute(alloc_native_window(size_of::() as u32)); - } - - win.window.common.magic = ANativeBase::magic('_', 'w', 'n', 'd'); - win.window.common.version = size_of::() as u32; - win.window.setSwapInterval = setSwapInterval; - win.window.query = query; - win.window.dequeueBuffer = dequeueBuffer; - win.window.queueBuffer = queueBuffer; - win.window.cancelBuffer = cancelBuffer; - win.set_usage = set_usage; - win.set_format = set_format; - win.set_transform = set_transform; - win.set_dimensions = set_dimensions; - win.api_connect = api_connect; - win.api_disconnect = api_disconnect; - win.alloc_dev = alloc_dev; - win.hwc_dev = hwc_dev; - win.width = width; - win.height = height; - win.usage = usage; - win.last_idx = -1; - win.fences = [-1, -1]; + let mut win = box GonkNativeWindow { + window: ANativeWindow { + common: ANativeBase { + magic: ANativeBase::magic('_', 'w', 'n', 'd'), + version: size_of::() as u32, + reserved: unsafe { zeroed() }, + incRef: gnw_incRef, + decRef: gnw_decRef, + }, + flags: 0, + minSwapInterval: 0, + maxSwapInterval: 0, + xdpi: 0f32, + ydpi: 0f32, + oem: unsafe { zeroed() }, + setSwapInterval: setSwapInterval, + dequeueBuffer_DEPRECATED: 0, + lockBuffer_DEPRECATED: 0, + queueBuffer_DEPRECATED: 0, + query: query, + perform: unsafe { transmute(gnw_perform) }, + cancelBuffer_DEPRECATED: 0, + dequeueBuffer: dequeueBuffer, + queueBuffer: queueBuffer, + cancelBuffer: cancelBuffer, + }, + set_usage: set_usage, + set_format: set_format, + set_transform: set_transform, + set_dimensions: set_dimensions, + api_connect: api_connect, + api_disconnect: api_disconnect, + count: 1, + alloc_dev: alloc_dev, + hwc_dev: hwc_dev, + width: width, + height: height, + format: 0, + usage: usage, + last_fence: -1, + last_idx: -1, + bufs: unsafe { zeroed() }, + fences: [-1, -1], + }; unsafe { transmute(win) } } @@ -554,23 +584,45 @@ impl GonkNativeWindow { } } +extern fn gnwb_incRef(base: *mut ANativeBase) { + let mut buf: &mut GonkNativeWindowBuffer = unsafe { transmute(base) }; + buf.count += 1; +} + +extern fn gnwb_decRef(base: *mut ANativeBase) { + let mut buf: &mut GonkNativeWindowBuffer = unsafe { transmute(base) }; + buf.count -= 1; + if buf.count == 0 { + unsafe { transmute::<_, Box>(base) }; + } +} + impl GonkNativeWindowBuffer { pub fn new(dev: *mut alloc_device, width: i32, height: i32, format: c_int, usage: c_int) -> *mut GonkNativeWindowBuffer { - let buf: &mut GonkNativeWindowBuffer; - unsafe { - buf = transmute(alloc_native_buffer(size_of::() as u32)); - } + let mut buf = box GonkNativeWindowBuffer { + buffer: ANativeWindowBuffer { + common: ANativeBase { + magic: ANativeBase::magic('_', 'b', 'f', 'r'), + version: size_of::() as u32, + reserved: unsafe { zeroed() }, + incRef: gnwb_incRef, + decRef: gnwb_decRef, + }, + width: width, + height: height, + stride: 0, + format: format, + usage: usage, + reserved: unsafe { zeroed() }, + handle: ptr::null(), + reserved_proc: unsafe { zeroed() }, + }, + count: 1, + }; - buf.buffer.common.magic = ANativeBase::magic('_', 'b', 'f', 'r'); - buf.buffer.common.version = size_of::() as u32; let ret = unsafe { ((*dev).alloc)(dev, width, height, format, usage, &mut buf.buffer.handle, &mut buf.buffer.stride) }; assert!(ret == 0, "Failed to allocate gralloc buffer!"); - buf.buffer.width = width; - buf.buffer.height = height; - buf.buffer.format = format; - buf.buffer.usage = usage; - unsafe { transmute(buf) } } }