VGUErrorCode vguPolygon(VGPath path, const VGfloat * points, VGint count, VGboolean closed) { VGErrorCode error = vgGetError(); //clear the error state if(!points || (((ptrdiff_t)points) & 3) || count <= 0) return VGU_ILLEGAL_ARGUMENT_ERROR; VGubyte segments[1] = {VG_MOVE_TO | VG_ABSOLUTE}; VGfloat data[2]; for(int i=0;i<count;i++) { data[0] = points[i*2+0]; data[1] = points[i*2+1]; append(path, 1, segments, 2, data); segments[0] = VG_LINE_TO | VG_ABSOLUTE; } if(closed) { segments[0] = VG_CLOSE_PATH; append(path, 1, segments, 0, data); } error = vgGetError(); if(error == VG_BAD_HANDLE_ERROR) return VGU_BAD_HANDLE_ERROR; else if(error == VG_PATH_CAPABILITY_ERROR) return VGU_PATH_CAPABILITY_ERROR; return VGU_NO_ERROR; }
/** @SYMTestCaseID GRAPHICS-EGL-0129 @SYMTestPriority 1 @SYMPREQ 39 @SYMREQ See SGL.GT0386.401 document @SYMTestCaseDesc Any attemp to create a VGImage from a bad EGLImage handle has to fail. @SYMTestActions Create a reference Bitmap Create and fully construct an RSgImage object having the same content as the reference bitmap • Set the iUsage bit to ESgUsageBitOpenVgImage Pass the RSgImage object into eglCreateImageKHR() with • The target parameter set to EGL_NATIVE_PIXMAP_KHR • Use the current display and EGL_NO_CONTEXT • Use a NULL attr_list Check that eglCreateImageKHR() does NOT return EGL_NO_IMAGE_KHR. Create a surface and a current context. Destroy the EGLImage but retain the handle value. Try to create a VGImage from this invalid handle. Check that the error VG_ILLEGAL_ARGUMENT_ERROR is raised. Check for memory and handle leaks. @SYMTestExpectedResults vgCreateImageTargetKHR raises a VG_ILLEGAL_ARGUMENT_ERROR error. Check for memory and handle leaks. */ TVerdict CEglTest_EGL_Image_VGImage_From_Invalid_EGLHandle::doTestStepL() { SetTestStepID(_L("GRAPHICS-EGL-0129")); INFO_PRINTF1(_L("CEglTest_VGImage_From_Invalid_EGLHandle::doTestStepL")); TBool ret = CheckForExtensionL(KEGL_RSgimage | KEGL_KHR_image_base | KEGL_KHR_image_pixmap | KVG_KHR_EGL_image); if(!ret) { // The extension is not supported RecordTestResultL(); CloseTMSGraphicsStep(); return TestStepResult(); } // This test is performed for default pixel format PrintUsedPixelConfiguration(); // Create display object GetDisplayL(); CreateEglSessionL(); iEglSess->InitializeL(); iEglSess->OpenSgDriverL(); INFO_PRINTF1(_L("Creating one RSgImage")); TSgImageInfoOpenVgImage imageInfo = TSgImageInfoOpenVgImage(iSourceFormat, KPixmapSize); #ifndef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE imageInfo.iCpuAccess = ESgCpuAccessReadWrite; #endif RSgImage sgImage; CleanupClosePushL(sgImage); ASSERT_EQUALS(sgImage.Create(imageInfo, NULL, NULL), KErrNone); INFO_PRINTF1(_L("Creating one EGLImage from it")); EGLImageKHR imageKHR = iEglSess->eglCreateImageKhrL(iDisplay, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, &sgImage, KEglImageAttribsPreservedTrue); ASSERT_EGL_TRUE(imageKHR != EGL_NO_IMAGE_KHR); //Create a Surface and Link it to a Context bound to OpenVG TUidPixelFormat pixelFormat = EglTestConversion::VgFormatToSgPixelFormat(iSurfaceFormat); TSgImageInfoOpenVgTarget imageInfo2 = TSgImageInfoOpenVgTarget(pixelFormat, KPixmapSize); iEglSess->CreatePixmapSurfaceAndMakeCurrentAndMatchL(imageInfo2, CTestEglSession::EResourceCloseSgImageEarly); INFO_PRINTF1(_L("Destroying the EGLImage but retain the handle value")); ASSERT_EGL_TRUE(iEglSess->DestroyEGLImage(iDisplay, imageKHR)); INFO_PRINTF1(_L("Attemptimg to create a VGImage from an invalid handle")); VGImage vgImage = iEglSess->vgCreateImageTargetKHR((VGeglImageKHR)imageKHR); ASSERT_VG_TRUE(vgImage == VG_INVALID_HANDLE); ASSERT_TRUE(vgGetError()==VG_ILLEGAL_ARGUMENT_ERROR); vgDestroyImage(vgImage); ASSERT_TRUE(vgGetError()==VG_BAD_HANDLE_ERROR); //cleanup CleanupStack::PopAndDestroy(&sgImage); CleanAll(); RecordTestResultL(); CloseTMSGraphicsStep(); return TestStepResult(); }
void render() { vgSetPaint(paint_, VG_FILL_PATH); assert(!vgGetError()); vgDrawPath(path_, VG_FILL_PATH); assert(!vgGetError()); }
void CEglTest_EGL_Image_Multi_Thread_Parallel::doThreadFunctionL(TInt aIdx) { INFO_PRINTF2(_L("CEglTest_EGL_Image_Multi_Thread_Parallel::doThreadFunctionL, Thread %d"),aIdx); GetDisplayL(); CTestEglSession* eglSess = CTestEglSession::NewLC(Logger(), iDisplay, aIdx); eglSess->InitializeL(); eglSess->OpenSgDriverL(); // create a reference bitmap (we give index 7, as there's only 1 image in this test case) TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(KDefaultSourceFormat); CFbsBitmap* bitmap = eglSess->CreateReferenceBitmapL(bitmapMode, KPixmapSize, 7); CleanupStack::PushL(bitmap); // Create an RSgImage INFO_PRINTF2(_L("Thread %d, Creating a RSgImage having the reference bitmap's content"),aIdx); TSgImageInfoOpenVgImage imageInfo = TSgImageInfoOpenVgImage(KDefaultSourceFormat, KPixmapSize); RSgImage rSgImageLocal; CleanupClosePushL(rSgImageLocal); ASSERT_EQUALS(rSgImageLocal.Create(imageInfo,bitmap->DataAddress(),bitmap->DataStride()), KErrNone); INFO_PRINTF2(_L("Thread %d, Creating an EGLImage from the shared RSgImage"),aIdx); EGLImageKHR eglImageLocal = eglSess->eglCreateImageKhrL(iDisplay, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, &rSgImageLocal, KEglImageAttribsPreservedTrue); ASSERT_EGL_TRUE(eglImageLocal != EGL_NO_IMAGE_KHR); CleanupStack::PopAndDestroy(&rSgImageLocal); //transferring ownership of the buffer to the EGLImage CleanupStack::PopAndDestroy(bitmap); INFO_PRINTF2(_L("Thread %d, Creating a Surface and a Context bound to OpenVG"),aIdx); TUidPixelFormat pixelFormat = EglTestConversion::VgFormatToSgPixelFormat(KDefaultSurfaceFormat); TSgImageInfoOpenVgTarget imageInfo2 = TSgImageInfoOpenVgTarget(pixelFormat, KPixmapSize); // Create a pixmap surface matching the native image pixel format eglSess->CreatePixmapSurfaceAndMakeCurrentAndMatchL(imageInfo2,CTestEglSession::EResourceCloseSgImageEarly); INFO_PRINTF2(_L("Thread %d, Creating one VGImage from the EGLImage"),aIdx); VGImage vgImageLocal = eglSess->vgCreateImageTargetKHR((VGeglImageKHR)eglImageLocal); ASSERT_VG_TRUE(vgImageLocal != VG_INVALID_HANDLE); ASSERT_EGL_TRUE(eglSess->DestroyEGLImage(iDisplay, eglImageLocal)); // Copy the source VGImage to the surface vgSetPixels(0, 0, vgImageLocal, 0, 0, KPixmapSize.iWidth, KPixmapSize.iHeight); ASSERT_TRUE(vgGetError()==VG_NO_ERROR); eglWaitClient(); // destroy VGImage vgDestroyImage(vgImageLocal); ASSERT_TRUE(vgGetError()==VG_NO_ERROR); // we can now compare the VgImage to the one we would expect for this particular thread CFbsBitmap* refBitmap = eglSess->CreateReferenceBitmapL(bitmapMode, KPixmapSize, 7); CleanupStack::PushL(refBitmap); eglSess->CheckVgDrawingL(KDefaultSurfaceFormat, refBitmap); CleanupStack::PopAndDestroy(refBitmap); INFO_PRINTF2(_L("Drawing successful, Thread %d"),aIdx); // cleanup eglSess->CloseSgDriver(); CleanupStack::PopAndDestroy(eglSess); }
void SubtitleRenderer::initialize_vg() { // get an EGL display connection display_ = eglGetDisplay(EGL_DEFAULT_DISPLAY); ENFORCE(display_); // initialize the EGL display connection ENFORCE(eglInitialize(display_, NULL, NULL)); // get an appropriate EGL frame buffer configuration static const EGLint attribute_list[] = { EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_NONE }; EGLConfig config{}; EGLint num_config{}; ENFORCE(eglChooseConfig(display_, attribute_list, &config, 1, &num_config)); ENFORCE(num_config); ENFORCE(eglBindAPI(EGL_OPENVG_API)); static EGL_DISPMANX_WINDOW_T nativewindow; nativewindow.element = dispman_element_; nativewindow.width = buffer_width_; nativewindow.height = buffer_height_; surface_ = eglCreateWindowSurface(display_, config, &nativewindow, NULL); ENFORCE(surface_); // create an EGL rendering context context_ = eglCreateContext(display_, config, EGL_NO_CONTEXT, NULL); ENFORCE(context_); auto result = eglMakeCurrent(display_, surface_, surface_, context_); assert(result); vgSeti(VG_FILTER_FORMAT_LINEAR, VG_TRUE); assert(!vgGetError()); vgSeti(VG_IMAGE_QUALITY, VG_IMAGE_QUALITY_NONANTIALIASED); assert(!vgGetError()); auto create_vg_font = [](VGFont& font) { font = vgCreateFont(64); ENFORCE(font); }; create_vg_font(vg_font_); create_vg_font(vg_font_border_); // VGfloat color[4] = { 1.0f, 0.0f, 0.0f, 1.0f }; // vgSetfv(VG_CLEAR_COLOR, 4, color); }
void SubtitleRenderer:: initialize_fonts(const std::string& font_path, float font_size) { ENFORCE(!FT_Init_FreeType(&ft_library_)); ENFORCE2(!FT_New_Face(ft_library_, font_path.c_str(), 0, &ft_face_), "Unable to open font"); ENFORCE(!FT_Set_Pixel_Sizes(ft_face_, 0, font_size*screen_height_)); auto get_bbox = [this](char32_t cp) { auto glyph_index = FT_Get_Char_Index(ft_face_, cp); ENFORCE(!FT_Load_Glyph(ft_face_, glyph_index, FT_LOAD_NO_HINTING)); FT_Glyph glyph; ENFORCE(!FT_Get_Glyph(ft_face_->glyph, &glyph)); SCOPE_EXIT {FT_Done_Glyph(glyph);}; FT_BBox bbox; FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_PIXELS, &bbox); return bbox; }; constexpr float padding_factor = 0.05f; int y_min = get_bbox('g').yMin; int y_max = get_bbox('M').yMax; y_max += -y_min*0.7f; line_height_ = y_max - y_min; const int v_padding = line_height_*padding_factor + 0.5f; line_height_ += v_padding*2; box_offset_ = y_min-v_padding; box_h_padding_ = line_height_/5.0f + 0.5f; constexpr float border_thickness = 0.045f; ENFORCE(!FT_Stroker_New(ft_library_, &ft_stroker_)); FT_Stroker_Set(ft_stroker_, line_height_*border_thickness*64.0f, FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 0); vgSeti(VG_FILTER_FORMAT_LINEAR, VG_TRUE); assert(!vgGetError()); vgSeti(VG_IMAGE_QUALITY, VG_IMAGE_QUALITY_NONANTIALIASED); assert(!vgGetError()); auto create_vg_font = [](VGFont& font) { font = vgCreateFont(128); ENFORCE(font); }; create_vg_font(vg_font_); create_vg_font(vg_font_border_); }
VGUErrorCode vguLine(VGPath path, VGfloat x0, VGfloat y0, VGfloat x1, VGfloat y1) { VGErrorCode error = vgGetError(); //clear the error state static const VGubyte segments[2] = {VG_MOVE_TO | VG_ABSOLUTE, VG_LINE_TO | VG_ABSOLUTE}; const VGfloat data[4] = {x0, y0, x1, y1}; append(path, 2, segments, 4, data); error = vgGetError(); if(error == VG_BAD_HANDLE_ERROR) return VGU_BAD_HANDLE_ERROR; else if(error == VG_PATH_CAPABILITY_ERROR) return VGU_PATH_CAPABILITY_ERROR; return VGU_NO_ERROR; }
void push(int x, int y, int width, int height) { assert(width >= 0); assert(height >= 0); vguRect(path_, x, y, width, height); assert(!vgGetError()); };
static void vg_copy_frame(void *data, const void *frame, unsigned width, unsigned height, unsigned pitch) { vg_t *vg = (vg_t*)data; if (vg->mEglImageBuf) { EGLImageKHR img = 0; bool new_egl = vg->driver->write_egl_image(frame, width, height, pitch, (vg->mTexType == VG_sXRGB_8888), 0, &img); rarch_assert(img != EGL_NO_IMAGE_KHR); if (new_egl) { vgDestroyImage(vg->mImage); vg->mImage = pvgCreateEGLImageTargetKHR((VGeglImageKHR) img); if (!vg->mImage) { RARCH_ERR("[VG:EGLImage] Error creating image: %08x\n", vgGetError()); exit(2); } vg->last_egl_image = img; } } else { vgImageSubData(vg->mImage, frame, pitch, vg->mTexType, 0, 0, width, height); } }
void render(int w, int h) { { float clearColor[4] = {1,1,1,1}; float scale = w / (tigerMaxX - tigerMinX); eglSwapBuffers(egldisplay, eglsurface); //force EGL to recognize resize vgSetfv(VG_CLEAR_COLOR, 4, clearColor); vgClear(0, 0, w, h); vgLoadIdentity(); vgTranslate(w * 0.5f, h * 0.5f); vgRotate(rotateN); vgTranslate(-w * 0.5f, -h * 0.5f); vgScale(scale, scale); vgTranslate(-tigerMinX, -tigerMinY + 0.5f * (h / scale - (tigerMaxY - tigerMinY))); PS_render(tiger); assert(vgGetError() == VG_NO_ERROR); renderWidth = w; renderHeight = h; } }
void VgLeaveIfErrorL() { VGErrorCode ret = vgGetError(); if(ret != VG_NO_ERROR) { User::Leave(ret); } }
FloatPoint Path::pointAtLength(float length, bool& ok) { VGfloat x = 0, y = 0; m_path->makeCompatibleContextCurrent(); vgPointAlongPath(m_path->vgPath(), 0, vgGetParameteri(m_path->vgPath(), VG_PATH_NUM_SEGMENTS), length, &x, &y, 0, 0); ok = (vgGetError() == VG_NO_ERROR); return FloatPoint(x, y); }
// End checks for errors, and renders to the display void End() { int error = vgGetError(); if (error != VG_NO_ERROR) { printf("vgErrorCode = %d\n", error); return; } eglSwapBuffers(state->display, state->surface); assert(eglGetError() == EGL_SUCCESS); }
float Path::normalAngleAtLength(float length, bool& ok) { VGfloat tangentX, tangentY; m_path->makeCompatibleContextCurrent(); vgPointAlongPath(m_path->vgPath(), 0, vgGetParameteri(m_path->vgPath(), VG_PATH_NUM_SEGMENTS), length, 0, 0, &tangentX, &tangentY); ok = (vgGetError() == VG_NO_ERROR); return atan2f(tangentY, tangentX) * 180.0 / piFloat; // convert to degrees }
// End checks for errors, and renders to the display void End() { int vgerr = vgGetError(); if(vgerr != VG_NO_ERROR) { // printf("VG error: %d", (int)vgerr); printf("vgError detected: 0x%08x.\n", vgerr); } //assert(vgGetError() == VG_NO_ERROR); eglSwapBuffers(state->display, state->surface); assert(eglGetError() == EGL_SUCCESS); }
int render(int width, int height) { static DWORD startTick =0; static DWORD frames = 0; VGImage image; char buf[256]; if((startTick == 0)||(frames > 50)) { if(frames > 50) frames = 0; startTick = GetTickCount(); frames++; } else { sprintf(buf, "fps:%2.2f frames/sec \n", (float)(frames++)*1000/(GetTickCount() - startTick)); OutputDebugString(buf); } if(pReadFile == NULL) { pReadFile = fopen("test.rgb","rb"); if(pReadFile) fseek(pReadFile, 0 , SEEK_SET); } if(pReadFile && (feof(pReadFile))) fseek(pReadFile, 0 , SEEK_SET); if(pReadFile) fread(pBuff, sizeof(BYTE),SRC_WIDTH*SRC_HEIGHT*2,pReadFile); image = vgCreateImage( VG_sRGB_565, SRC_WIDTH, SRC_HEIGHT, VG_IMAGE_QUALITY_BETTER ); if(image == NULL) return -1; vgImageSubData( image, pBuff, SRC_WIDTH*2, VG_sRGB_565, 0, 0, SRC_WIDTH, SRC_HEIGHT); vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE); vgLoadIdentity(); vgScale((VGfloat)width/SRC_WIDTH, (VGfloat)height/SRC_HEIGHT); vgTranslate(SRC_WIDTH, SRC_HEIGHT); vgRotate(180.0f); vgDrawImage( image ); vgDestroyImage( image ); if ( vgGetError() == VG_NO_ERROR ) eglSwapBuffers( egldisplay, eglsurface ); return 0; }
VGUErrorCode vguRect(VGPath path, VGfloat x, VGfloat y, VGfloat width, VGfloat height) { VGErrorCode error = vgGetError(); //clear the error state if(width <= 0 || height <= 0) return VGU_ILLEGAL_ARGUMENT_ERROR; static const VGubyte segments[5] = {VG_MOVE_TO | VG_ABSOLUTE, VG_HLINE_TO | VG_ABSOLUTE, VG_VLINE_TO | VG_ABSOLUTE, VG_HLINE_TO | VG_ABSOLUTE, VG_CLOSE_PATH}; const VGfloat data[5] = {x, y, x + width, y + height, x}; append(path, 5, segments, 5, data); error = vgGetError(); if(error == VG_BAD_HANDLE_ERROR) return VGU_BAD_HANDLE_ERROR; else if(error == VG_PATH_CAPABILITY_ERROR) return VGU_PATH_CAPABILITY_ERROR; return VGU_NO_ERROR; }
void SubtitleRenderer:: draw_text(VGFont font, VGFont italic_font, const std::vector<SubtitleRenderer::InternalChar>& text, int x, int y, unsigned int lightness) { VGPaint paint = vgCreatePaint(); assert(paint); vgSetColor(paint, (lightness<<8) | (lightness<<16) | (lightness<<24) | 0xFF); assert(!vgGetError()); vgSetPaint(paint, VG_FILL_PATH); assert(!vgGetError()); vgDestroyPaint(paint); assert(!vgGetError()); vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_MULTIPLY); assert(!vgGetError()); VGfloat pos[] = {static_cast<VGfloat>(x), static_cast<VGfloat>(y)}; vgSetfv(VG_GLYPH_ORIGIN, 2, pos); assert(!vgGetError()); for (auto c = text.begin(); c != text.end(); ++c) { vgDrawGlyph(c->italic ? italic_font : font, c->codepoint, VG_FILL_PATH, VG_FALSE); assert(!vgGetError()); } }
BoxRenderer(unsigned int opacity) { path_ = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1.0, 0.0, 0, 0, VG_PATH_CAPABILITY_ALL); assert(path_); paint_ = vgCreatePaint(); assert(paint_); vgSetColor(paint_, opacity); assert(!vgGetError()); }
VGUErrorCode vguEllipse(VGPath path, VGfloat cx, VGfloat cy, VGfloat width, VGfloat height) { VGErrorCode error = vgGetError(); //clear the error state if(width <= 0 || height <= 0) return VGU_ILLEGAL_ARGUMENT_ERROR; static const VGubyte segments[4] = {VG_MOVE_TO | VG_ABSOLUTE, VG_SCCWARC_TO | VG_ABSOLUTE, VG_SCCWARC_TO | VG_ABSOLUTE, VG_CLOSE_PATH}; const VGfloat data[12] = {cx + width/2, cy, width/2, height/2, 0, cx - width/2, cy, width/2, height/2, 0, cx + width/2, cy}; append(path, 4, segments, 12, data); error = vgGetError(); if(error == VG_BAD_HANDLE_ERROR) return VGU_BAD_HANDLE_ERROR; else if(error == VG_PATH_CAPABILITY_ERROR) return VGU_PATH_CAPABILITY_ERROR; return VGU_NO_ERROR; }
VGUErrorCode vguRoundRect(VGPath path, VGfloat x, VGfloat y, VGfloat width, VGfloat height, VGfloat arcWidth, VGfloat arcHeight) { VGErrorCode error = vgGetError(); //clear the error state if(width <= 0 || height <= 0) return VGU_ILLEGAL_ARGUMENT_ERROR; arcWidth = RI_CLAMP(arcWidth, 0.0f, width); arcHeight = RI_CLAMP(arcHeight, 0.0f, height); static const VGubyte segments[10] = {VG_MOVE_TO | VG_ABSOLUTE, VG_HLINE_TO | VG_ABSOLUTE, VG_SCCWARC_TO | VG_ABSOLUTE, VG_VLINE_TO | VG_ABSOLUTE, VG_SCCWARC_TO | VG_ABSOLUTE, VG_HLINE_TO | VG_ABSOLUTE, VG_SCCWARC_TO | VG_ABSOLUTE, VG_VLINE_TO | VG_ABSOLUTE, VG_SCCWARC_TO | VG_ABSOLUTE, VG_CLOSE_PATH}; const VGfloat data[26] = {x + arcWidth/2, y, x + width - arcWidth/2, arcWidth/2, arcHeight/2, 0, x + width, y + arcHeight/2, y + height - arcHeight/2, arcWidth/2, arcHeight/2, 0, x + width - arcWidth/2, y + height, x + arcWidth/2, arcWidth/2, arcHeight/2, 0, x, y + height - arcHeight/2, y + arcHeight/2, arcWidth/2, arcHeight/2, 0, x + arcWidth/2, y}; append(path, 10, segments, 26, data); error = vgGetError(); if(error == VG_BAD_HANDLE_ERROR) return VGU_BAD_HANDLE_ERROR; else if(error == VG_PATH_CAPABILITY_ERROR) return VGU_PATH_CAPABILITY_ERROR; return VGU_NO_ERROR; }
// SaveEnd dumps the raster before rendering to the display void SaveEnd(const char *filename) { FILE *fp; assert(vgGetError() == VG_NO_ERROR); if (strlen(filename) == 0) { dumpscreen(state->screen_width, state->screen_height, stdout); } else { fp = fopen(filename, "wb"); if (fp != NULL) { dumpscreen(state->screen_width, state->screen_height, fp); fclose(fp); } } eglSwapBuffers(state->display, state->surface); assert(eglGetError() == EGL_SUCCESS); }
int EGLUtilsVG::loadTexture(const char *fn) { char testr[256]; sprintf(testr, ":/%s", fn ); QString filename = QString( testr ); QImage image = QImage( filename ); int w=image.width(); int h=image.height(); qDebug() << filename << "w:" << w << "h:" << h; VGImage texture = vgCreateImage(VG_sARGB_8888, w, h, VG_IMAGE_QUALITY_BETTER); qDebug("vgCreateImage handle %x", texture); if(texture==VG_INVALID_HANDLE) { VGErrorCode err = vgGetError(); qDebug("loadVGImage '%s' error 0x%x", fn, err); } vgImageSubData(texture, (QRgb*)image.bits(), w*4, VG_sARGB_8888, 0, 0, w, h); return texture; }
void PS_render(PS* ps) { int i; assert(ps); vgSeti(VG_BLEND_MODE, VG_BLEND_SRC_OVER); for(i=0;i<ps->m_numPaths;i++) { vgSeti(VG_FILL_RULE, ps->m_paths[i].m_fillRule); vgSetPaint(ps->m_paths[i].m_fillPaint, VG_FILL_PATH); if(ps->m_paths[i].m_paintMode & VG_STROKE_PATH) { vgSetf(VG_STROKE_LINE_WIDTH, ps->m_paths[i].m_strokeWidth); vgSeti(VG_STROKE_CAP_STYLE, ps->m_paths[i].m_capStyle); vgSeti(VG_STROKE_JOIN_STYLE, ps->m_paths[i].m_joinStyle); vgSetf(VG_STROKE_MITER_LIMIT, ps->m_paths[i].m_miterLimit); vgSetPaint(ps->m_paths[i].m_strokePaint, VG_STROKE_PATH); } vgDrawPath(ps->m_paths[i].m_path, ps->m_paths[i].m_paintMode); } assert(vgGetError() == VG_NO_ERROR); }
void SubtitleRenderer::load_glyph(char32_t codepoint) { VGfloat escapement[2]{}; auto load_glyph_internal = [&](FT_Face ft_face, VGFont vg_font, bool border) { try { auto glyph_index = FT_Get_Char_Index(ft_face, codepoint); ENFORCE(!FT_Load_Glyph(ft_face, glyph_index, FT_LOAD_NO_HINTING)); FT_Glyph glyph; ENFORCE(!FT_Get_Glyph(ft_face->glyph, &glyph)); SCOPE_EXIT {FT_Done_Glyph(glyph);}; if (border) ENFORCE(!FT_Glyph_StrokeBorder(&glyph, ft_stroker_, 0, 1)); ENFORCE(!FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, NULL, 1)); FT_BitmapGlyph bit_glyph = (FT_BitmapGlyph) glyph; FT_Bitmap& bitmap = bit_glyph->bitmap; VGImage image{}; VGfloat glyph_origin[2]{}; if (bitmap.width > 0 && bitmap.rows > 0) { constexpr VGfloat blur_stddev = 0.6; const int padding = static_cast<int>(3*blur_stddev + 0.5); const int image_width = bitmap.width + padding*2; const int image_height = bitmap.rows + padding*2; image = vgCreateImage(VG_A_8, image_width, image_height, VG_IMAGE_QUALITY_NONANTIALIASED); assert(image); if (bitmap.pitch > 0) { vgImageSubData(image, bitmap.buffer + bitmap.pitch*(bitmap.rows-1), -bitmap.pitch, VG_A_8, padding, padding, bitmap.width, bitmap.rows); assert(!vgGetError()); } else { vgImageSubData(image, bitmap.buffer, bitmap.pitch, VG_A_8, padding, padding, bitmap.width, bitmap.rows); assert(!vgGetError()); } auto softened_image = vgCreateImage(VG_A_8, image_width, image_height, VG_IMAGE_QUALITY_NONANTIALIASED); assert(image); // Even out hard and soft edges vgGaussianBlur(softened_image, image, blur_stddev, blur_stddev, VG_TILE_FILL); assert(!vgGetError()); vgDestroyImage(image); assert(!vgGetError()); image = softened_image; glyph_origin[0] = static_cast<VGfloat>(padding - bit_glyph->left); glyph_origin[1] = static_cast<VGfloat>(padding + bitmap.rows - bit_glyph->top - 1); } escapement[0] = static_cast<VGfloat>((ft_face->glyph->advance.x + 32) / 64); escapement[1] = 0; vgSetGlyphToImage(vg_font, codepoint, image, glyph_origin, escapement); assert(!vgGetError()); if (image) { vgDestroyImage(image); assert(!vgGetError()); } } catch(...) { escapement[0] = 0; escapement[1] = 0; vgSetGlyphToImage(vg_font, codepoint, VG_INVALID_HANDLE, escapement, escapement); assert(!vgGetError()); } }; load_glyph_internal(ft_face_, vg_font_, false); glyphs_[codepoint].advance = escapement[0]; load_glyph_internal(ft_face_, vg_font_border_, true); }
void CEglTest_EGL_Image_Multi_Thread_DrawAfterTerminate::doThreadFunctionL(TInt aIdx) { INFO_PRINTF2(_L("CEglTest_EGL_Image_Multi_Thread_DrawAfterTerminate::doThreadFunctionL, Thread %d"),aIdx); GetDisplayL(); CTestEglSession* eglSess = CTestEglSession::NewLC(Logger(), iDisplay, aIdx); eglSess->InitializeL(); eglSess->OpenSgDriverL(); TRequestStatus statusThread1; VGImage vgImageLocal = VG_INVALID_HANDLE; EGLint surfaceWidth; EGLint surfaceHeigth; //Thread0 asks to be notified when Thread1 exits //Creates a RSgImage having the reference bitmap as content //Creates a EGLImage from the RSgImage //Creates a surface //Creates a VGImage from the EGLImage if(aIdx == 0) { // Thread0 asks to be notified when Thread1 exits iThreadStatus[1].iThread.Logon(statusThread1); RSgImage rSgImageLocal; CleanupClosePushL(rSgImageLocal); // create a reference bitmap (we give index 9, as there's only 1 image in this test case) TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(KDefaultSourceFormat); CFbsBitmap* bitmap = eglSess->CreateReferenceBitmapL(bitmapMode, KPixmapSize, 9); CleanupStack::PushL(bitmap); // Create an RSgImage INFO_PRINTF2(_L("Thread %d, Creating a RSgImage having the reference bitmap's content"),aIdx); TSgImageInfoOpenVgImage imageInfo = TSgImageInfoOpenVgImage(KDefaultSourceFormat, KPixmapSize); ASSERT_EQUALS(rSgImageLocal.Create(imageInfo,bitmap->DataAddress(),bitmap->DataStride()), KErrNone); CleanupStack::PopAndDestroy(bitmap); INFO_PRINTF2(_L("Thread %d, Creating an EGLImage from the shared RSgImage"),aIdx); EGLImageKHR eglImageLocal = eglSess->eglCreateImageKhrL(iDisplay, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, &rSgImageLocal, KEglImageAttribsPreservedTrue); ASSERT_EGL_TRUE(eglImageLocal != EGL_NO_IMAGE_KHR); CleanupStack::PopAndDestroy(&rSgImageLocal); //transferring ownership of the buffer to the EGLImage INFO_PRINTF2(_L("Thread %d, Creating a Surface and a Context bound to OpenVG"),aIdx); TUidPixelFormat pixelFormat = EglTestConversion::VgFormatToSgPixelFormat(KDefaultSurfaceFormat); TSgImageInfoOpenVgTarget imageInfo2 = TSgImageInfoOpenVgTarget(pixelFormat, KPixmapSize); // Create a pixmap surface matching the native image pixel format eglSess->CreatePixmapSurfaceAndMakeCurrentAndMatchL(imageInfo2,CTestEglSession::EResourceCloseSgImageEarly); //We now store the size of the surface because after eglTerminate is called on the display //it will not be possible to use explicitly all the resources linked to it //i.e. every call to an EGL API who takes a display as an argument will raise a EGL_BAD_DISPLAY error eglQuerySurface(iDisplay, eglSess->Surface(), EGL_WIDTH, &surfaceWidth); eglQuerySurface(iDisplay, eglSess->Surface(), EGL_HEIGHT, &surfaceHeigth); INFO_PRINTF2(_L("Thread %d, Creating one VGImage from the EGLImage"),aIdx); vgImageLocal = eglSess->vgCreateImageTargetKHR((VGeglImageKHR)eglImageLocal); ASSERT_VG_TRUE(vgImageLocal != VG_INVALID_HANDLE); ASSERT_EGL_TRUE(eglSess->DestroyEGLImage(iDisplay, eglImageLocal)); } Rendezvous(aIdx); //Thread1 calls eglTerminate and exit if(aIdx == 1) { INFO_PRINTF2(_L(", Thread %d, Calling eglTerminate and exiting"),aIdx); TerminateDisplayL(); } Rendezvous(aIdx); //Thread0 resumes when Thread1 exits //and it uses the resources that are linked to the just destroyed display if(aIdx == 0) { User::WaitForRequest(statusThread1); // It's still possible to use the current context, surface and VGImage even though the display has been terminated //Copy the source VGImage to the surface vgSetPixels(0, 0, vgImageLocal, 0, 0, KPixmapSize.iWidth, KPixmapSize.iHeight); ASSERT_TRUE(vgGetError()==VG_NO_ERROR); eglWaitClient(); // we can now compare the VgImage to the one we would expect for this particular thread TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(KDefaultSourceFormat); CFbsBitmap* refBitmap = eglSess->CreateReferenceBitmapL(bitmapMode, KPixmapSize, 9); CleanupStack::PushL(refBitmap); eglSess->CheckVgDrawingL(KDefaultSurfaceFormat, refBitmap); CleanupStack::PopAndDestroy(refBitmap); INFO_PRINTF2(_L("Drawing successful, Thread %d"),aIdx); vgDestroyImage(vgImageLocal); ASSERT_TRUE(vgGetError() == VG_NO_ERROR); eglReleaseThread(); } // cleanup eglSess->CloseSgDriver(); CleanupStack::PopAndDestroy(eglSess); }
void clear() { vgClearPath(path_, VG_PATH_CAPABILITY_ALL); assert(!vgGetError()); }
~BoxRenderer() { vgDestroyPath(path_); assert(!vgGetError()); vgDestroyPaint(paint_); assert(!vgGetError()); }
/** Render text. * * FIXME: Not at all optimal - re-renders each time. * FIXME: Not UTF-8 aware * FIXME: better caching */ VCOS_STATUS_T gx_priv_render_text( GX_DISPLAY_T *disp, GRAPHICS_RESOURCE_HANDLE res, uint32_t x, uint32_t y, uint32_t width, uint32_t height, uint32_t fg_colour, uint32_t bg_colour, const char *text, uint32_t text_length, uint32_t text_size ) { VGfloat vg_colour[4]; VGFT_FONT_T *font; VGPaint fg; GX_CLIENT_STATE_T save; VCOS_STATUS_T status = VCOS_SUCCESS; int clip = 1; vcos_demand(inited); // has gx_font_init() been called? gx_priv_save(&save, res); if (width == GRAPHICS_RESOURCE_WIDTH && height == GRAPHICS_RESOURCE_HEIGHT) { clip = 0; } width = (width == GRAPHICS_RESOURCE_WIDTH) ? res->width : width; height = (height == GRAPHICS_RESOURCE_HEIGHT) ? res->height : height; font = find_font(text, text_size); if (!font) { status = VCOS_ENOMEM; goto finish; } // setup the clipping rectangle if (clip) { VGint coords[] = {x,y,width,height}; vgSeti(VG_SCISSORING, VG_TRUE); vgSetiv(VG_SCISSOR_RECTS, 4, coords); } // setup the background colour if needed if (bg_colour != GRAPHICS_TRANSPARENT_COLOUR) { int err; VGfloat rendered_w, rendered_h; VGfloat vg_bg_colour[4]; // setup the background colour... gx_priv_colour_to_paint(bg_colour, vg_bg_colour); vgSetfv(VG_CLEAR_COLOR, 4, vg_bg_colour); // fill in a rectangle... vgft_get_text_extents(font, text, text_length, (VGfloat)x, (VGfloat)y, &rendered_w, &rendered_h); if ( ( 0 < (VGint)rendered_w ) && ( 0 < (VGint)rendered_h ) ) { vgClear(x, y, (VGint)rendered_w, (VGint)rendered_h); err = vgGetError(); if (err) { GX_LOG("Error %d clearing bg text %d %d %g %g", err, x, y, rendered_w, rendered_h); vcos_assert(0); } // if } // if } // if // setup the foreground colour fg = vgCreatePaint(); if (!fg) { status = VCOS_ENOMEM; goto finish; } // draw the foreground text vgSetParameteri(fg, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR); gx_priv_colour_to_paint(fg_colour, vg_colour); vgSetParameterfv(fg, VG_PAINT_COLOR, 4, vg_colour); vgSetPaint(fg, VG_FILL_PATH); vgft_font_draw(font, (VGfloat)x, (VGfloat)y, text, text_length, VG_FILL_PATH); vgDestroyPaint(fg); vcos_assert(vgGetError() == 0); vgSeti(VG_SCISSORING, VG_FALSE); finish: gx_priv_restore(&save); return status; }
void* QVGPixmapData::toNativeType(NativeType type) { if (type == QPixmapData::SgImage) { #if defined(QT_SYMBIAN_SUPPORTS_SGIMAGE) && !defined(QT_NO_EGL) toVGImage(); if (!isValid() || vgImage == VG_INVALID_HANDLE) return 0; TInt err = 0; RSgDriver driver; err = driver.Open(); if (err != KErrNone) return 0; TSgImageInfo sgInfo; sgInfo.iPixelFormat = EUidPixelFormatARGB_8888_PRE; sgInfo.iSizeInPixels.SetSize(w, h); sgInfo.iUsage = ESgUsageBitOpenVgImage | ESgUsageBitOpenVgSurface; QScopedPointer<RSgImage> sgImage(new RSgImage()); err = sgImage->Create(sgInfo, NULL, NULL); if (err != KErrNone) { driver.Close(); return 0; } const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE}; EGLImageKHR eglImage = QEgl::eglCreateImageKHR(QEgl::display(), EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, (EGLClientBuffer)sgImage.data(), (EGLint*)KEglImageAttribs); if (!eglImage || eglGetError() != EGL_SUCCESS) { sgImage->Close(); driver.Close(); return 0; } VGImage dstVgImage = QVG::vgCreateEGLImageTargetKHR(eglImage); if (!dstVgImage || vgGetError() != VG_NO_ERROR) { QEgl::eglDestroyImageKHR(QEgl::display(), eglImage); sgImage->Close(); driver.Close(); return 0; } vgCopyImage(dstVgImage, 0, 0, vgImage, 0, 0, w, h, VG_FALSE); if (vgGetError() != VG_NO_ERROR) { sgImage->Close(); sgImage.reset(); } // release stuff vgDestroyImage(dstVgImage); QEgl::eglDestroyImageKHR(QEgl::display(), eglImage); driver.Close(); return reinterpret_cast<void*>(sgImage.take()); #endif } else if (type == QPixmapData::FbsBitmap && isValid()) { ensureReadback(true); if (source.isNull()) { source = QVolatileImage(w, h, sourceFormat()); } // Just duplicate the bitmap handle, no data copying happens. return source.duplicateNativeImage(); } return 0; }