void MLAcceleratedImageFilter::addInputImage(GLuint id, const QByteArray &name)
{
	if (_inTexInfos.size() >= MaxInImageCount)
	{
		qWarning() << Q_FUNC_INFO << ": too many input images";
		return;
	}
	
	_inTexInfos << TextureInfo(id, name);
}
示例#2
0
TextureAtlas::TextureIndex TextureAtlas::AddTexture(const std::string& fname)
{
	TextureList::iterator it = m_textureList.find(fname);

	if (it != m_textureList.end())
		return it->second.texIdx;

	TextureIndex id = m_currentTextureIndex++;
	m_textureList.insert(std::make_pair(fname, TextureInfo((ILuint)-1, id)));
	return id;
}
示例#3
0
QSharedPointer<Texture> TextureManager::loadTexture(const QString &fileName, bool useDefaultTexture)
{
	// сначала ищем текстуру в кэше
	TextureCache::iterator it = mTextureCache.find(fileName);
	if (it != mTextureCache.end())
	{
		QSharedPointer<Texture> texture = it->mTexture.toStrongRef();
		if (!texture.isNull())
			return texture;
		mTextureCache.erase(it);
	}

	// не нашли в кэше - загружаем текстуру из файла
	QSharedPointer<Texture> texture;
	QString path = Project::getSingleton().getRootDirectory() + fileName;
	mPrimaryGLWidget->makeCurrent();
	if (Utils::fileExists(path) && (texture = QSharedPointer<Texture>(new Texture(path)))->isLoaded())
	{
		// добавляем файл на слежение
		if (!mWatcher->files().contains(path))
			mWatcher->addPath(path);

		// добавляем текстуру в кэш
		mTextureCache.insert(fileName, TextureInfo(texture));
	}
	else if (useDefaultTexture)
	{
		// возвращаем текстуру по умолчанию
		texture = QSharedPointer<Texture>(new Texture());
		mTextureCache.insert(fileName, TextureInfo(texture));
	}
	else
	{
		// очищаем указатель на текстуру в случае ошибки
		texture.clear();
	}

	return texture;
}
示例#4
0
TextureSource::TextureSource(IrrlichtDevice *device):
		m_device(device)
{
	assert(m_device);

	m_main_thread = get_current_thread_id();

	// Add a NULL TextureInfo as the first index, named ""
	m_textureinfo_cache.push_back(TextureInfo(""));
	m_name_to_id[""] = 0;

	// Cache some settings
	// Note: Since this is only done once, the game must be restarted
	// for these settings to take effect
	m_setting_trilinear_filter = g_settings->getBool("trilinear_filter");
	m_setting_bilinear_filter = g_settings->getBool("bilinear_filter");
	m_setting_anisotropic_filter = g_settings->getBool("anisotropic_filter");
}
示例#5
0
TextureInfo loadTexture(const std::string& filename, bool premultiply) {
	int width, height, comp;
	auto data = std::unique_ptr<unsigned char[], void(*)(void*)>(
		stbi_load((data_path + filename).c_str(), &width, &height, &comp, 4), &stbi_image_free);
	if (data == nullptr)
		return TextureInfo();

	if (premultiply) {
		unsigned int size = width * height;

		for (unsigned int i = 0; i < size; ++i) {
			unsigned char alpha = data[i*4 + 3];
			for (unsigned int j = 0; j < 3; ++j) {
				data[i*4 + j] = data[i*4 + j] * alpha / 255;
			}
		}
	}

	return loadTexture(width, height, data.get());
}
示例#6
0
void DrawingBuffer::beginDestruction()
{
    ASSERT(!m_destructionInProgress);
    m_destructionInProgress = true;

    clearPlatformLayer();

    while (!m_recycledMailboxQueue.isEmpty())
        deleteMailbox(m_recycledMailboxQueue.takeLast());

    if (m_multisampleFBO)
        m_gl->DeleteFramebuffers(1, &m_multisampleFBO);

    if (m_fbo)
        m_gl->DeleteFramebuffers(1, &m_fbo);

    if (m_multisampleRenderbuffer)
        m_gl->DeleteRenderbuffers(1, &m_multisampleRenderbuffer);

    if (m_depthStencilBuffer)
        m_gl->DeleteRenderbuffers(1, &m_depthStencilBuffer);

    if (m_colorBuffer.textureId) {
        deleteChromiumImageForTexture(&m_colorBuffer);
        m_gl->DeleteTextures(1, &m_colorBuffer.textureId);
    }

    setSize(IntSize());

    m_colorBuffer = TextureInfo();
    m_frontColorBuffer = FrontBufferInfo();
    m_multisampleRenderbuffer = 0;
    m_depthStencilBuffer = 0;
    m_multisampleFBO = 0;
    m_fbo = 0;

    if (m_layer)
        GraphicsLayer::unregisterContentsLayer(m_layer->layer());
}
示例#7
0
			void GLFramebuffer2D::Init()
			{
				TE_OGL(glGenFramebuffers(1, &m_handle_fb));
				TE_OGL(glGenRenderbuffers(1, &m_handle_db));

				auto params = TextureParameters(TextureFormat::RGBA, TextureFilterMode::LINEAR, TextureWrapMode::CLAMP, TextureDataType::UNSIGNED_BYTE, m_samples);
				m_texture.push_back(TextureInfo());
				m_texture[0].texture = new GLTexture2D(m_width, m_height, nullptr, params);
				m_texture[0].attachment = TE_ATTACHMENT_0;

				TE_OGL(glBindRenderbuffer(GL_RENDERBUFFER, m_handle_db));
				if (m_samples > 1)
				{
					TE_OGL(glRenderbufferStorageMultisample(GL_RENDERBUFFER, m_samples, GL_DEPTH_COMPONENT24, m_width, m_height));
				}
				else
				{
					TE_OGL(glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, m_width, m_height));
				}

				TE_OGL(glBindFramebuffer(GL_FRAMEBUFFER, m_handle_fb));

				TE_OGL(glFramebufferTexture2D(GL_FRAMEBUFFER, AttachmentToGL(m_texture[0].attachment), m_samples > 1 ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D, m_texture[0].texture->getHandle(), 0));

				TE_OGL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_handle_db));

				if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
				{
					std::cout << "Failed to create framebuffer properly!" << std::endl;
				}

				uint32 attachments[] = { GL_COLOR_ATTACHMENT0 };
				TE_OGL(glDrawBuffers(1, attachments));

				TE_OGL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
				TE_OGL(glBindRenderbuffer(GL_RENDERBUFFER, 0));
			}
bool
CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation& aEdit,
                                                     EditReplyVector& replyv)
{
  switch (aEdit.type()) {
    case CompositableOperation::TOpCreatedTexture: {
      MOZ_LAYERS_LOG(("[ParentSide] Created texture"));
      const OpCreatedTexture& op = aEdit.get_OpCreatedTexture();
      CompositableParent* compositableParent =
        static_cast<CompositableParent*>(op.compositableParent());
      CompositableHost* compositable = compositableParent->GetCompositableHost();

      compositable->EnsureDeprecatedTextureHost(op.textureId(), op.descriptor(),
                                      compositableParent->GetCompositableManager(),
                                      op.textureInfo());

      break;
    }
    case CompositableOperation::TOpCreatedIncrementalTexture: {
      MOZ_LAYERS_LOG(("[ParentSide] Created texture"));
      const OpCreatedIncrementalTexture& op = aEdit.get_OpCreatedIncrementalTexture();

      CompositableParent* compositableParent =
        static_cast<CompositableParent*>(op.compositableParent());
      CompositableHost* compositable = compositableParent->GetCompositableHost();

      compositable->EnsureDeprecatedTextureHostIncremental(compositableParent->GetCompositableManager(),
                                                 op.textureInfo(),
                                                 op.bufferRect());
      break;
    }
    case CompositableOperation::TOpDestroyThebesBuffer: {
      MOZ_LAYERS_LOG(("[ParentSide] Created double buffer"));
      const OpDestroyThebesBuffer& op = aEdit.get_OpDestroyThebesBuffer();
      CompositableParent* compositableParent = static_cast<CompositableParent*>(op.compositableParent());
      CompositableHost* compositableHost = compositableParent->GetCompositableHost();
      if (compositableHost->GetType() != BUFFER_CONTENT &&
          compositableHost->GetType() != BUFFER_CONTENT_DIRECT)
      {
        return false;
      }
      DeprecatedContentHostBase* content = static_cast<DeprecatedContentHostBase*>(compositableHost);
      content->DestroyTextures();

      break;
    }
    case CompositableOperation::TOpPaintTexture: {
      MOZ_LAYERS_LOG(("[ParentSide] Paint Texture X"));
      const OpPaintTexture& op = aEdit.get_OpPaintTexture();

      CompositableParent* compositableParent =
        static_cast<CompositableParent*>(op.compositableParent());
      CompositableHost* compositable =
        compositableParent->GetCompositableHost();

      Layer* layer = compositable ? compositable->GetLayer() : nullptr;
      LayerComposite* shadowLayer = layer ? layer->AsLayerComposite() : nullptr;
      if (shadowLayer) {
        Compositor* compositor = static_cast<LayerManagerComposite*>(layer->Manager())->GetCompositor();
        compositable->SetCompositor(compositor);
        compositable->SetLayer(layer);
      } else {
        // if we reach this branch, it most likely means that async textures
        // are coming in before we had time to attach the compositable to a
        // layer. Don't panic, it is okay in this case. it should not be
        // happening continuously, though.
      }

      if (layer) {
        RenderTraceInvalidateStart(layer, "FF00FF", layer->GetVisibleRegion().GetBounds());
      }

      if (compositable) {
        const SurfaceDescriptor& descriptor = op.image();
        compositable->EnsureDeprecatedTextureHost(op.textureId(),
                                        descriptor,
                                        compositableParent->GetCompositableManager(),
                                        TextureInfo());
        MOZ_ASSERT(compositable->GetDeprecatedTextureHost());

        SurfaceDescriptor newBack;
        bool shouldRecomposite = compositable->Update(descriptor, &newBack);
        if (IsSurfaceDescriptorValid(newBack)) {
          replyv.push_back(OpTextureSwap(compositableParent, nullptr,
                                         op.textureId(), newBack));
        }

        if (IsAsync() && shouldRecomposite) {
          ScheduleComposition(op);
        }
      }

      if (layer) {
        RenderTraceInvalidateEnd(layer, "FF00FF");
      }

      // return texure data to client if necessary
      ReturnTextureDataIfNecessary(compositable, replyv, op.compositableParent());
      break;
    }
    case CompositableOperation::TOpPaintTextureRegion: {
      MOZ_LAYERS_LOG(("[ParentSide] Paint ThebesLayer"));

      const OpPaintTextureRegion& op = aEdit.get_OpPaintTextureRegion();
      CompositableParent* compositableParent = static_cast<CompositableParent*>(op.compositableParent());
      CompositableHost* compositable =
        compositableParent->GetCompositableHost();
      Layer* layer = compositable->GetLayer();
      if (!layer || layer->GetType() != Layer::TYPE_THEBES) {
        return false;
      }
      ThebesLayerComposite* thebes = static_cast<ThebesLayerComposite*>(layer);

      const ThebesBufferData& bufferData = op.bufferData();

      RenderTraceInvalidateStart(thebes, "FF00FF", op.updatedRegion().GetBounds());

      nsIntRegion frontUpdatedRegion;
      if (!compositable->UpdateThebes(bufferData,
                                      op.updatedRegion(),
                                      thebes->GetValidRegion(),
                                      &frontUpdatedRegion))
      {
        return false;
      }
      replyv.push_back(
        OpContentBufferSwap(compositableParent, nullptr, frontUpdatedRegion));

      RenderTraceInvalidateEnd(thebes, "FF00FF");
      // return texure data to client if necessary
      ReturnTextureDataIfNecessary(compositable, replyv, op.compositableParent());
      break;
    }
    case CompositableOperation::TOpPaintTextureIncremental: {
      MOZ_LAYERS_LOG(("[ParentSide] Paint ThebesLayer"));

      const OpPaintTextureIncremental& op = aEdit.get_OpPaintTextureIncremental();

      CompositableParent* compositableParent = static_cast<CompositableParent*>(op.compositableParent());
      CompositableHost* compositable =
        compositableParent->GetCompositableHost();

      SurfaceDescriptor desc = op.image();

      compositable->UpdateIncremental(op.textureId(),
                                      desc,
                                      op.updatedRegion(),
                                      op.bufferRect(),
                                      op.bufferRotation());
      break;
    }
    case CompositableOperation::TOpUpdatePictureRect: {
      const OpUpdatePictureRect& op = aEdit.get_OpUpdatePictureRect();
      CompositableHost* compositable
       = static_cast<CompositableParent*>(op.compositableParent())->GetCompositableHost();
      MOZ_ASSERT(compositable);
      compositable->SetPictureRect(op.picture());
      break;
    }
    case CompositableOperation::TOpUseTiledLayerBuffer: {
      MOZ_LAYERS_LOG(("[ParentSide] Paint TiledLayerBuffer"));
      const OpUseTiledLayerBuffer& op = aEdit.get_OpUseTiledLayerBuffer();
      CompositableParent* compositableParent = static_cast<CompositableParent*>(op.compositableParent());
      CompositableHost* compositable =
        compositableParent->GetCompositableHost();

      TiledLayerComposer* tileComposer = compositable->AsTiledLayerComposer();
      NS_ASSERTION(tileComposer, "compositable is not a tile composer");

      const SurfaceDescriptorTiles& tileDesc = op.tileLayerDescriptor();
      tileComposer->UseTiledLayerBuffer(this, tileDesc);
      break;
    }
    case CompositableOperation::TOpRemoveTexture: {
      const OpRemoveTexture& op = aEdit.get_OpRemoveTexture();
      CompositableHost* compositable = AsCompositable(op);
      RefPtr<TextureHost> tex = TextureHost::AsTextureHost(op.textureParent());

      MOZ_ASSERT(tex.get());
      compositable->RemoveTextureHost(tex);
      // return texure data to client if necessary
      ReturnTextureDataIfNecessary(compositable, replyv, op.compositableParent());
      break;
    }
    case CompositableOperation::TOpUseTexture: {
      const OpUseTexture& op = aEdit.get_OpUseTexture();
      CompositableHost* compositable = AsCompositable(op);
      RefPtr<TextureHost> tex = TextureHost::AsTextureHost(op.textureParent());

      MOZ_ASSERT(tex.get());
      compositable->UseTextureHost(tex);

      if (IsAsync()) {
        ScheduleComposition(op);
        // Async layer updates don't trigger invalidation, manually tell the layer
        // that its content have changed.
        if (compositable->GetLayer()) {
          compositable->GetLayer()->SetInvalidRectToVisibleRegion();
        }
      }
      // return texure data to client if necessary
      ReturnTextureDataIfNecessary(compositable, replyv, op.compositableParent());
      break;
    }
    case CompositableOperation::TOpUseComponentAlphaTextures: {
      const OpUseComponentAlphaTextures& op = aEdit.get_OpUseComponentAlphaTextures();
      CompositableHost* compositable = AsCompositable(op);
      RefPtr<TextureHost> texOnBlack = TextureHost::AsTextureHost(op.textureOnBlackParent());
      RefPtr<TextureHost> texOnWhite = TextureHost::AsTextureHost(op.textureOnWhiteParent());

      MOZ_ASSERT(texOnBlack && texOnWhite);
      compositable->UseComponentAlphaTextures(texOnBlack, texOnWhite);

      if (IsAsync()) {
        ScheduleComposition(op);
      }
      // return texure data to client if necessary
      ReturnTextureDataIfNecessary(compositable, replyv, op.compositableParent());
      break;
    }
    case CompositableOperation::TOpUpdateTexture: {
      const OpUpdateTexture& op = aEdit.get_OpUpdateTexture();
      RefPtr<TextureHost> texture = TextureHost::AsTextureHost(op.textureParent());
      MOZ_ASSERT(texture);

      texture->Updated(op.region().type() == MaybeRegion::TnsIntRegion
                       ? &op.region().get_nsIntRegion()
                       : nullptr); // no region means invalidate the entire surface
      break;
    }

    default: {
      MOZ_ASSERT(false, "bad type");
    }
  }

  return true;
}
示例#9
0
			void GLFramebuffer2D::addAttachment(Attachment attach) {
				m_texture.push_back(TextureInfo());
				m_texture[m_texture.size() - 1].attachment = attach;

				resizeTexture(m_width, m_height);
			}
示例#10
0
TextureInfo ImageClientSingle::GetTextureInfo() const
{
  return TextureInfo(COMPOSITABLE_IMAGE);
}
void TextureManager::CheckUpdate()
{
    // The images or their lenses have changed.
    // Find what size we should have the textures.
    // Note that one image changing does affect the rest, if an image suddenly
    // takes up more space, the others should take up less.
    unsigned int num_images = m_pano->getNrOfImages();
    if (num_images == 0)
    {
        textures.clear();
        return;
    }
    // if we are doing photometric correction, and someone changed the output
    // exposure, all of our images are at the wrong exposure.
    if (photometric_correct && view_state->RequireRecalculatePhotometric())
    {
        textures.clear();
    }
    HuginBase::PanoramaOptions *dest_img = view_state->GetOptions();
    // Recalculuate the ideal image density if required
    // TODO tidy up once it works.
    DEBUG_INFO("Updating texture sizes.");
    // find the total of fields of view of the images, in degrees squared
    // we assume each image has the same density across all it's pixels
    double total_fov = 0.0;
    for (unsigned int image_index = 0; image_index < num_images; image_index++)
    {
        HuginBase::SrcPanoImage *src = view_state->GetSrcImage(image_index);
        double aspect = double(src->getSize().height())
                                               / double(src->getSize().width());
        total_fov += src->getHFOV() * aspect;
    };
    // now find the ideal density
    texel_density = double(GetMaxTotalTexels()) / total_fov;

    // now recalculate the best image sizes
    // The actual texture size is the biggest one possible withouth scaling the
    // image up in any direction. We only specifiy mipmap levels we can fit in
    // a given amount of texture memory, while respecting the image's FOV.
    int texels_used = 0;
    double ideal_texels_used = 0.0;
    for (unsigned int image_index = 0; image_index < num_images; image_index++)
    {    
        // find this texture
        // if it has not been created before, it will be created now.
        std::map<TextureKey, TextureInfo>::iterator it;
        HuginBase::SrcPanoImage *img_p = view_state->GetSrcImage(image_index);
        TextureKey key(img_p, &photometric_correct);
        it = textures.find(key);
        TextureInfo *texinfo;
        /* This section would allow us to reuse textures generated when we want
         * to change the size. It is not used as it causes segmentation faults
         * under Ubuntu 8.04's "ati" graphics driver.
         */
      #if 0
        if (it == textures.end())
        {
            // We haven't seen this image before.
            // Find a size for it and make its texture.
            // store the power that 2 is raised to, not the actual size
            unsigned int max_tex_width_p = int(log2(img_p->getSize().width())),
                        max_tex_height_p = int(log2(img_p->getSize().height()));
            // check this is hardware supported.
            {
              unsigned int biggest = GetMaxTextureSizePower();
              if (biggest < max_tex_width_p) max_tex_width_p = biggest;
              if (biggest < max_tex_height_p) max_tex_height_p = biggest;
            }
            std::cout << "Texture size for image " << image_index << " is "
                      << (1 << max_tex_width_p) << " by "
                      << (1 << max_tex_height_p) << "\n";
            // create a new texinfo and store the texture details.
            std::cout << "About to create new TextureInfo for "
                      << img_p->getFilename()
                      << ".\n";
            std::pair<std::map<TextureKey, TextureInfo>::iterator, bool> ins;
            ins = textures.insert(std::pair<TextureKey, TextureInfo>
                                 (TextureKey(img_p, &photometric_correct),
                // the key is used to identify the image with (or without)
                // photometric correction parameters.
                              TextureInfo(max_tex_width_p, max_tex_height_p)
                            ));
            texinfo = &((ins.first)->second);
        }
        else
        {
            texinfo = &(it->second);
        }
                
        // find the highest mipmap we want to use.
        double hfov = img_p->getHFOV(),
               aspect = double (texinfo->height) / double (texinfo->width),
               ideal_texels = texel_density * hfov * aspect,
               // we would like a mipmap with this size:
               ideal_tex_width = sqrt(ideal_texels / aspect),
               ideal_tex_height = aspect * ideal_tex_width;
        // Ideally this mipmap would bring us up to this many texels
        ideal_texels_used += ideal_texels;
        std::cout << "Ideal mip size: " << ideal_tex_width << " by "
                  << ideal_tex_height << "\n";
        // Find the smallest mipmap level that is at least this size.
        int max_mip_level = (texinfo->width_p > texinfo->height_p)
                            ? texinfo->width_p : texinfo->height_p;
        int mip_level = max_mip_level - ceil((ideal_tex_width > ideal_tex_height)
                        ? log2(ideal_tex_width) : log2(ideal_tex_height));
        // move to the next mipmap level if we are over budget.
        if ((texels_used + (1 << (texinfo->width_p + texinfo->height_p
                                  - mip_level * 2)))
            > ideal_texels_used)
        {
            // scale down
            mip_level ++;
        }
        // don't allow any mipmaps smaller than the 1 by 1 pixel one.
        if (mip_level > max_mip_level) mip_level = max_mip_level;
        // don't allow any mipmaps with a negative level of detail (scales up)
        if (mip_level < 0) mip_level = 0;
        // find the size of this level
        int mip_width_p = texinfo->width_p - mip_level,
            mip_height_p = texinfo->height_p - mip_level;
        // check if we have scaled down to a single line, and make sure we
        // limit the line's width to 1 pixel.
        if (mip_width_p < 0) mip_width_p = 0;
        if (mip_height_p < 0) mip_height_p = 0;
        
        // now count these texels as used- we are ignoring the smaller mip
        //   levels, they add 1/3 on to the size.
        texels_used += 1 << (mip_width_p + mip_height_p);
        std::cout << "biggest mipmap of image " << image_index << " is "
                  << (1 << mip_width_p) << " by " << (1 << mip_height_p)
                  << " (level " << mip_level <<").\n";
        std::cout << "Ideal texels used " << int(ideal_texels_used)
                  << ", actually used " << texels_used << ".\n\n";
        if (texinfo->min_lod != mip_level)
        {
            // maximum level required changed.
            if (texinfo->min_lod > mip_level)
            {
                // generate more levels
                texinfo->DefineLevels(mip_level,
                                      (texinfo->min_lod > max_mip_level) ?
                                      max_mip_level : texinfo->min_lod - 1,
                                      photometric_correct, dest_img,
                                      view_state->GetSrcImage(image_index));
            }
            texinfo->SetMaxLevel(mip_level);
            texinfo->min_lod = mip_level;
        }
    }
    #endif
    /* Instead of the above section, replace the whole texture when appropriate:
        */
        // Find a size for it
        double hfov = img_p->getHFOV(),
           aspect = double (img_p->getSize().height())
                                            / double (img_p->getSize().width()),
           ideal_texels = texel_density * hfov * aspect,
           // we would like a texture this size:
           ideal_tex_width = sqrt(ideal_texels / aspect),
           ideal_tex_height = aspect * ideal_tex_width;
        // shrink if bigger than the original, avoids scaling up excessively.
        if (ideal_tex_width > img_p->getSize().width())
                ideal_tex_width = img_p->getSize().width();
        if (ideal_tex_height > img_p->getSize().height())
                ideal_tex_height = img_p->getSize().height();
        // we will need to round up/down to a power of two
        // round up first, then shrink if over budget.
        // store the power that 2 is raised to, not the actual size
        unsigned int tex_width_p = int(log2(ideal_tex_width)) + 1,
                    tex_height_p = int(log2(ideal_tex_height)) + 1;
        // check this is hardware supported.
        {
          unsigned int biggest = GetMaxTextureSizePower();
          if (biggest < tex_width_p) tex_width_p = biggest;
          if (biggest < tex_height_p) tex_height_p = biggest;
        }
        
        // check if this is over budget.
        ideal_texels_used += ideal_texels; 
        // while the texture is over budget, shrink it
        while (  (texels_used + (1 << (tex_width_p + tex_height_p)))
            > ideal_texels_used)
        {
            // smaller aspect means the texture is wider.
            if ((double) (1 << tex_height_p) / (double) (1 << tex_width_p)
               < aspect)
            {
                tex_width_p--;
            } else {
                tex_height_p--;
            }
        }
        // we have a nice size
        texels_used += 1 << (tex_width_p + tex_height_p);
        if (   it == textures.end()
            || (it->second).width_p != tex_width_p
            || (it->second).height_p != tex_height_p)
        {
            // Either: 1. We haven't seen this image before
            //     or: 2. Our texture for this is image is the wrong size
            // ...therefore we make a new one the right size:
            //
            // remove duplicate key if exists
            TextureKey checkKey (img_p, &photometric_correct);
            if (textures.find(checkKey) != textures.end()) {
                // Already exists in map, remove it first before adding a new one
                textures.erase(checkKey);
            }

            std::pair<std::map<TextureKey, TextureInfo>::iterator, bool> ins;
            ins = textures.insert(std::pair<TextureKey, TextureInfo>
                                 (TextureKey(img_p, &photometric_correct),
                // the key is used to identify the image with (or without)
                // photometric correction parameters.
                              TextureInfo(view_state, tex_width_p, tex_height_p)
                            ));
           // create and upload the texture image
           texinfo = &((ins.first)->second);
           texinfo->DefineLevels(0, // minimum mip level
                                 // maximum mip level
                        tex_width_p > tex_height_p ? tex_width_p : tex_height_p,
                                photometric_correct,
                                *dest_img,
                                *view_state->GetSrcImage(image_index));
           texinfo->DefineMaskTexture(*view_state->GetSrcImage(image_index));
        }
        else
        {
            if(view_state->RequireRecalculateMasks(image_index))
            {
                //mask for this image has changed, also update only mask
                (*it).second.UpdateMask(*view_state->GetSrcImage(image_index));
            };
        }
    }
bool
CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation& aEdit,
                                                     EditReplyVector& replyv)
{
  switch (aEdit.type()) {
    case CompositableOperation::TOpCreatedTexture: {
      MOZ_LAYERS_LOG(("[ParentSide] Created texture"));
      const OpCreatedTexture& op = aEdit.get_OpCreatedTexture();
      CompositableParent* compositableParent =
        static_cast<CompositableParent*>(op.compositableParent());
      CompositableHost* compositable = compositableParent->GetCompositableHost();

      compositable->EnsureTextureHost(op.textureId(), op.descriptor(),
                                      compositableParent->GetCompositableManager(),
                                      op.textureInfo());

      break;
    }
    case CompositableOperation::TOpDestroyThebesBuffer: {
      MOZ_LAYERS_LOG(("[ParentSide] Created double buffer"));
      const OpDestroyThebesBuffer& op = aEdit.get_OpDestroyThebesBuffer();
      CompositableParent* compositableParent = static_cast<CompositableParent*>(op.compositableParent());
      ContentHostBase* content = static_cast<ContentHostBase*>(compositableParent->GetCompositableHost());
      content->DestroyTextures();

      break;
    }
    case CompositableOperation::TOpPaintTexture: {
      MOZ_LAYERS_LOG(("[ParentSide] Paint Texture X"));
      const OpPaintTexture& op = aEdit.get_OpPaintTexture();

      CompositableParent* compositableParent =
        static_cast<CompositableParent*>(op.compositableParent());
      CompositableHost* compositable =
        compositableParent->GetCompositableHost();

      Layer* layer = compositable ? compositable->GetLayer() : nullptr;
      LayerComposite* shadowLayer = layer ? layer->AsLayerComposite() : nullptr;
      if (shadowLayer) {
        Compositor* compositor = static_cast<LayerManagerComposite*>(layer->Manager())->GetCompositor();
        compositable->SetCompositor(compositor);
        compositable->SetLayer(layer);
      } else {
        // if we reach this branch, it most likely means that async textures
        // are coming in before we had time to attach the conmpositable to a
        // layer. Don't panic, it is okay in this case. it should not be
        // happening continuously, though.
      }

      if (layer) {
        RenderTraceInvalidateStart(layer, "FF00FF", layer->GetVisibleRegion().GetBounds());
      }

      if (compositable) {
        const SurfaceDescriptor& descriptor = op.image();
        compositable->EnsureTextureHost(op.textureId(),
                                        descriptor,
                                        compositableParent->GetCompositableManager(),
                                        TextureInfo());
        MOZ_ASSERT(compositable->GetTextureHost());

        SurfaceDescriptor newBack;
        bool shouldRecomposite = compositable->Update(descriptor, &newBack);
        if (IsSurfaceDescriptorValid(newBack)) {
          replyv.push_back(OpTextureSwap(compositableParent, nullptr,
                                         op.textureId(), newBack));
        }

        if (shouldRecomposite && compositableParent->GetCompositorID()) {
          CompositorParent* cp
            = CompositorParent::GetCompositor(compositableParent->GetCompositorID());
          if (cp) {
            cp->ScheduleComposition();
          }
        }
      }

      if (layer) {
        RenderTraceInvalidateEnd(layer, "FF00FF");
      }

      break;
    }
    case CompositableOperation::TOpPaintTextureRegion: {
      MOZ_LAYERS_LOG(("[ParentSide] Paint ThebesLayer"));

      const OpPaintTextureRegion& op = aEdit.get_OpPaintTextureRegion();
      CompositableParent* compositableParent = static_cast<CompositableParent*>(op.compositableParent());
      CompositableHost* compositable =
        compositableParent->GetCompositableHost();
      ThebesLayerComposite* thebes =
        static_cast<ThebesLayerComposite*>(compositable->GetLayer());

      const ThebesBufferData& bufferData = op.bufferData();

      RenderTraceInvalidateStart(thebes, "FF00FF", op.updatedRegion().GetBounds());

      nsIntRegion frontUpdatedRegion;
      compositable->UpdateThebes(bufferData,
                                 op.updatedRegion(),
                                 thebes->GetValidRegion(),
                                 &frontUpdatedRegion);
      replyv.push_back(
        OpContentBufferSwap(compositableParent, nullptr, frontUpdatedRegion));

      RenderTraceInvalidateEnd(thebes, "FF00FF");
      break;
    }
    case CompositableOperation::TOpUpdatePictureRect: {
      const OpUpdatePictureRect& op = aEdit.get_OpUpdatePictureRect();
      CompositableHost* compositable
       = static_cast<CompositableParent*>(op.compositableParent())->GetCompositableHost();
      MOZ_ASSERT(compositable);
      compositable->SetPictureRect(op.picture());
      break;
    }
    case CompositableOperation::TOpPaintTiledLayerBuffer: {
      MOZ_LAYERS_LOG(("[ParentSide] Paint TiledLayerBuffer"));
      const OpPaintTiledLayerBuffer& op = aEdit.get_OpPaintTiledLayerBuffer();
      CompositableParent* compositableParent = static_cast<CompositableParent*>(op.compositableParent());
      CompositableHost* compositable =
        compositableParent->GetCompositableHost();

      TiledLayerComposer* tileComposer = compositable->AsTiledLayerComposer();
      NS_ASSERTION(tileComposer, "compositable is not a tile composer");

      BasicTiledLayerBuffer* p = reinterpret_cast<BasicTiledLayerBuffer*>(op.tiledLayerBuffer());
      tileComposer->PaintedTiledLayerBuffer(p);
      break;
    }
    default: {
      MOZ_ASSERT(false, "bad type");
    }
  }

  return true;
}
示例#13
0
void nuiGLPainter::UploadTexture(nuiTexture* pTexture)
{
  nuiSurface* pSurface = pTexture->GetSurface();
  
  float Width = pTexture->GetUnscaledWidth();
  float Height = pTexture->GetUnscaledHeight();
  GLenum target = GetTextureTarget(pTexture->IsPowerOfTwo());
  bool changedctx = false;

  std::map<nuiTexture*, TextureInfo>::iterator it = mTextures.find(pTexture);
  if (it == mTextures.end())
    it = mTextures.insert(mTextures.begin(), std::pair<nuiTexture*, TextureInfo>(pTexture, TextureInfo()));
  NGL_ASSERT(it != mTextures.end());
  
  TextureInfo& info(it->second);

  nuiCheckForGLErrors();
  
  if (!pTexture->IsPowerOfTwo())
  {
    switch (GetRectangleTextureSupport())
    {
      case 0:
        Width = pTexture->GetWidthPOT();
        Height = pTexture->GetHeightPOT();
        break;
      case 1:
      case 2:
        break;
    }
  }
  
  //NGL_OUT(_T("Apply Target: 0x%x\n"), target);
  nglImage* pImage = pTexture->GetImage();

  {
    bool firstload = false;
    bool reload = info.mReload;
    if (!pSurface && !(pImage && pImage->GetPixelSize()))
      return;

    uint i;
    if (info.mTexture == (GLuint)-1)
    { // Generate a texture
//      if (mpSharedContext)
//      {
//        mpSharedContext->MakeCurrent();
//        nuiCheckForGLErrors();
//        changedctx = true;
//      }
      
      glGenTextures(1, &info.mTexture);
      //NGL_OUT(_T("nuiGLPainter::UploadTexture 0x%x : '%ls' / %d\n"), pTexture, pTexture->GetSource().GetChars(), info.mTexture);
      nuiCheckForGLErrors();
      firstload = true;
      reload = true;
    }

    glBindTexture(target, info.mTexture);
    nuiCheckForGLErrors();
    
    if (reload)
    {
      int type = 8;
      GLint pixelformat = 0;
      GLint internalPixelformat = 0;
      GLbyte* pBuffer = NULL;
      bool allocated = false;

      if (pImage)
      {
        type = pImage->GetBitDepth();
        pixelformat = pImage->GetPixelFormat();
        internalPixelformat = pImage->GetPixelFormat();
        pBuffer = (GLbyte*)pImage->GetBuffer();
        
        if (!GetRectangleTextureSupport())
        {
          nuiCheckForGLErrors();
          if (!pTexture->IsPowerOfTwo())
          {        
            pBuffer = (GLbyte*)malloc( (uint)(Width * Height * pImage->GetPixelSize()));
            if (!pBuffer) 
              return;
            allocated = true;
            memset(pBuffer,0, (uint)(Width*Height * pImage->GetPixelSize()));
            
            for (i=0; i < pImage->GetHeight(); i++)
            {
              
              memcpy
              (
               pBuffer + (uint)(Width * i * pImage->GetPixelSize()), 
               pImage->GetBuffer() + pImage->GetBytesPerLine()*i, 
               pImage->GetBytesPerLine()
               );
            }
          }
        }
        glPixelStorei(GL_UNPACK_ALIGNMENT,1);
        nuiCheckForGLErrors();

        switch (type)
        {
          case 16:
          case 15:
            type = GL_UNSIGNED_SHORT_5_5_5_1;
            break;
          case 8:
          case 24:
          case 32:
            type = GL_UNSIGNED_BYTE;
            break;
        }

#if !defined(_OPENGL_ES_) && defined(_MACOSX_)
        glTexParameteri(target, GL_TEXTURE_STORAGE_HINT_APPLE, GL_STORAGE_CACHED_APPLE);
        glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
#endif
      }
      else
      {
        NGL_ASSERT(pSurface);
#if !defined(_OPENGL_ES_) && defined(_MACOSX_)
        internalPixelformat = pSurface->GetPixelFormat();
        if (internalPixelformat == GL_RGBA)
        {
          internalPixelformat = GL_RGBA;
          pixelformat = GL_BGRA;
          type = GL_UNSIGNED_INT_8_8_8_8_REV;
        }
        else if (internalPixelformat == GL_RGB)
        {
          internalPixelformat = GL_RGB;
          pixelformat = GL_BGR;
          type = GL_UNSIGNED_BYTE;
        }
        else
        {
          pixelformat = pSurface->GetPixelFormat();
          type = GL_UNSIGNED_BYTE;
        }
        glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
#else
        internalPixelformat = pSurface->GetPixelFormat();
        pixelformat = pSurface->GetPixelFormat();
        type = GL_UNSIGNED_BYTE;
#endif
      }


#ifndef _MACOSX_
      if (!firstload)
      {
        glTexSubImage2D
        (  
         target,
         0,
         0,0,
         (int)Width,
         (int)Height,
         pixelformat,
         type,
         pBuffer
         );
        nuiCheckForGLErrors();
        pTexture->ResetForceReload();
      }
      else
#endif
      {
#ifndef _OPENGL_ES_
        if (pTexture->GetAutoMipMap())
        {
#ifdef _MACOSX_
          glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
          nuiCheckForGLErrors();
#endif
          glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, (int)log2(Width));
          nuiCheckForGLErrors();
          gluBuild2DMipmaps(target, internalPixelformat, (int)Width, (int)Height, pixelformat, type, pBuffer);          
          nuiCheckForGLErrors();
        }
        else
#endif
        {
          glTexImage2D(target, 0, internalPixelformat, (int)Width, (int)Height, 0, pixelformat, type, pBuffer);
        }
        nuiCheckForGLErrors();
      }

      info.mReload = false;

      if (allocated)
        free(pBuffer);
//#FIXME
//      if (!pTexture->IsBufferRetained()) { 
//        pTexture->ReleaseBuffer();
//      }

      glTexParameteri(target, GL_TEXTURE_MIN_FILTER, pTexture->GetMinFilter());
      nuiCheckForGLErrors();
      glTexParameteri(target, GL_TEXTURE_MAG_FILTER, pTexture->GetMagFilter());
      nuiCheckForGLErrors();
      glTexParameteri(target, GL_TEXTURE_WRAP_S, pTexture->GetWrapS());
      nuiCheckForGLErrors();
      glTexParameteri(target, GL_TEXTURE_WRAP_T, pTexture->GetWrapT());
      nuiCheckForGLErrors();
      
    }
  }

  if (pTexture->GetPixelFormat() == eImagePixelAlpha)
  {
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
    
    glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
    glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
    
    glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
    glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE);
    
    glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PRIMARY_COLOR);
    glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_PRIMARY_COLOR);
    
    glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_ALPHA);
    glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
    
    glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
    glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
    
  }
  else
  {
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, pTexture->GetEnvMode());
  }
  
  
  
  nuiCheckForGLErrors();

  if (changedctx)
  {
    mpContext->BeginSession();
    nuiCheckForGLErrors();
    glBindTexture(target, info.mTexture);
    nuiCheckForGLErrors();
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, pTexture->GetEnvMode());
    nuiCheckForGLErrors();
  }
  
  glMatrixMode(GL_TEXTURE);
  nuiCheckForGLErrors();
  glLoadIdentity();
  nuiCheckForGLErrors();
  
  uint32 rectangle = GetRectangleTextureSupport();
  nuiCheckForGLErrors();

  double rx = 1;
  double ry = 1;
  if (rectangle != 1)
  {
    rx = pTexture->GetUnscaledWidth() / Width;
    ry = pTexture->GetUnscaledHeight() / Height;
#ifndef _OPENGL_ES_
    if (target == GL_TEXTURE_RECTANGLE_ARB)
    {
      rx *= pTexture->GetUnscaledWidth();
      ry *= pTexture->GetUnscaledHeight();
    }
#endif
  }

  if (pSurface)
  {
    glTranslatef(0, ry, 0);
    ry = -ry;    
  }
  
#ifndef _OPENGL_ES_
  glScaled(rx, ry, 1);
#else
  glScalef((float)rx, (float)ry, 1);
#endif
  nuiCheckForGLErrors();
  
  glMatrixMode(GL_MODELVIEW);
  nuiCheckForGLErrors();
}