OP_STATUS VEGAFilter::applyShader(VEGABackingStore_FBO* destStore, const VEGAFilterRegion& in_region, unsigned int frame, unsigned int borderWidth, VEGAFilterEdgeMode edgeMode) { VEGA3dDevice* device = g_vegaGlobals.vega3dDevice; OP_ASSERT(device); VEGAFilterRegion region = in_region; // This could end up being modified OP_STATUS err; VEGA3dTexture* tmpSource = NULL; VEGA3dTexture* srctex = NULL; VEGA3dRenderTarget* destRT = destStore->GetWriteRenderTarget(frame); if (sourceRT->getType() == VEGA3dRenderTarget::VEGA3D_RT_TEXTURE) srctex = static_cast<VEGA3dFramebufferObject*>(sourceRT)->getAttachedColorTexture(); if (sourceRT == destRT || !srctex) { tmpSource = device->getTempTexture(region.width, region.height); if (!tmpSource) return OpStatus::ERR; VEGARefCount::IncRef(tmpSource); device->setRenderTarget(sourceRT); device->copyToTexture(tmpSource, VEGA3dTexture::CUBE_SIDE_NONE, 0, 0, 0, region.sx, region.sy, region.width, region.height); region.sx = region.sy = 0; srctex = tmpSource; } if (!srctex) return OpStatus::ERR; if (borderWidth) { if (isSubRegion(region, srctex) || edgeMode == VEGAFILTEREDGE_NONE || (edgeMode == VEGAFILTEREDGE_WRAP && NEEDS_POW2_WORKAROUND(srctex->getWidth(), srctex->getHeight()))) { VEGA3dFramebufferObject* fbo = NULL; err = device->createFramebuffer(&fbo); if (OpStatus::IsError(err)) { VEGARefCount::DecRef(tmpSource); return err; } VEGA3dTexture* tmp2Source = NULL; err = createClampTexture(device, srctex, region.sx, region.sy, region.width, region.height, borderWidth, edgeMode, fbo, &tmp2Source); VEGARefCount::DecRef(fbo); VEGARefCount::DecRef(tmpSource); RETURN_IF_ERROR(err); tmpSource = tmp2Source; srctex = tmp2Source; } else if (edgeMode == VEGAFILTEREDGE_WRAP) { srctex->setWrapMode(VEGA3dTexture::WRAP_REPEAT, VEGA3dTexture::WRAP_REPEAT); } else srctex->setWrapMode(VEGA3dTexture::WRAP_CLAMP_EDGE, VEGA3dTexture::WRAP_CLAMP_EDGE); } else srctex->setWrapMode(VEGA3dTexture::WRAP_CLAMP_EDGE, VEGA3dTexture::WRAP_CLAMP_EDGE); VEGA3dShaderProgram* shader = NULL; err = getShader(device, &shader, srctex); if (OpStatus::IsSuccess(err)) { // FIXME: Set color? VEGA3dBuffer* vbuf = NULL; VEGA3dVertexLayout* vlayout = NULL; unsigned int vbufStartIndex = 0; err = setupVertexBuffer(device, &vbuf, &vlayout, &vbufStartIndex, srctex, shader, region); if (OpStatus::IsSuccess(err)) { device->setRenderTarget(destRT); device->setRenderState(device->getDefault2dNoBlendNoScissorRenderState()); shader->setOrthogonalProjection(); err = device->drawPrimitives(VEGA3dDevice::PRIMITIVE_TRIANGLE_STRIP, vlayout, vbufStartIndex, 4); } putShader(device, shader); VEGARefCount::DecRef(vlayout); VEGARefCount::DecRef(vbuf); } VEGARefCount::DecRef(tmpSource); return err; }
// Set for rendering void LLVertexBuffer::setBuffer(U32 data_mask) { LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); //set up pointers if the data mask is different ... BOOL setup = (sLastMask != data_mask); if (useVBOs()) { if (mGLBuffer && (mGLBuffer != sGLRenderBuffer || !sVBOActive)) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer); sVBOActive = TRUE; setup = TRUE; // ... or the bound buffer changed } if (mGLIndices && (mGLIndices != sGLRenderIndices || !sIBOActive)) { glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mGLIndices); sIBOActive = TRUE; } unmapBuffer(); } else { if (mGLBuffer) { if (sEnableVBOs && sVBOActive) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); sVBOActive = FALSE; setup = TRUE; // ... or a VBO is deactivated } if (sGLRenderBuffer != mGLBuffer) { setup = TRUE; // ... or a client memory pointer changed } } if (sEnableVBOs && mGLIndices && sIBOActive) { glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); sIBOActive = FALSE; } } if (mGLIndices) { sGLRenderIndices = mGLIndices; } if (mGLBuffer) { sGLRenderBuffer = mGLBuffer; if (data_mask && setup) { if (!sRenderActive) { llwarns << "Vertex buffer set for rendering outside of render frame." << llendl; } setupVertexBuffer(data_mask); // subclass specific setup (virtual function) sLastMask = data_mask; } } }
// Set for rendering void LLVertexBuffer::setBuffer(U32 data_mask, S32 type) { LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); //set up pointers if the data mask is different ... BOOL setup = (sLastMask != data_mask); if (useVBOs()) { if (mGLBuffer && (mGLBuffer != sGLRenderBuffer || !sVBOActive)) { /*if (sMapped) { llerrs << "VBO bound while another VBO mapped!" << llendl; }*/ stop_glerror(); glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer); stop_glerror(); sBindCount++; sVBOActive = TRUE; setup = TRUE; // ... or the bound buffer changed } if (mGLIndices && (mGLIndices != sGLRenderIndices || !sIBOActive)) { /*if (sMapped) { llerrs << "VBO bound while another VBO mapped!" << llendl; }*/ stop_glerror(); glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mGLIndices); stop_glerror(); sBindCount++; sIBOActive = TRUE; } BOOL error = FALSE; if (gDebugGL) { GLint buff; glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff); if ((GLuint)buff != mGLBuffer) { llerrs << "Invalid GL vertex buffer bound: " << buff << llendl; } if (mGLIndices) { glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff); if ((GLuint)buff != mGLIndices) { llerrs << "Invalid GL index buffer bound: " << buff << llendl; } } } if (mResized) { if (gDebugGL) { GLint buff; glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff); if ((GLuint)buff != mGLBuffer) { llerrs << "Invalid GL vertex buffer bound: " << buff << llendl; } if (mGLIndices != 0) { glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff); if ((GLuint)buff != mGLIndices) { llerrs << "Invalid GL index buffer bound: " << buff << llendl; } } } if (mGLBuffer) { stop_glerror(); glBufferDataARB(GL_ARRAY_BUFFER_ARB, getSize(), NULL, mUsage); stop_glerror(); } if (mGLIndices) { stop_glerror(); glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, getIndicesSize(), NULL, mUsage); stop_glerror(); } mEmpty = TRUE; mResized = FALSE; if (data_mask != 0) { llerrs << "Buffer set for rendering before being filled after resize." << llendl; } } if (error) { llerrs << "LLVertexBuffer::mapBuffer failed" << llendl; } unmapBuffer(type); } else { if (mGLBuffer) { if (sVBOActive) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); sBindCount++; sVBOActive = FALSE; setup = TRUE; // ... or a VBO is deactivated } if (sGLRenderBuffer != mGLBuffer) { setup = TRUE; // ... or a client memory pointer changed } } if (mGLIndices && sIBOActive) { /*if (sMapped) { llerrs << "VBO unbound while potentially mapped!" << llendl; }*/ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); sBindCount++; sIBOActive = FALSE; } } setupClientArrays(data_mask); if (mGLIndices) { sGLRenderIndices = mGLIndices; } if (mGLBuffer) { sGLRenderBuffer = mGLBuffer; if (data_mask && setup) { setupVertexBuffer(data_mask); // subclass specific setup (virtual function) sSetCount++; } } }