Home | History | Annotate | Download | only in kms
      1 /*
      2  * Copyright  2014 NVIDIA Corporation
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8  * and/or sell copies of the Software, and to permit persons to whom the
      9  * Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice (including the next
     12  * paragraph) shall be included in all copies or substantial portions of the
     13  * Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
     21  * IN THE SOFTWARE.
     22  */
     23 
     24 #ifdef HAVE_CONFIG_H
     25 #include "config.h"
     26 #endif
     27 
     28 #include <errno.h>
     29 #include <string.h>
     30 
     31 #include "libkms-test.h"
     32 
     33 static int kms_plane_probe(struct kms_plane *plane)
     34 {
     35 	struct kms_device *device = plane->device;
     36 	drmModeObjectPropertiesPtr props;
     37 	drmModePlane *p;
     38 	unsigned int i;
     39 
     40 	p = drmModeGetPlane(device->fd, plane->id);
     41 	if (!p)
     42 		return -ENODEV;
     43 
     44 	/* TODO: allow dynamic assignment to CRTCs */
     45 	if (p->crtc_id == 0) {
     46 		for (i = 0; i < device->num_crtcs; i++) {
     47 			if (p->possible_crtcs & (1 << i)) {
     48 				p->crtc_id = device->crtcs[i]->id;
     49 				break;
     50 			}
     51 		}
     52 	}
     53 
     54 	for (i = 0; i < device->num_crtcs; i++) {
     55 		if (device->crtcs[i]->id == p->crtc_id) {
     56 			plane->crtc = device->crtcs[i];
     57 			break;
     58 		}
     59 	}
     60 
     61 	plane->formats = calloc(p->count_formats, sizeof(uint32_t));
     62 	if (!plane->formats)
     63 		return -ENOMEM;
     64 
     65 	for (i = 0; i < p->count_formats; i++)
     66 		plane->formats[i] = p->formats[i];
     67 
     68 	plane->num_formats = p->count_formats;
     69 
     70 	drmModeFreePlane(p);
     71 
     72 	props = drmModeObjectGetProperties(device->fd, plane->id,
     73 					   DRM_MODE_OBJECT_PLANE);
     74 	if (!props)
     75 		return -ENODEV;
     76 
     77 	for (i = 0; i < props->count_props; i++) {
     78 		drmModePropertyPtr prop;
     79 
     80 		prop = drmModeGetProperty(device->fd, props->props[i]);
     81 		if (prop) {
     82 			if (strcmp(prop->name, "type") == 0)
     83 				plane->type = props->prop_values[i];
     84 
     85 			drmModeFreeProperty(prop);
     86 		}
     87 	}
     88 
     89 	drmModeFreeObjectProperties(props);
     90 
     91 	return 0;
     92 }
     93 
     94 struct kms_plane *kms_plane_create(struct kms_device *device, uint32_t id)
     95 {
     96 	struct kms_plane *plane;
     97 
     98 	plane = calloc(1, sizeof(*plane));
     99 	if (!plane)
    100 		return NULL;
    101 
    102 	plane->device = device;
    103 	plane->id = id;
    104 
    105 	kms_plane_probe(plane);
    106 
    107 	return plane;
    108 }
    109 
    110 void kms_plane_free(struct kms_plane *plane)
    111 {
    112 	free(plane);
    113 }
    114 
    115 int kms_plane_set(struct kms_plane *plane, struct kms_framebuffer *fb,
    116 		  unsigned int x, unsigned int y)
    117 {
    118 	struct kms_device *device = plane->device;
    119 	int err;
    120 
    121 	err = drmModeSetPlane(device->fd, plane->id, plane->crtc->id, fb->id,
    122 			      0, x, y, fb->width, fb->height, 0 << 16,
    123 			      0 << 16, fb->width << 16, fb->height << 16);
    124 	if (err < 0)
    125 		return -errno;
    126 
    127 	return 0;
    128 }
    129 
    130 bool kms_plane_supports_format(struct kms_plane *plane, uint32_t format)
    131 {
    132 	unsigned int i;
    133 
    134 	for (i = 0; i < plane->num_formats; i++)
    135 		if (plane->formats[i] == format)
    136 			return true;
    137 
    138 	return false;
    139 }
    140