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