void
GrallocTextureHostBasic::SetCropRect(nsIntRect aCropRect)
{
  MOZ_ASSERT(aCropRect.TopLeft() == gfx::IntPoint(0, 0));
  MOZ_ASSERT(!aCropRect.IsEmpty());
  MOZ_ASSERT(aCropRect.width <= mSize.width);
  MOZ_ASSERT(aCropRect.height <= mSize.height);

  gfx::IntSize cropSize(aCropRect.width, aCropRect.height);
  if (mCropSize == cropSize) {
    return;
  }

  mCropSize = cropSize;
  ClearTextureSource();
}
void RenderSettingsDialog::apply(SceneContext *ctx) {
	Scene *scene = new Scene(ctx->scene);
	ref<Sensor> oldSensor = scene->getSensor();
	Film *oldFilm = oldSensor->getFilm();
	Properties filmProps = oldSensor->getFilm()->getProperties();
	ref<PluginManager> pluginMgr = PluginManager::getInstance();

	/* Temporarily set up a new file resolver */
	ref<Thread> thread = Thread::getThread();
	ref<FileResolver> oldResolver = thread->getFileResolver();
	ref<FileResolver> newResolver = oldResolver->clone();
	newResolver->prependPath(fs::absolute(scene->getSourceFile()).parent_path());
	thread->setFileResolver(newResolver);

	/* Configure the reconstruction filter */
	Properties rFilterProps(getPluginName(ui->rFilterBox));
	if (m_rFilterNode != NULL)
		m_rFilterNode->putProperties(rFilterProps);
	ref<ReconstructionFilter> rFilter = static_cast<ReconstructionFilter *>
		(pluginMgr->createObject(MTS_CLASS(ReconstructionFilter), rFilterProps));
	rFilter->configure();

	/* Configure the sampler */
	Properties samplerProps(getPluginName(ui->samplerBox));
	if (m_samplerNode != NULL)
		m_samplerNode->putProperties(samplerProps);
	ref<Sampler> sampler = static_cast<Sampler *>
		(pluginMgr->createObject(MTS_CLASS(Sampler), samplerProps));
	sampler->configure();

	/* Configure the integrator */
	Properties integratorProps(getPluginName(ui->integratorBox));
	if (m_integratorNode != NULL)
		m_integratorNode->putProperties(integratorProps);
	ref<Integrator> integrator = static_cast<Integrator *>
		(pluginMgr->createObject(MTS_CLASS(Integrator), integratorProps));
	integrator->configure();

	if (ui->icBox->isChecked()) {
		Properties icProps("irrcache");
		if (m_icNode != NULL)
			m_icNode->putProperties(icProps);
		ref<Integrator> ic = static_cast<Integrator *>
			(pluginMgr->createObject(MTS_CLASS(Integrator), icProps));
		ic->addChild(integrator);
		ic->configure();
		integrator = ic;
	}

	if (ui->aiBox->isChecked()) {
		Properties aiProps("adaptive");
		if (m_aiNode != NULL)
			m_aiNode->putProperties(aiProps);
		ref<Integrator> ai = static_cast<Integrator *>
			(pluginMgr->createObject(MTS_CLASS(Integrator), aiProps));
		ai->addChild(integrator);
		ai->configure();
		integrator = ai;
	}

	QStringList resolution = ui->resolutionBox->currentText().split('x');
	SAssert(resolution.size() == 2);
	Vector2i cropSize(
		std::max(1, resolution[0].toInt()),
		std::max(1, resolution[1].toInt()));

	/* Configure the film */
	Vector2i oldSize = oldFilm->getSize();
	Vector2i oldCropSize = oldFilm->getCropSize();
	Point2i oldCropOffset = oldFilm->getCropOffset();

	Vector2i size(math::roundToInt((oldSize.x * cropSize.x / (Float) oldCropSize.x)),
			      math::roundToInt((oldSize.y * cropSize.y / (Float) oldCropSize.y)));

	Point2i cropOffset(math::roundToInt((oldCropOffset.x * cropSize.x / (Float) oldCropSize.x)),
			           math::roundToInt((oldCropOffset.y * cropSize.y / (Float) oldCropSize.y)));

	filmProps.setInteger("width", size.x, false);
	filmProps.setInteger("height", size.y, false);

	/* g-pt and g-bdpt only work with multifilm. */
	if (getPluginName(ui->integratorBox) == "gbdpt" || getPluginName(ui->integratorBox) == "gpt")
		filmProps.setPluginName("multifilm");
	else
		filmProps.setPluginName("hdrfilm");

	if (size.x != cropSize.x || size.y != cropSize.y || cropOffset.x != 0 || cropOffset.y != 0) {
		filmProps.setInteger("cropWidth", cropSize.x, false);
		filmProps.setInteger("cropHeight", cropSize.y, false);
		filmProps.setInteger("cropOffsetX", cropOffset.x, false);
		filmProps.setInteger("cropOffsetY", cropOffset.y, false);
	} else {
		filmProps.removeProperty("cropWidth");
		filmProps.removeProperty("cropHeight");
		filmProps.removeProperty("cropOffsetX");
		filmProps.removeProperty("cropOffsetY");
	}

	ctx->originalSize = cropSize;

	ref<Film> film = static_cast<Film *> (pluginMgr->createObject(
			MTS_CLASS(Film), filmProps));
	film->addChild(rFilter);
	film->configure();

	if (cropSize.x != ctx->framebuffer->getWidth() ||
		cropSize.y != ctx->framebuffer->getHeight()) {
		ctx->framebuffer = new Bitmap(Bitmap::ERGBA, Bitmap::EFloat32, cropSize);
		ctx->framebuffer->clear();
		ctx->mode = EPreview;
	}

	/* Configure the sensor */
	Properties sensorProps = oldSensor->getProperties();

	if (oldSensor->getClass()->derivesFrom(MTS_CLASS(PerspectiveCamera))) {
		sensorProps.removeProperty("focalLength");
		sensorProps.setString("fovAxis", "y", false);
		sensorProps.setFloat("fov",
			static_cast<const PerspectiveCamera *>(oldSensor.get())->getYFov(), false);
	}

	ref<Sensor> newSensor = static_cast<Sensor *>
		(pluginMgr->createObject(MTS_CLASS(Sensor), sensorProps));
	newSensor->addChild(sampler);
	newSensor->addChild(film);
	newSensor->setMedium(oldSensor->getMedium());
	newSensor->configure();

	/* Update the scene with the newly constructed elements */
	scene->removeSensor(oldSensor);
	scene->addSensor(newSensor);
	scene->setSensor(newSensor);

	scene->setSampler(sampler);
	scene->setIntegrator(integrator);
	scene->configure();

	ctx->scene = scene;
	thread->setFileResolver(oldResolver);
}