////////////////////////////////////////////////////////////////////////////////
// Do not modify!
// Generated by rpcapi
////////////////////////////////////////////////////////////////////////////////

package service

import (
	"io"

	"android.googlesource.com/platform/tools/gpu/log"
	"android.googlesource.com/platform/tools/gpu/rpc"
)

type client struct {
	rpc.Client
}

func CreateClient(r io.Reader, w io.Writer, mtu int) RPC {
	return client{rpc.NewClient(r, w, mtu)}
}

// Client compliance
func (c client) Import(l log.Logger, name string, Data U8Array) (res CaptureId, err error) {
	var val interface{}
	if val, err = c.Send(&callImport{name: name, Data: Data}); err == nil {
		res = val.(*resultImport).value
	} else {
		l.Errorf("RPC Import failed with error: %v", err)
	}
	return
}

func (c client) GetCaptures(l log.Logger) (res CaptureIdArray, err error) {
	var val interface{}
	if val, err = c.Send(&callGetCaptures{}); err == nil {
		res = val.(*resultGetCaptures).value
	} else {
		l.Errorf("RPC GetCaptures failed with error: %v", err)
	}
	return
}

func (c client) GetDevices(l log.Logger) (res DeviceIdArray, err error) {
	var val interface{}
	if val, err = c.Send(&callGetDevices{}); err == nil {
		res = val.(*resultGetDevices).value
	} else {
		l.Errorf("RPC GetDevices failed with error: %v", err)
	}
	return
}

func (c client) GetState(l log.Logger, capture CaptureId, after uint64) (res BinaryId, err error) {
	var val interface{}
	if val, err = c.Send(&callGetState{capture: capture, after: after}); err == nil {
		res = val.(*resultGetState).value
	} else {
		l.Errorf("RPC GetState failed with error: %v", err)
	}
	return
}

func (c client) GetHierarchy(l log.Logger, capture CaptureId) (res HierarchyId, err error) {
	var val interface{}
	if val, err = c.Send(&callGetHierarchy{capture: capture}); err == nil {
		res = val.(*resultGetHierarchy).value
	} else {
		l.Errorf("RPC GetHierarchy failed with error: %v", err)
	}
	return
}

func (c client) GetMemoryInfo(l log.Logger, capture CaptureId, after uint64, rng MemoryRange) (res MemoryInfoId, err error) {
	var val interface{}
	if val, err = c.Send(&callGetMemoryInfo{capture: capture, after: after, rng: rng}); err == nil {
		res = val.(*resultGetMemoryInfo).value
	} else {
		l.Errorf("RPC GetMemoryInfo failed with error: %v", err)
	}
	return
}

func (c client) GetFramebufferColor(l log.Logger, device DeviceId, capture CaptureId, api ApiId, after uint64, settings RenderSettings) (res ImageInfoId, err error) {
	var val interface{}
	if val, err = c.Send(&callGetFramebufferColor{device: device, capture: capture, api: api, after: after, settings: settings}); err == nil {
		res = val.(*resultGetFramebufferColor).value
	} else {
		l.Errorf("RPC GetFramebufferColor failed with error: %v", err)
	}
	return
}

func (c client) GetFramebufferDepth(l log.Logger, device DeviceId, capture CaptureId, api ApiId, after uint64) (res ImageInfoId, err error) {
	var val interface{}
	if val, err = c.Send(&callGetFramebufferDepth{device: device, capture: capture, api: api, after: after}); err == nil {
		res = val.(*resultGetFramebufferDepth).value
	} else {
		l.Errorf("RPC GetFramebufferDepth failed with error: %v", err)
	}
	return
}

func (c client) GetTimingInfo(l log.Logger, device DeviceId, capture CaptureId, mask TimingMask) (res TimingInfoId, err error) {
	var val interface{}
	if val, err = c.Send(&callGetTimingInfo{device: device, capture: capture, mask: mask}); err == nil {
		res = val.(*resultGetTimingInfo).value
	} else {
		l.Errorf("RPC GetTimingInfo failed with error: %v", err)
	}
	return
}

func (c client) PrerenderFramebuffers(l log.Logger, device DeviceId, capture CaptureId, api ApiId, width uint32, height uint32, atomIds U64Array) (res BinaryId, err error) {
	var val interface{}
	if val, err = c.Send(&callPrerenderFramebuffers{device: device, capture: capture, api: api, width: width, height: height, atomIds: atomIds}); err == nil {
		res = val.(*resultPrerenderFramebuffers).value
	} else {
		l.Errorf("RPC PrerenderFramebuffers failed with error: %v", err)
	}
	return
}

func (c client) ReplaceAtom(l log.Logger, capture CaptureId, atomId uint64, atomType uint16, data Binary) (res CaptureId, err error) {
	var val interface{}
	if val, err = c.Send(&callReplaceAtom{capture: capture, atomId: atomId, atomType: atomType, data: data}); err == nil {
		res = val.(*resultReplaceAtom).value
	} else {
		l.Errorf("RPC ReplaceAtom failed with error: %v", err)
	}
	return
}

func (c client) ResolveAtomStream(l log.Logger, id AtomStreamId) (res AtomStream, err error) {
	var val interface{}
	if val, err = c.Send(&callResolveAtomStream{id: id}); err == nil {
		res = val.(*resultResolveAtomStream).value
	} else {
		l.Errorf("RPC ResolveAtomStream failed with error: %v", err)
	}
	return
}

func (c client) ResolveBinary(l log.Logger, id BinaryId) (res Binary, err error) {
	var val interface{}
	if val, err = c.Send(&callResolveBinary{id: id}); err == nil {
		res = val.(*resultResolveBinary).value
	} else {
		l.Errorf("RPC ResolveBinary failed with error: %v", err)
	}
	return
}

func (c client) ResolveCapture(l log.Logger, id CaptureId) (res Capture, err error) {
	var val interface{}
	if val, err = c.Send(&callResolveCapture{id: id}); err == nil {
		res = val.(*resultResolveCapture).value
	} else {
		l.Errorf("RPC ResolveCapture failed with error: %v", err)
	}
	return
}

func (c client) ResolveDevice(l log.Logger, id DeviceId) (res Device, err error) {
	var val interface{}
	if val, err = c.Send(&callResolveDevice{id: id}); err == nil {
		res = val.(*resultResolveDevice).value
	} else {
		l.Errorf("RPC ResolveDevice failed with error: %v", err)
	}
	return
}

func (c client) ResolveHierarchy(l log.Logger, id HierarchyId) (res Hierarchy, err error) {
	var val interface{}
	if val, err = c.Send(&callResolveHierarchy{id: id}); err == nil {
		res = val.(*resultResolveHierarchy).value
	} else {
		l.Errorf("RPC ResolveHierarchy failed with error: %v", err)
	}
	return
}

func (c client) ResolveImageInfo(l log.Logger, id ImageInfoId) (res ImageInfo, err error) {
	var val interface{}
	if val, err = c.Send(&callResolveImageInfo{id: id}); err == nil {
		res = val.(*resultResolveImageInfo).value
	} else {
		l.Errorf("RPC ResolveImageInfo failed with error: %v", err)
	}
	return
}

func (c client) ResolveMemoryInfo(l log.Logger, id MemoryInfoId) (res MemoryInfo, err error) {
	var val interface{}
	if val, err = c.Send(&callResolveMemoryInfo{id: id}); err == nil {
		res = val.(*resultResolveMemoryInfo).value
	} else {
		l.Errorf("RPC ResolveMemoryInfo failed with error: %v", err)
	}
	return
}

func (c client) ResolveSchema(l log.Logger, id SchemaId) (res Schema, err error) {
	var val interface{}
	if val, err = c.Send(&callResolveSchema{id: id}); err == nil {
		res = val.(*resultResolveSchema).value
	} else {
		l.Errorf("RPC ResolveSchema failed with error: %v", err)
	}
	return
}

func (c client) ResolveTimingInfo(l log.Logger, id TimingInfoId) (res TimingInfo, err error) {
	var val interface{}
	if val, err = c.Send(&callResolveTimingInfo{id: id}); err == nil {
		res = val.(*resultResolveTimingInfo).value
	} else {
		l.Errorf("RPC ResolveTimingInfo failed with error: %v", err)
	}
	return
}
