经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » Android » 查看文章
MTK Recovery 模式横屏修改(适用于6.0 + 8.1)
来源:cnblogs  作者:cczheng  时间:2019/9/17 9:43:08  对本文有异议

在这里插入图片描述

修改前

在这里插入图片描述

修改后

6.0 Recovery 模式横屏修改方法

修改相关文件
bootable\recovery\minui\Android.mk
bootable\recovery\minui\mt_graphic_rotate.cpp
bootable\recovery\minui\mt_graphic_rotate.h
bootable\recovery\minui\graphics_fbdev.cpp
bootable\recovery\minui\minui.h

1、在 Android.mk 中增加 mt_graphic_rotate.cpp 编译项

  1. LOCAL_SRC_FILES := events.cpp graphics.cpp graphics_adf.cpp graphics_drm.cpp graphics_fbdev.cpp resources.cpp
  2. #cczheng add
  3. LOCAL_SRC_FILES += mt_graphic_rotate.cpp

2、对比修改 mt_graphic_rotate.cpp,没有则直接复制以下类

  1. /*
  2. * Copyright (C) 2014 MediaTek Inc.
  3. * Modification based on code covered by the mentioned copyright
  4. * and/or permission notice(s).
  5. */
  6. #include <stdbool.h>
  7. #include <stdlib.h>
  8. #include <unistd.h>
  9. #include <inttypes.h>
  10. #include <fcntl.h>
  11. #include <stdio.h>
  12. #include <sys/cdefs.h>
  13. #include <sys/ioctl.h>
  14. #include <sys/mman.h>
  15. #include <sys/types.h>
  16. #include <linux/fb.h>
  17. #include <linux/kd.h>
  18. #include "minui.h"
  19. #include "graphics.h"
  20. GRSurface __gr_canvas;
  21. GRSurface* gr_canvas = NULL;
  22. int rotate_index=-1;
  23. static void print_surface_info(GRSurface *s, const char *name)
  24. {
  25. printf("[graphics] %s > Height:%d, Width:%d, PixelBytes:%d, RowBytes:%d, Size:%d, Data: 0x%08" PRIxPTR "\n",
  26. name, s->height, s->width, s->pixel_bytes, s->row_bytes, s->height* s->row_bytes, (uintptr_t) s->data);
  27. }
  28. // Read configuration from MTK_LCM_PHYSICAL_ROTATION
  29. #ifndef MTK_LCM_PHYSICAL_ROTATION
  30. #define MTK_LCM_PHYSICAL_ROTATION "undefined"
  31. #endif
  32. static int rotate_config(GRSurface *gr_draw)
  33. {
  34. if (rotate_index<0)
  35. {
  36. if (gr_draw->pixel_bytes != 4) rotate_index=0; // support 4 bytes pixel only
  37. else if (0 == strncmp(MTK_LCM_PHYSICAL_ROTATION, "90", 2)) rotate_index=1;
  38. else if (0 == strncmp(MTK_LCM_PHYSICAL_ROTATION, "180", 3)) rotate_index=2;
  39. else if (0 == strncmp(MTK_LCM_PHYSICAL_ROTATION, "270", 3)) rotate_index=3;
  40. else rotate_index=0;
  41. printf("[graphics] rotate_config %d %s\n", rotate_index, MTK_LCM_PHYSICAL_ROTATION);
  42. }
  43. return rotate_index;
  44. }
  45. #define swap(x, y, type) {type z; z=x; x=y; y=z;}
  46. // Allocate and setup the canvas object
  47. void rotate_canvas_init(GRSurface *gr_draw)
  48. {
  49. gr_canvas = &__gr_canvas;
  50. memcpy(gr_canvas, gr_draw, sizeof(GRSurface));
  51. // Swap canvas' height and width, if the rotate angle is 90" or 270"
  52. if (rotate_config(gr_draw)%2) {
  53. swap(gr_canvas->width, gr_canvas->height, int);
  54. gr_canvas->row_bytes = gr_canvas->width * gr_canvas->pixel_bytes;
  55. }
  56. gr_canvas->data = (unsigned char*) malloc(gr_canvas->height * gr_canvas->row_bytes);
  57. if (gr_canvas->data == NULL) {
  58. printf("[graphics] rotate_canvas_init() malloc gr_canvas->data failed\n");
  59. gr_canvas = NULL;
  60. return;
  61. }
  62. memset(gr_canvas->data, 0, gr_canvas->height * gr_canvas->row_bytes);
  63. print_surface_info(gr_draw, "gr_draw");
  64. print_surface_info(gr_canvas, "gr_canvas");
  65. }
  66. // Cleanup the canvas
  67. void rotate_canvas_exit(void)
  68. {
  69. if (gr_canvas) {
  70. if (gr_canvas->data)
  71. free(gr_canvas->data);
  72. free(gr_canvas);
  73. }
  74. gr_canvas=NULL;
  75. }
  76. // Return the canvas object
  77. GRSurface *rotate_canvas_get(GRSurface *gr_draw)
  78. {
  79. // Initialize the canvas, if it was not exist.
  80. if (gr_canvas==NULL)
  81. rotate_canvas_init(gr_draw);
  82. return gr_canvas;
  83. }
  84. // Surface Rotate Routines
  85. static void rotate_surface_0(GRSurface *dst, GRSurface *src)
  86. {
  87. memcpy(dst->data, src->data, src->height*src->row_bytes);
  88. }
  89. static void rotate_surface_270(GRSurface *dst, GRSurface *src)
  90. {
  91. int v, w, h;
  92. unsigned int *src_pixel;
  93. unsigned int *dst_pixel;
  94. for (h=0, v=src->width-1; h<dst->height; h++, v--) {
  95. for (w=0; w<dst->width; w++) {
  96. dst_pixel = (unsigned int *)(dst->data + dst->row_bytes*h);
  97. src_pixel = (unsigned int *)(src->data + src->row_bytes*w);
  98. *(dst_pixel+w)=*(src_pixel+v);
  99. }
  100. }
  101. }
  102. static void rotate_surface_180(GRSurface *dst, GRSurface *src)
  103. {
  104. int v, w, k, h;
  105. unsigned int *src_pixel;
  106. unsigned int *dst_pixel;
  107. for (h=0, k=src->height-1; h<dst->height && k>=0 ; h++, k--) {
  108. dst_pixel = (unsigned int *)(dst->data + dst->row_bytes*h);
  109. src_pixel = (unsigned int *)(src->data + src->row_bytes*k);
  110. for (w=0, v=src->width-1; w<dst->width && v>=0; w++, v--) {
  111. *(dst_pixel+w)=*(src_pixel+v);
  112. }
  113. }
  114. }
  115. static void rotate_surface_90(GRSurface *dst, GRSurface *src)
  116. {
  117. int w, k, h;
  118. unsigned int *src_pixel;
  119. unsigned int *dst_pixel;
  120. for (h=0; h<dst->height; h++) {
  121. for (w=0, k=src->height-1; w<dst->width; w++, k--) {
  122. dst_pixel = (unsigned int *)(dst->data + dst->row_bytes*h);
  123. src_pixel = (unsigned int *)(src->data + src->row_bytes*k);
  124. *(dst_pixel+w)=*(src_pixel+h);
  125. }
  126. }
  127. }
  128. typedef void (*rotate_surface_t) (GRSurface *, GRSurface *);
  129. rotate_surface_t rotate_func[4]=
  130. {
  131. rotate_surface_0,
  132. rotate_surface_90,
  133. rotate_surface_180,
  134. rotate_surface_270
  135. };
  136. // rotate and copy src* surface to dst surface
  137. void rotate_surface(GRSurface *dst, GRSurface *src)
  138. {
  139. rotate_surface_t rotate;
  140. rotate=rotate_func[rotate_config(dst)];
  141. rotate(dst, src);
  142. }

3、对比修改 mt_graphic_rotate.h,没有则直接复制以下类

  1. /*
  2. * Copyright (C) 2014 MediaTek Inc.
  3. * Modification based on code covered by the mentioned copyright
  4. * and/or permission notice(s).
  5. */
  6. #ifndef MT_GRAPHICS_ROTATE_H_
  7. #define MT_GRAPHICS_ROTATE_H_
  8. #include "minui.h"
  9. void rotate_canvas_exit(void);
  10. void rotate_canvas_init(GRSurface *gr_draw);
  11. void rotate_surface(GRSurface *dst, GRSurface *src);
  12. GRSurface *rotate_canvas_get(GRSurface *gr_draw);
  13. #endif

4、对比修改 graphics_fbdev.cpp,没有则直接复制以下类

  1. /*
  2. * Copyright (C) 2014 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include <stdbool.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <unistd.h>
  20. #include <fcntl.h>
  21. #include <stdio.h>
  22. #include <sys/cdefs.h>
  23. #include <sys/ioctl.h>
  24. #include <sys/mman.h>
  25. #include <sys/types.h>
  26. #include <linux/fb.h>
  27. #include <linux/kd.h>
  28. #include "minui.h"
  29. #include "graphics.h"
  30. #include "mt_graphic_rotate.h"
  31. static GRSurface* fbdev_init(minui_backend*);
  32. static GRSurface* fbdev_flip(minui_backend*);
  33. static void fbdev_blank(minui_backend*, bool);
  34. static void fbdev_exit(minui_backend*);
  35. static GRSurface gr_framebuffer[2];
  36. static bool double_buffered;
  37. static GRSurface* gr_draw = NULL;
  38. static int displayed_buffer;
  39. static fb_var_screeninfo vi;
  40. static int fb_fd = -1;
  41. static minui_backend my_backend = {
  42. .init = fbdev_init,
  43. .flip = fbdev_flip,
  44. .blank = fbdev_blank,
  45. .exit = fbdev_exit,
  46. };
  47. minui_backend* open_fbdev() {
  48. return &my_backend;
  49. }
  50. static void fbdev_blank(minui_backend* backend __unused, bool blank)
  51. {
  52. int ret;
  53. ret = ioctl(fb_fd, FBIOBLANK, blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK);
  54. if (ret < 0)
  55. perror("ioctl(): blank");
  56. }
  57. static void set_displayed_framebuffer(unsigned n)
  58. {
  59. if (n > 1 || !double_buffered) return;
  60. vi.yres_virtual = gr_framebuffer[0].height * 2;
  61. vi.yoffset = n * gr_framebuffer[0].height;
  62. vi.bits_per_pixel = gr_framebuffer[0].pixel_bytes * 8;
  63. if (ioctl(fb_fd, FBIOPUT_VSCREENINFO, &vi) < 0) {
  64. perror("active fb swap failed");
  65. }
  66. displayed_buffer = n;
  67. }
  68. static GRSurface* fbdev_init(minui_backend* backend) {
  69. int fd = open("/dev/graphics/fb0", O_RDWR);
  70. if (fd == -1) {
  71. perror("cannot open fb0");
  72. return NULL;
  73. }
  74. fb_fix_screeninfo fi;
  75. if (ioctl(fd, FBIOGET_FSCREENINFO, &fi) < 0) {
  76. perror("failed to get fb0 info");
  77. close(fd);
  78. return NULL;
  79. }
  80. if (ioctl(fd, FBIOGET_VSCREENINFO, &vi) < 0) {
  81. perror("failed to get fb0 info");
  82. close(fd);
  83. return NULL;
  84. }
  85. // We print this out for informational purposes only, but
  86. // throughout we assume that the framebuffer device uses an RGBX
  87. // pixel format. This is the case for every development device I
  88. // have access to. For some of those devices (eg, hammerhead aka
  89. // Nexus 5), FBIOGET_VSCREENINFO *reports* that it wants a
  90. // different format (XBGR) but actually produces the correct
  91. // results on the display when you write RGBX.
  92. //
  93. // If you have a device that actually *needs* another pixel format
  94. // (ie, BGRX, or 565), patches welcome...
  95. printf("fb0 reports (possibly inaccurate):\n"
  96. " vi.bits_per_pixel = %d\n"
  97. " vi.red.offset = %3d .length = %3d\n"
  98. " vi.green.offset = %3d .length = %3d\n"
  99. " vi.blue.offset = %3d .length = %3d\n",
  100. vi.bits_per_pixel,
  101. vi.red.offset, vi.red.length,
  102. vi.green.offset, vi.green.length,
  103. vi.blue.offset, vi.blue.length);
  104. void* bits = mmap(0, fi.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
  105. if (bits == MAP_FAILED) {
  106. perror("failed to mmap framebuffer");
  107. close(fd);
  108. return NULL;
  109. }
  110. memset(bits, 0, fi.smem_len);
  111. gr_framebuffer[0].width = vi.xres;
  112. gr_framebuffer[0].height = vi.yres;
  113. gr_framebuffer[0].row_bytes = fi.line_length;
  114. gr_framebuffer[0].pixel_bytes = vi.bits_per_pixel / 8;
  115. gr_framebuffer[0].data = reinterpret_cast<uint8_t*>(bits);
  116. memset(gr_framebuffer[0].data, 0, gr_framebuffer[0].height * gr_framebuffer[0].row_bytes);
  117. /* check if we can use double buffering */
  118. printf("[graphics] vi.yres * fi.line_length = %d * %d * 2 = %d, fi.smem_len=%d\n",
  119. vi.yres, fi.line_length, vi.yres * fi.line_length * 2, fi.smem_len);
  120. if (vi.yres * fi.line_length * 2 <= fi.smem_len) {
  121. double_buffered = true;
  122. printf("[graphics] double buffered\n");
  123. memcpy(gr_framebuffer+1, gr_framebuffer, sizeof(GRSurface));
  124. gr_framebuffer[1].data = gr_framebuffer[0].data +
  125. gr_framebuffer[0].height * gr_framebuffer[0].row_bytes;
  126. gr_draw = gr_framebuffer+1;
  127. } else {
  128. double_buffered = false;
  129. printf("[graphics] without double buffer\n");
  130. // Without double-buffering, we allocate RAM for a buffer to
  131. // draw in, and then "flipping" the buffer consists of a
  132. // memcpy from the buffer we allocated to the framebuffer.
  133. gr_draw = (GRSurface*) malloc(sizeof(GRSurface));
  134. memcpy(gr_draw, gr_framebuffer, sizeof(GRSurface));
  135. gr_draw->data = (unsigned char*) malloc(gr_draw->height * gr_draw->row_bytes);
  136. if (!gr_draw->data) {
  137. perror("failed to allocate in-memory surface");
  138. return NULL;
  139. }
  140. }
  141. memset(gr_draw->data, 0, gr_draw->height * gr_draw->row_bytes);
  142. fb_fd = fd;
  143. set_displayed_framebuffer(0);
  144. printf("framebuffer: %d (%d x %d)\n", fb_fd, gr_draw->width, gr_draw->height);
  145. #if 0 // to avoid display blink due to display driver not disable backlight after kernel standardization, so that temp state between display suspend/resume is shown
  146. fbdev_blank(backend, true);
  147. fbdev_blank(backend, false);
  148. #endif
  149. return rotate_canvas_get(gr_draw);
  150. }
  151. static GRSurface* fbdev_flip(minui_backend* backend __unused) {
  152. rotate_surface(gr_draw, rotate_canvas_get(gr_draw));
  153. if (double_buffered) {
  154. #if defined(RECOVERY_BGRA)
  155. // In case of BGRA, do some byte swapping
  156. unsigned int idx;
  157. unsigned char tmp;
  158. unsigned char* ucfb_vaddr = (unsigned char*)gr_draw->data;
  159. for (idx = 0 ; idx < (gr_draw->height * gr_draw->row_bytes);
  160. idx += 4) {
  161. tmp = ucfb_vaddr[idx];
  162. ucfb_vaddr[idx ] = ucfb_vaddr[idx + 2];
  163. ucfb_vaddr[idx + 2] = tmp;
  164. }
  165. #endif
  166. // Change gr_draw to point to the buffer currently displayed,
  167. // then flip the driver so we're displaying the other buffer
  168. // instead.
  169. gr_draw = gr_framebuffer + displayed_buffer;
  170. set_displayed_framebuffer(1-displayed_buffer);
  171. } else {
  172. // Copy from the in-memory surface to the framebuffer.
  173. memcpy(gr_framebuffer[0].data, gr_draw->data,
  174. gr_draw->height * gr_draw->row_bytes);
  175. }
  176. return rotate_canvas_get(gr_draw);
  177. }
  178. static void fbdev_exit(minui_backend* backend __unused) {
  179. close(fb_fd);
  180. fb_fd = -1;
  181. rotate_canvas_exit();
  182. if (!double_buffered && gr_draw) {
  183. free(gr_draw->data);
  184. free(gr_draw);
  185. }
  186. gr_draw = NULL;
  187. }

5、对比修改 minui.h,没有则直接复制以下类

  1. /*
  2. * Copyright (C) 2007 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #ifndef _MINUI_H_
  17. #define _MINUI_H_
  18. #include <sys/types.h>
  19. #include <functional>
  20. //
  21. // Graphics.
  22. //
  23. struct GRSurface {
  24. int width;
  25. int height;
  26. int row_bytes;
  27. int pixel_bytes;
  28. unsigned char* data;
  29. };
  30. int gr_init();
  31. void gr_exit();
  32. int gr_fb_width();
  33. int gr_fb_height();
  34. void gr_flip();
  35. void gr_fb_blank(bool blank);
  36. void gr_clear(); // clear entire surface to current color
  37. void gr_color(unsigned char r, unsigned char g, unsigned char b, unsigned char a);
  38. void gr_fill(int x1, int y1, int x2, int y2);
  39. void gr_text(int x, int y, const char *s, bool bold);
  40. void gr_texticon(int x, int y, GRSurface* icon);
  41. int gr_measure(const char *s);
  42. void gr_font_size(int *x, int *y);
  43. void gr_blit(GRSurface* source, int sx, int sy, int w, int h, int dx, int dy);
  44. unsigned int gr_get_width(GRSurface* surface);
  45. unsigned int gr_get_height(GRSurface* surface);
  46. //
  47. // Input events.
  48. //
  49. struct input_event;
  50. // TODO: move these over to std::function.
  51. typedef int (*ev_callback)(int fd, uint32_t epevents, void* data);
  52. typedef int (*ev_set_key_callback)(int code, int value, void* data);
  53. int ev_init(ev_callback input_cb, void* data);
  54. void ev_exit();
  55. int ev_add_fd(int fd, ev_callback cb, void* data);
  56. void ev_iterate_available_keys(std::function<void(int)> f);
  57. int ev_sync_key_state(ev_set_key_callback set_key_cb, void* data);
  58. // 'timeout' has the same semantics as poll(2).
  59. // 0 : don't block
  60. // < 0 : block forever
  61. // > 0 : block for 'timeout' milliseconds
  62. int ev_wait(int timeout);
  63. int ev_get_input(int fd, uint32_t epevents, input_event* ev);
  64. void ev_dispatch();
  65. int ev_get_epollfd();
  66. //
  67. // Resources
  68. //
  69. // res_create_*_surface() functions return 0 if no error, else
  70. // negative.
  71. //
  72. // A "display" surface is one that is intended to be drawn to the
  73. // screen with gr_blit(). An "alpha" surface is a grayscale image
  74. // interpreted as an alpha mask used to render text in the current
  75. // color (with gr_text() or gr_texticon()).
  76. //
  77. // All these functions load PNG images from "/res/images/${name}.png".
  78. // Load a single display surface from a PNG image.
  79. int res_create_display_surface(const char* name, GRSurface** pSurface);
  80. // Load an array of display surfaces from a single PNG image. The PNG
  81. // should have a 'Frames' text chunk whose value is the number of
  82. // frames this image represents. The pixel data itself is interlaced
  83. // by row.
  84. int res_create_multi_display_surface(const char* name,
  85. int* frames, GRSurface*** pSurface);
  86. // Load a single alpha surface from a grayscale PNG image.
  87. int res_create_alpha_surface(const char* name, GRSurface** pSurface);
  88. // Load part of a grayscale PNG image that is the first match for the
  89. // given locale. The image is expected to be a composite of multiple
  90. // translations of the same text, with special added rows that encode
  91. // the subimages' size and intended locale in the pixel data. See
  92. // development/tools/recovery_l10n for an app that will generate these
  93. // specialized images from Android resources.
  94. int res_create_localized_alpha_surface(const char* name, const char* locale,
  95. GRSurface** pSurface);
  96. // Free a surface allocated by any of the res_create_*_surface()
  97. // functions.
  98. void res_free_surface(GRSurface* surface);
  99. #endif

8.1 Recovery 模式横屏修改方法

8.1 的修改步骤和 6.0 大体差不多,前三步都一样,请参考上面的,由于 8.1 中不需要 minui.h 文件,所以 mt_graphic_rotate.hmt_graphic_rotate.cpp 中 需要注释

  1. //#include "minui.h"

4、对比修改 graphics_fbdev.cpp

  1. /*
  2. * Copyright (C) 2014 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "graphics_fbdev.h"
  17. #include <fcntl.h>
  18. #include <linux/fb.h>
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <sys/ioctl.h>
  23. #include <sys/mman.h>
  24. #include <sys/types.h>
  25. #include <unistd.h>
  26. #include "minui/minui.h"
  27. //cczheng add for rotateCanvas
  28. #include "mt_graphic_rotate.h"
  29. MinuiBackendFbdev::MinuiBackendFbdev() : gr_draw(nullptr), fb_fd(-1) {}
  30. void MinuiBackendFbdev::Blank(bool blank) {
  31. int ret = ioctl(fb_fd, FBIOBLANK, blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK);
  32. if (ret < 0) perror("ioctl(): blank");
  33. }
  34. void MinuiBackendFbdev::SetDisplayedFramebuffer(unsigned n) {
  35. if (n > 1 || !double_buffered) return;
  36. vi.yres_virtual = gr_framebuffer[0].height * 2;
  37. vi.yoffset = n * gr_framebuffer[0].height;
  38. vi.bits_per_pixel = gr_framebuffer[0].pixel_bytes * 8;
  39. if (ioctl(fb_fd, FBIOPUT_VSCREENINFO, &vi) < 0) {
  40. perror("active fb swap failed");
  41. }
  42. displayed_buffer = n;
  43. }
  44. GRSurface* MinuiBackendFbdev::Init() {
  45. int fd = open("/dev/graphics/fb0", O_RDWR);
  46. if (fd == -1) {
  47. perror("cannot open fb0");
  48. return nullptr;
  49. }
  50. fb_fix_screeninfo fi;
  51. if (ioctl(fd, FBIOGET_FSCREENINFO, &fi) < 0) {
  52. perror("failed to get fb0 info");
  53. close(fd);
  54. return nullptr;
  55. }
  56. if (ioctl(fd, FBIOGET_VSCREENINFO, &vi) < 0) {
  57. perror("failed to get fb0 info");
  58. close(fd);
  59. return nullptr;
  60. }
  61. // We print this out for informational purposes only, but
  62. // throughout we assume that the framebuffer device uses an RGBX
  63. // pixel format. This is the case for every development device I
  64. // have access to. For some of those devices (eg, hammerhead aka
  65. // Nexus 5), FBIOGET_VSCREENINFO *reports* that it wants a
  66. // different format (XBGR) but actually produces the correct
  67. // results on the display when you write RGBX.
  68. //
  69. // If you have a device that actually *needs* another pixel format
  70. // (ie, BGRX, or 565), patches welcome...
  71. printf(
  72. "fb0 reports (possibly inaccurate):\n"
  73. " vi.bits_per_pixel = %d\n"
  74. " vi.red.offset = %3d .length = %3d\n"
  75. " vi.green.offset = %3d .length = %3d\n"
  76. " vi.blue.offset = %3d .length = %3d\n",
  77. vi.bits_per_pixel, vi.red.offset, vi.red.length, vi.green.offset, vi.green.length,
  78. vi.blue.offset, vi.blue.length);
  79. void* bits = mmap(0, fi.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
  80. if (bits == MAP_FAILED) {
  81. perror("failed to mmap framebuffer");
  82. close(fd);
  83. return nullptr;
  84. }
  85. memset(bits, 0, fi.smem_len);
  86. gr_framebuffer[0].width = vi.xres;
  87. gr_framebuffer[0].height = vi.yres;
  88. gr_framebuffer[0].row_bytes = fi.line_length;
  89. gr_framebuffer[0].pixel_bytes = vi.bits_per_pixel / 8;
  90. gr_framebuffer[0].data = static_cast<uint8_t*>(bits);
  91. memset(gr_framebuffer[0].data, 0, gr_framebuffer[0].height * gr_framebuffer[0].row_bytes);
  92. /* check if we can use double buffering */
  93. if (vi.yres * fi.line_length * 2 <= fi.smem_len) {
  94. double_buffered = true;
  95. memcpy(gr_framebuffer + 1, gr_framebuffer, sizeof(GRSurface));
  96. gr_framebuffer[1].data =
  97. gr_framebuffer[0].data + gr_framebuffer[0].height * gr_framebuffer[0].row_bytes;
  98. gr_draw = gr_framebuffer + 1;
  99. } else {
  100. double_buffered = false;
  101. // Without double-buffering, we allocate RAM for a buffer to
  102. // draw in, and then "flipping" the buffer consists of a
  103. // memcpy from the buffer we allocated to the framebuffer.
  104. gr_draw = static_cast<GRSurface*>(malloc(sizeof(GRSurface)));
  105. memcpy(gr_draw, gr_framebuffer, sizeof(GRSurface));
  106. gr_draw->data = static_cast<unsigned char*>(malloc(gr_draw->height * gr_draw->row_bytes));
  107. if (!gr_draw->data) {
  108. perror("failed to allocate in-memory surface");
  109. return nullptr;
  110. }
  111. }
  112. memset(gr_draw->data, 0, gr_draw->height * gr_draw->row_bytes);
  113. fb_fd = fd;
  114. SetDisplayedFramebuffer(0);
  115. printf("framebuffer: %d (%d x %d)\n", fb_fd, gr_draw->width, gr_draw->height);
  116. #if 0
  117. Blank(true);
  118. Blank(false);
  119. #endif
  120. //return gr_draw;
  121. //cczheng add for rotateCanvas
  122. return rotate_canvas_get(gr_draw);
  123. }
  124. GRSurface* MinuiBackendFbdev::Flip() {
  125. //cczheng add for rotateCanvas
  126. rotate_surface(gr_draw, rotate_canvas_get(gr_draw));
  127. if (double_buffered) {
  128. // Change gr_draw to point to the buffer currently displayed,
  129. // then flip the driver so we're displaying the other buffer
  130. // instead.
  131. gr_draw = gr_framebuffer + displayed_buffer;
  132. SetDisplayedFramebuffer(1 - displayed_buffer);
  133. } else {
  134. // Copy from the in-memory surface to the framebuffer.
  135. memcpy(gr_framebuffer[0].data, gr_draw->data, gr_draw->height * gr_draw->row_bytes);
  136. }
  137. //return gr_draw;
  138. //cczheng add for rotateCanvas
  139. return rotate_canvas_get(gr_draw);
  140. }
  141. MinuiBackendFbdev::~MinuiBackendFbdev() {
  142. close(fb_fd);
  143. fb_fd = -1;
  144. //cczheng add for rotateCanvas
  145. rotate_canvas_exit();
  146. if (!double_buffered && gr_draw) {
  147. free(gr_draw->data);
  148. free(gr_draw);
  149. }
  150. gr_draw = nullptr;
  151. }

修改旋转角度,在 mt_graphic_rotate.cpp 中的 rotate_config(GRSurface gr_draw)
旋转90度就将 return rotate_index 直接改为 return 1,
依次类推转 180度, 改为 return 2, 270 度改为 return 3.
注意旋转方向为顺时针旋转

我修改的情况对应 return 3.

原文链接:http://www.cnblogs.com/cczheng-666/p/11528773.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号