Example #1
0
bool Drm::getModeInfo(int device, drmModeModeInfo& mode)
{
    Mutex::Autolock _l(mLock);

    int outputIndex = getOutputIndex(device);
    if (outputIndex < 0 ) {
        return false;
    }

    DrmOutput *output= &mOutputs[outputIndex];
    if (output->connected == false) {
        ELOGTRACE("device is not connected");
        return false;
    }

    if (output->mode.hdisplay == 0 || output->mode.vdisplay == 0) {
        ELOGTRACE("invalid width or height");
        return false;
    }

    memcpy(&mode, &output->mode, sizeof(drmModeModeInfo));

#ifdef INTEL_SUPPORT_HDMI_PRIMARY
    // FIXME: use default fb size instead of hdmi mode, because to
    // support hdmi primary, we cannot report dynamic mode to SF.
    mode.hdisplay = DEFAULT_DRM_FB_WIDTH;
    mode.vdisplay = DEFAULT_DRM_FB_HEIGHT;
#endif

    return true;
}
Example #2
0
// HWC 1.4 requires that we return all of the compatible configs in getDisplayConfigs
// this is needed so getActiveConfig/setActiveConfig work correctly.  It is up to the
// user space to decide what speed to send.
drmModeModeInfoPtr Drm::detectAllConfigs(int device, int *modeCount)
{
    RETURN_NULL_IF_NOT_INIT();
    Mutex::Autolock _l(mLock);

    if (modeCount != NULL)
        *modeCount = 0;
    else
        return NULL;

    int outputIndex = getOutputIndex(device);
    if (outputIndex < 0) {
        ELOGTRACE("invalid device");
        return NULL;
    }

    DrmOutput *output= &mOutputs[outputIndex];
    if (!output->connected) {
        ELOGTRACE("device is not connected");
        return NULL;
    }

    if (output->connector->count_modes <= 0) {
        ELOGTRACE("invalid count of modes");
        return NULL;
    }

    *modeCount = output->connector->count_modes;
    return output->connector->modes;
}
Example #3
0
bool Drm::isConnected(int device)
{
    Mutex::Autolock _l(mLock);

    int output = getOutputIndex(device);
    if (output < 0 ) {
        return false;
    }

    return mOutputs[output].connected;
}
Example #4
0
bool Drm::setDpmsMode(int device, int mode)
{
    Mutex::Autolock _l(mLock);

    int output = getOutputIndex(device);
    if (output < 0 ) {
        return false;
    }

    if (mode != IDisplayDevice::DEVICE_DISPLAY_OFF &&
            mode != IDisplayDevice::DEVICE_DISPLAY_STANDBY &&
            mode != IDisplayDevice::DEVICE_DISPLAY_ON) {
        ELOGTRACE("invalid mode %d", mode);
        return false;
    }

    DrmOutput *out = &mOutputs[output];
    if (!out->connected) {
        ELOGTRACE("device is not connected");
        return false;
    }

    drmModePropertyPtr props;
    for (int i = 0; i < out->connector->count_props; i++) {
        props = drmModeGetProperty(mDrmFd, out->connector->props[i]);
        if (!props) {
            continue;
        }

        if (strcmp(props->name, "DPMS") == 0) {
            int ret = drmModeConnectorSetProperty(
                mDrmFd,
                out->connector->connector_id,
                props->prop_id,
                (mode == IDisplayDevice::DEVICE_DISPLAY_ON) ? DRM_MODE_DPMS_ON :
                        IDisplayDevice::DEVICE_DISPLAY_STANDBY == mode ?
                        DRM_MODE_DPMS_STANDBY : DRM_MODE_DPMS_OFF);
            drmModeFreeProperty(props);
            if (ret != 0) {
                ELOGTRACE("unable to set DPMS %d", mode);
                return false;
            } else {
                return true;
            }
        }
        drmModeFreeProperty(props);
    }
    return false;
}
Example #5
0
int Drm::getPanelOrientation(int device)
{
    int outputIndex = getOutputIndex(device);
    if (outputIndex < 0) {
        ELOGTRACE("invalid device");
        return PANEL_ORIENTATION_0;
    }

    DrmOutput *output= &mOutputs[outputIndex];
    if (output->connected == false) {
        ELOGTRACE("device is not connected");
        return PANEL_ORIENTATION_0;
    }

    return output->panelOrientation;
}
Example #6
0
bool Drm::setRefreshRate(int device, int hz)
{
    RETURN_FALSE_IF_NOT_INIT();
    Mutex::Autolock _l(mLock);

    if (device != IDisplayDevice::DEVICE_EXTERNAL) {
        WLOGTRACE("Setting mode on invalid device %d", device);
        return false;
    }

    int outputIndex = getOutputIndex(device);
    if (outputIndex < 0 ) {
        ELOGTRACE("invalid device");
        return false;
    }

    DrmOutput *output= &mOutputs[outputIndex];
    if (!output->connected) {
        ELOGTRACE("device is not connected");
        return false;
    }

    if (output->connector->count_modes <= 0) {
        ELOGTRACE("invalid count of modes");
        return false;
    }

    drmModeModeInfoPtr mode;
    int index = 0;
    for (int i = 0; i < output->connector->count_modes; i++) {
        mode = &output->connector->modes[i];
        if (mode->type & DRM_MODE_TYPE_PREFERRED) {
            index = i;
        }
        if (mode->hdisplay == output->mode.hdisplay &&
            mode->vdisplay == output->mode.vdisplay &&
            mode->vrefresh == (uint32_t)hz) {
            index = i;
            break;
        }
    }

    mode = &output->connector->modes[index];
    return setDrmMode(outputIndex, mode);
}
Example #7
0
bool Drm::getPhysicalSize(int device, uint32_t& width, uint32_t& height)
{
    Mutex::Autolock _l(mLock);

    int outputIndex = getOutputIndex(device);
    if (outputIndex < 0 ) {
        return false;
    }

    DrmOutput *output= &mOutputs[outputIndex];
    if (output->connected == false) {
        ELOGTRACE("device is not connected");
        return false;
    }

    width = output->connector->mmWidth;
    height = output->connector->mmHeight;
    return true;
}
Example #8
0
bool Drm::getDisplayResolution(int device, uint32_t& width, uint32_t& height)
{
    Mutex::Autolock _l(mLock);

    int outputIndex = getOutputIndex(device);
    if (outputIndex < 0) {
        return false;
    }

    DrmOutput *output= &mOutputs[outputIndex];
    if (output->connected == false) {
        ELOGTRACE("device is not connected");
        return false;
    }

    width = output->mode.hdisplay;
    height = output->mode.vdisplay;

    if (!width || !height) {
        ELOGTRACE("invalid width or height");
        return false;
    }
    return true;
}
Example #9
0
glong indic_ot_reorder(const gunichar *chars, const glong *utf8_offsets, glong char_count, const IndicOTClassTable *class_table, gunichar *out_chars, glong *char_indices, gulong *char_tags, MPreFixups **outMPreFixups)
{
    MPreFixups *mpreFixups = NULL;
    Output output;
    glong i, prev = 0;
    gboolean last_in_word = FALSE;

    if (outMPreFixups && (class_table->scriptFlags & SF_MPRE_FIXUP)) {
	mpreFixups = indic_mprefixups_new (char_count);
    }

    initOutput(&output, utf8_offsets, out_chars, char_indices, char_tags, mpreFixups);

    while (prev < char_count) {
	glong syllable = indic_ot_find_syllable(class_table, chars, prev, char_count);
	glong matra, vmabove, vmpost = syllable;

	while (vmpost > prev && indic_ot_is_vm_post(class_table, chars[vmpost - 1])) {
	    vmpost -= 1;
	}

	vmabove = vmpost;
	while (vmabove > prev && indic_ot_is_vm_above(class_table, chars[vmabove - 1])) {
	    vmabove -= 1;
	}

	matra = vmabove - 1;
	initMatra(&output, prev, blwf_p, !last_in_word);
	while (noteMatra(&output, class_table, chars[matra]) &&
	       matra != prev)
	    matra--;

	last_in_word = TRUE;
	switch (indic_ot_get_char_class(class_table, chars[prev]) & CF_CLASS_MASK) {
	case CC_RESERVED:
	    last_in_word = FALSE;
	    /* Fall through */
	case CC_INDEPENDENT_VOWEL:
	case CC_ZERO_WIDTH_MARK:
	    for (i = prev; i < syllable; i += 1) {
		writeChar(&output, chars[i], /*i*/ prev, blwf_p);
	    }

	    break;

	case CC_MODIFYING_MARK_ABOVE:
	case CC_MODIFYING_MARK_POST:
	case CC_NUKTA:
	case CC_VIRAMA:
	    /* patch for rendering fix for Malayalam SAMVRUTHOKARA by suresh */
	    if (chars[prev - 1] == 0x0D41) {
	       	 writeChar(&output, chars[prev], prev, blwf_p);
		 break;
	    }
	    /* end patch */

	case CC_AL_LAKUNA:
	    writeChar(&output, C_DOTTED_CIRCLE, prev, blwf_p);
	    writeChar(&output, chars[prev], prev, blwf_p);
	    break;

	case CC_DEPENDENT_VOWEL:
	    writeMpre(&output);
	    writeChar(&output, C_DOTTED_CIRCLE, prev, blwf_p);
	    writeMbelow(&output);
	    writeMabove(&output);
	    writeMpost(&output);
	    writeLengthMark(&output);
	    writeAlLakuna(&output);
	    break;

	case CC_CONSONANT:
	case CC_CONSONANT_WITH_NUKTA:
	{
	    guint32 length = vmabove - prev;
	    glong lastConsonant = vmabove - 1;
	    glong baseLimit = prev;
	    glong baseConsonant, postBase, postBaseLimit;
	    gboolean seenVattu, seenBelowBaseForm, supressVattu;
	    glong bcSpan;

	    /* Check for REPH at front of syllable */
	    if (length > 2 && indic_ot_is_reph(class_table, chars[prev]) && indic_ot_is_virama(class_table, chars[prev + 1])) {
		baseLimit += 2;

		/* Check for eyelash RA, if the script supports it */
		if ((class_table->scriptFlags & SF_EYELASH_RA) != 0 &&
		    chars[baseLimit] == C_SIGN_ZWJ) {
		    if (length > 3) {
			baseLimit += 1;
		    } else {
			baseLimit -= 2;
		    }
		}
	    }

	    while (lastConsonant > baseLimit && !indic_ot_is_consonant(class_table, chars[lastConsonant])) {
		lastConsonant -= 1;
	    }

	    baseConsonant = lastConsonant;
	    postBase = lastConsonant + 1;

	    postBaseLimit = class_table->scriptFlags & SF_POST_BASE_LIMIT_MASK;
	    seenVattu = false;
	    seenBelowBaseForm = false;
	    supressVattu = true;

	    while (baseConsonant > baseLimit) {
		IndicOTCharClass charClass = indic_ot_get_char_class(class_table, chars[baseConsonant]);

		if (IS_CONSONANT(charClass)) {
		    if (postBaseLimit == 0 || seenVattu ||
			(baseConsonant > baseLimit && !indic_ot_is_virama(class_table, chars[baseConsonant - 1])) ||
			!HAS_POST_OR_BELOW_BASE_FORM(charClass)) {
			break;
		    }

		    seenVattu = IS_VATTU(charClass);

		    if (HAS_POST_BASE_FORM(charClass)) {
			if (seenBelowBaseForm) {
			    break;
			}

			postBase = baseConsonant;
		    } else if (HAS_BELOW_BASE_FORM(charClass)) {
			seenBelowBaseForm = true;
		    }

		    postBaseLimit -= 1;
		}

		baseConsonant -= 1;
	    }

	    /* Write Mpre */
	    writeMpre(&output);

	    /* Write eyelash RA */
	    /* NOTE: baseLimit == prev + 3 iff eyelash RA present... */
	    if (baseLimit == prev + 3) {
		writeChar(&output, chars[prev], prev, half_p);
		writeChar(&output, chars[prev + 1], prev /*+ 1*/, half_p);
		writeChar(&output, chars[prev + 2], prev /*+ 2*/, half_p);
	    }

	    /* write any pre-base consonants */
	    supressVattu = true;

	    for (i = baseLimit; i < baseConsonant; i += 1) {
		gunichar ch = chars[i];
		/* Applying blwf to the first consonant doesn't makes sense
		 * since the below-form follows the consonant that it is
		 * put under */
		gulong tag = (i == baseLimit) ? half_p : blwf_p;
		IndicOTCharClass charClass = indic_ot_get_char_class(class_table, ch);

		if (IS_CONSONANT(charClass)) {
		    if (IS_VATTU(charClass) && supressVattu) {
			tag = nukt_p;
		    }
		    else if ((i + 2 < baseConsonant) && (chars[i + 2] == C_SIGN_ZWNJ)) {
			tag = nukt_p;
		    }

		    supressVattu = IS_VATTU(charClass);
		} else if (IS_VIRAMA(charClass) && chars[i + 1] == C_SIGN_ZWNJ)
		{
		    tag = nukt_p;
		}

		writeChar(&output, ch, /*i*/ prev, tag);
	    }

	    bcSpan = baseConsonant + 1;

	    if (bcSpan < vmabove && indic_ot_is_nukta(class_table, chars[bcSpan])) {
		bcSpan += 1;
	    }

	    if (baseConsonant == lastConsonant && bcSpan < vmabove && indic_ot_is_virama(class_table, chars[bcSpan])) {
		bcSpan += 1;

		if (bcSpan < vmabove && chars[bcSpan] == C_SIGN_ZWNJ) {
		    bcSpan += 1;
		}
	    }

	    /* note the base consonant for post-GSUB fixups */
	    noteBaseConsonant(&output);

	    /* write base consonant */
	    for (i = baseConsonant; i < bcSpan; i += 1) {
		writeChar(&output, chars[i], /*i*/ prev, nukt_p);
	    }

	    if ((class_table->scriptFlags & SF_MATRAS_AFTER_BASE) != 0) {
		gboolean is_for_0C48 = FALSE;
		if (output.fOutChars != NULL) {  /*for 0x0C48 of Telugu*/
		    int t;
		    for (t = prev; t < syllable; t++) {
			if (chars[t] == 0x0C48) {
			    writeMabove(&output);
			    writeMbelow(&output);
			    writeMpost(&output);

			    is_for_0C48 = TRUE;
			    break;
			}
		    }
		}

		if (!is_for_0C48) {
		    writeMbelow(&output);
		    writeMabove(&output);
		    writeMpost(&output);
		}
	    }

	    /* write below-base consonants */
	    if (baseConsonant != lastConsonant) {
		for (i = bcSpan + 1; i < postBase; i += 1) {
		    writeChar(&output, chars[i], /*i*/ prev, blwf_p);
		}

		if (postBase > lastConsonant) {
		    /* write halant that was after base consonant */
		    writeChar(&output, chars[bcSpan], /*bcSpan*/ prev, blwf_p);
		}
	    }

	    /* write Mbelow, Mabove */
	    if ((class_table->scriptFlags & SF_MATRAS_AFTER_BASE) == 0) {
		writeMbelow(&output);
		writeMabove(&output);
	    }

	   if ((class_table->scriptFlags & SF_REPH_AFTER_BELOW) != 0) {
		if (baseLimit == prev + 2) {
		    writeChar(&output, chars[prev], prev, rphf_p);
		    writeChar(&output, chars[prev + 1], prev /*+ 1*/, rphf_p);
		}

		/* write VMabove */
		for (i = vmabove; i < vmpost; i += 1) {
		    writeChar(&output, chars[i], /*i*/ prev, blwf_p);
		}
	    }

	    /* write post-base consonants */
	    if (baseConsonant != lastConsonant) {
		if (postBase <= lastConsonant) {
		    for (i = postBase; i <= lastConsonant; i += 1) {
			writeChar(&output, chars[i], /*i*/ prev, pstf_p);
		    }

		    /* write halant that was after base consonant */
		    writeChar(&output, chars[bcSpan], /*bcSpan*/ prev, blwf_p);
		}

		/* write the training halant, if there is one */
		if (lastConsonant < matra && indic_ot_is_virama(class_table, chars[matra])) {
		    writeChar(&output, chars[matra], /*matra*/ prev, nukt_p);
		}
	    }

	    /* write Mpost */
	    if ((class_table->scriptFlags & SF_MATRAS_AFTER_BASE) == 0) {
		writeMpost(&output);
	    }

	    writeLengthMark(&output);
	    writeAlLakuna(&output);

	    /* write reph */
	    if ((class_table->scriptFlags & SF_REPH_AFTER_BELOW) == 0) {
		if (baseLimit == prev + 2) {
		    writeChar(&output, chars[prev], prev, rphf_p);
		    writeChar(&output, chars[prev + 1], prev /*+ 1*/, rphf_p);
		}

		/* write VMabove */
		for (i = vmabove; i < vmpost; i += 1) {
		    writeChar(&output, chars[i], /*i*/ prev, blwf_p);
		}
	    }

	    /* write VMpost */
	    for (i = vmpost; i < syllable; i += 1) {
		writeChar(&output, chars[i], /*i*/ prev, blwf_p);
	    }

	    break;
	}

	default:
	    break;
	}


	prev = syllable;
    }

    if (outMPreFixups) {
	*outMPreFixups = mpreFixups;
    }

    return getOutputIndex(&output);
}
Example #10
0
bool Drm::detect(int device)
{
    RETURN_FALSE_IF_NOT_INIT();

    Mutex::Autolock _l(mLock);
    int outputIndex = getOutputIndex(device);
    if (outputIndex < 0 ) {
        return false;
    }

    resetOutput(outputIndex);

    // get drm resources
    drmModeResPtr resources = drmModeGetResources(mDrmFd);
    if (!resources) {
        ELOGTRACE("fail to get drm resources, error: %s", strerror(errno));
        return false;
    }

    drmModeConnectorPtr connector = NULL;
    DrmOutput *output = &mOutputs[outputIndex];
    bool ret = false;

    // find connector for the given device
    for (int i = 0; i < resources->count_connectors; i++) {
        if (!resources->connectors || !resources->connectors[i]) {
            ELOGTRACE("fail to get drm resources connectors, error: %s", strerror(errno));
            continue;
        }

        connector = drmModeGetConnector(mDrmFd, resources->connectors[i]);
        if (!connector) {
            ELOGTRACE("drmModeGetConnector failed");
            continue;
        }

        if (connector->connector_type != DrmConfig::getDrmConnector(device)) {
            drmModeFreeConnector(connector);
            continue;
        }

        if (connector->connection != DRM_MODE_CONNECTED) {
            ILOGTRACE("device %d is not connected", device);
            drmModeFreeConnector(connector);
            ret = true;
            break;
        }

        output->connector = connector;
        output->connected = true;

        // get proper encoder for the given connector
        if (connector->encoder_id) {
            ILOGTRACE("Drm connector has encoder attached on device %d", device);
            output->encoder = drmModeGetEncoder(mDrmFd, connector->encoder_id);
            if (!output->encoder) {
                ELOGTRACE("failed to get encoder from a known encoder id");
                // fall through to get an encoder
            }
        }
        if (!output->encoder) {
            ILOGTRACE("getting encoder for device %d", device);
            drmModeEncoderPtr encoder;
            for (int j = 0; j < resources->count_encoders; j++) {
                if (!resources->encoders || !resources->encoders[j]) {
                    ELOGTRACE("fail to get drm resources encoders, error: %s", strerror(errno));
                    continue;
                }

                encoder = drmModeGetEncoder(mDrmFd, resources->encoders[i]);
                if (!encoder) {
                    ELOGTRACE("drmModeGetEncoder failed");
                    continue;
                }
                if (encoder->encoder_type == DrmConfig::getDrmEncoder(device)) {
                    output->encoder = encoder;
                    break;
                }
                drmModeFreeEncoder(encoder);
                encoder = NULL;
            }
        }
        if (!output->encoder) {
            ELOGTRACE("failed to get drm encoder");
            break;
        }

        // get an attached crtc or spare crtc
        if (output->encoder->crtc_id) {
            ILOGTRACE("Drm encoder has crtc attached on device %d", device);
            output->crtc = drmModeGetCrtc(mDrmFd, output->encoder->crtc_id);
            if (!output->crtc) {
                ELOGTRACE("failed to get crtc from a known crtc id");
                // fall through to get a spare crtc
            }
        }
        if (!output->crtc) {
            ILOGTRACE("getting crtc for device %d", device);
            drmModeCrtcPtr crtc;
            for (int j = 0; j < resources->count_crtcs; j++) {
                if (!resources->crtcs || !resources->crtcs[j]) {
                    ELOGTRACE("fail to get drm resources crtcs, error: %s", strerror(errno));
                    continue;
                }

                crtc = drmModeGetCrtc(mDrmFd, resources->crtcs[j]);
                if (!crtc) {
                    ELOGTRACE("drmModeGetCrtc failed");
                    continue;
                }
                // check if legal crtc to the encoder
                if (output->encoder->possible_crtcs & (1<<j)) {
                    if (crtc->buffer_id == 0) {
                        output->crtc = crtc;
                        break;
                    }
                }
                drmModeFreeCrtc(crtc);
            }
        }
        if (!output->crtc) {
            ELOGTRACE("failed to get drm crtc");
            break;
        }

        // current mode
        if (output->crtc->mode_valid) {
            ILOGTRACE("mode is valid, kernel mode settings");
            memcpy(&output->mode, &output->crtc->mode, sizeof(drmModeModeInfo));
            //output->fbId = output->crtc->buffer_id;
            ret = true;
        } else {
            ELOGTRACE("mode is invalid. Kernel mode setting is not completed");
            ret = false;
        }

        if (outputIndex == OUTPUT_PRIMARY) {
            if (!readIoctl(DRM_PSB_PANEL_ORIENTATION, &output->panelOrientation, sizeof(int))) {
                ELOGTRACE("failed to get device %d orientation", device);
                output->panelOrientation = PANEL_ORIENTATION_0;
            }
        } else {
            output->panelOrientation = PANEL_ORIENTATION_0;
        }
        break;
    }

    if (!ret) {
        if (output->connector == NULL && outputIndex != OUTPUT_PRIMARY) {
            // a fatal failure on primary device
            // non fatal on secondary device
            WLOGTRACE("device %d is disabled?", device);
            ret = true;
        }
         resetOutput(outputIndex);
    } else if (output->connected) {
        ILOGTRACE("mode is: %dx%d@%dHz", output->mode.hdisplay, output->mode.vdisplay, output->mode.vrefresh);
    }

    drmModeFreeResources(resources);
    return ret;
}