summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2012-07-05 15:41:38 +0100
committerDave Airlie <airlied@redhat.com>2012-07-07 10:37:45 +0100
commit426bc0a28edbe0e9153f692a02dd25f744ffa034 (patch)
treec6073d639665eeeaa5d1b37f17b70f63ac4266d5
parent12905dfaf01088a00f4a0a78cffba03329e7b724 (diff)
randr: add hooks for offload sink provider protocol
This adds the protocol handler and associated providers handling for the offload slaves, it allows two providers to be connected as offload sink/source. Reviewed-by: Keith Packard <keithp@keithp.com> Reviewed-by: Adam Jackson <ajax@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--randr/randrstr.h10
-rw-r--r--randr/rrdispatch.c2
-rw-r--r--randr/rrprovider.c54
3 files changed, 65 insertions, 1 deletions
diff --git a/randr/randrstr.h b/randr/randrstr.h
index 5ca8830de..16e7d01b8 100644
--- a/randr/randrstr.h
+++ b/randr/randrstr.h
@@ -164,6 +164,7 @@ struct _rrProvider {
int nameLength;
RRPropertyPtr properties;
Bool pendingProperties;
+ struct _rrProvider *offload_sink;
struct _rrProvider *output_source;
};
@@ -226,6 +227,11 @@ typedef Bool (*RRProviderSetOutputSourceProcPtr)(ScreenPtr pScreen,
RRProviderPtr provider,
RRProviderPtr output_source);
+typedef Bool (*RRProviderSetOffloadSinkProcPtr)(ScreenPtr pScreen,
+ RRProviderPtr provider,
+ RRProviderPtr offload_sink);
+
+
/* These are for 1.0 compatibility */
typedef struct _rrRefresh {
@@ -278,6 +284,7 @@ typedef struct _rrScrPriv {
RRCrtcSetScanoutPixmapProcPtr rrCrtcSetScanoutPixmap;
RRProviderSetOutputSourceProcPtr rrProviderSetOutputSource;
+ RRProviderSetOffloadSinkProcPtr rrProviderSetOffloadSink;
RRProviderGetPropertyProcPtr rrProviderGetProperty;
RRProviderSetPropertyProcPtr rrProviderSetProperty;
/*
@@ -888,6 +895,9 @@ ProcRRGetProviderInfo(ClientPtr client);
extern _X_EXPORT int
ProcRRSetProviderOutputSource(ClientPtr client);
+extern _X_EXPORT int
+ProcRRSetProviderOffloadSink(ClientPtr client);
+
extern _X_EXPORT Bool
RRProviderInit(void);
diff --git a/randr/rrdispatch.c b/randr/rrdispatch.c
index 6fe51c77a..1942d74f8 100644
--- a/randr/rrdispatch.c
+++ b/randr/rrdispatch.c
@@ -245,7 +245,7 @@ int (*ProcRandrVector[RRNumberRequests]) (ClientPtr) = {
/* V1.4 additions */
ProcRRGetProviders, /* 32 */
ProcRRGetProviderInfo, /* 33 */
- NULL, /* 34 */
+ ProcRRSetProviderOffloadSink, /* 34 */
ProcRRSetProviderOutputSource, /* 35 */
ProcRRListProviderProperties, /* 36 */
ProcRRQueryProviderProperty, /* 37 */
diff --git a/randr/rrprovider.c b/randr/rrprovider.c
index 8385d3f5f..c4fe36980 100644
--- a/randr/rrprovider.c
+++ b/randr/rrprovider.c
@@ -175,10 +175,15 @@ ProcRRGetProviderInfo (ClientPtr client)
/* count associated providers */
rep.nAssociatedProviders = 0;
+ if (provider->offload_sink)
+ rep.nAssociatedProviders++;
if (provider->output_source)
rep.nAssociatedProviders++;
xorg_list_for_each_entry(provscreen, &pScreen->output_slave_list, output_head)
rep.nAssociatedProviders++;
+ xorg_list_for_each_entry(provscreen, &pScreen->offload_slave_list, offload_head)
+ rep.nAssociatedProviders++;
+
rep.length = (pScrPriv->numCrtcs + pScrPriv->numOutputs +
(rep.nAssociatedProviders * 2) + bytes_to_int32(rep.nameLength));
@@ -210,6 +215,15 @@ ProcRRGetProviderInfo (ClientPtr client)
}
i = 0;
+ if (provider->offload_sink) {
+ providers[i] = provider->offload_sink->id;
+ if (client->swapped)
+ swapl(&providers[i]);
+ prov_cap[i] = RR_Capability_SinkOffload;
+ if (client->swapped)
+ swapl(&prov_cap[i]);
+ i++;
+ }
if (provider->output_source) {
providers[i] = provider->output_source->id;
if (client->swapped)
@@ -228,6 +242,17 @@ ProcRRGetProviderInfo (ClientPtr client)
swapl(&prov_cap[i]);
i++;
}
+ xorg_list_for_each_entry(provscreen, &pScreen->offload_slave_list, offload_head) {
+ pScrProvPriv = rrGetScrPriv(provscreen);
+ providers[i] = pScrProvPriv->provider->id;
+ if (client->swapped)
+ swapl(&providers[i]);
+ prov_cap[i] = RR_Capability_SourceOffload;
+ if (client->swapped)
+ swapl(&prov_cap[i]);
+ i++;
+ }
+
memcpy(name, provider->name, rep.nameLength);
if (client->swapped) {
@@ -279,6 +304,35 @@ ProcRRSetProviderOutputSource(ClientPtr client)
return Success;
}
+int
+ProcRRSetProviderOffloadSink(ClientPtr client)
+{
+ REQUEST(xRRSetProviderOffloadSinkReq);
+ rrScrPrivPtr pScrPriv;
+ RRProviderPtr provider, sink_provider = NULL;
+ ScreenPtr pScreen;
+
+ REQUEST_AT_LEAST_SIZE(xRRSetProviderOffloadSinkReq);
+
+ VERIFY_RR_PROVIDER(stuff->provider, provider, DixReadAccess);
+ if (!(provider->capabilities & RR_Capability_SourceOffload))
+ return BadValue;
+
+ if (stuff->sink_provider) {
+ VERIFY_RR_PROVIDER(stuff->sink_provider, sink_provider, DixReadAccess);
+ if (!(sink_provider->capabilities & RR_Capability_SinkOffload))
+ return BadValue;
+ }
+ pScreen = provider->pScreen;
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ pScrPriv->rrProviderSetOffloadSink(pScreen, provider, sink_provider);
+
+ RRTellChanged (pScreen);
+
+ return Success;
+}
+
RRProviderPtr
RRProviderCreate(ScreenPtr pScreen, const char *name,
int nameLength)