| 1543 | } |
| 1544 | |
| 1545 | ImagePtr |
| 1546 | EffectInstance::convertRAMImageToOpenGLTexture(const ImagePtr& image) |
| 1547 | { |
| 1548 | assert(image->getStorageMode() != eStorageModeGLTex); |
| 1549 | |
| 1550 | boost::shared_ptr<ImageParams> params( new ImageParams( *image->getParams() ) ); |
| 1551 | CacheEntryStorageInfo& info = params->getStorageInfo(); |
| 1552 | info.mode = eStorageModeGLTex; |
| 1553 | info.textureTarget = GL_TEXTURE_2D; |
| 1554 | |
| 1555 | RectI bounds = image->getBounds(); |
| 1556 | OSGLContextPtr context = getThreadLocalOpenGLContext(); |
| 1557 | assert(context); |
| 1558 | if (!context) { |
| 1559 | throw std::runtime_error("No OpenGL context attached"); |
| 1560 | } |
| 1561 | |
| 1562 | GLuint pboID = context->getPBOId(); |
| 1563 | assert(pboID != 0); |
| 1564 | glEnable(GL_TEXTURE_2D); |
| 1565 | // bind PBO to update texture source |
| 1566 | glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pboID); |
| 1567 | |
| 1568 | std::size_t dataSize = bounds.area() * 4 * info.dataTypeSize; |
| 1569 | |
| 1570 | // Note that glMapBufferARB() causes sync issue. |
| 1571 | // If GPU is working with this buffer, glMapBufferARB() will wait(stall) |
| 1572 | // until GPU to finish its job. To avoid waiting (idle), you can call |
| 1573 | // first glBufferDataARB() with NULL pointer before glMapBufferARB(). |
| 1574 | // If you do that, the previous data in PBO will be discarded and |
| 1575 | // glMapBufferARB() returns a new allocated pointer immediately |
| 1576 | // even if GPU is still working with the previous data. |
| 1577 | glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, dataSize, 0, GL_DYNAMIC_DRAW_ARB); |
| 1578 | |
| 1579 | bool useTmpImage = image->getComponentsCount() != 4; |
| 1580 | ImagePtr tmpImg; |
| 1581 | if (useTmpImage) { |
| 1582 | tmpImg.reset( new Image( ImagePlaneDesc::getRGBAComponents(), image->getRoD(), bounds, 0, image->getPixelAspectRatio(), image->getBitDepth(), image->getPremultiplication(), image->getFieldingOrder(), false, eStorageModeRAM) ); |
| 1583 | tmpImg->setKey(image->getKey()); |
| 1584 | if (tmpImg->getComponents() == image->getComponents()) { |
| 1585 | tmpImg->pasteFrom(*image, bounds); |
| 1586 | } else { |
| 1587 | image->convertToFormat(bounds, eViewerColorSpaceLinear, eViewerColorSpaceLinear, -1, false, false, tmpImg.get()); |
| 1588 | } |
| 1589 | } |
| 1590 | |
| 1591 | Image::ReadAccess racc( tmpImg ? tmpImg.get() : image.get() ); |
| 1592 | const unsigned char* srcdata = racc.pixelAt(bounds.x1, bounds.y1); |
| 1593 | assert(srcdata); |
| 1594 | |
| 1595 | GLvoid* gpuData = glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB); |
| 1596 | if (gpuData) { |
| 1597 | // update data directly on the mapped buffer |
| 1598 | memcpy(gpuData, srcdata, dataSize); |
| 1599 | GLboolean result = glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB); // release the mapped buffer |
| 1600 | assert(result == GL_TRUE); |
| 1601 | Q_UNUSED(result); |
| 1602 | } |
nothing calls this directly
no test coverage detected